text:
// Currently has the following issues:
// - Does not handle postEditValue
// - Fields without editors need to sync with their values in Store
// - starting to edit another record while already editing and dirty should probably prevent it
// - aggregating validation messages
// - tabIndex is not managed bc we leave elements in dom, and simply move via positioning
// - layout issues when changing sizes/width while hidden (layout bug)

/**
 * Internal utility class used to provide row editing functionality. For developers, they should use
 * the RowEditing plugin to use this functionality with a grid.
 *
 * @private
 */
Ext.define('Ext.grid.RowEditor', {
    extend: 'Ext.form.Panel',
    alias: 'widget.roweditor',

    requires: [
        'Ext.tip.ToolTip',
        'Ext.util.KeyNav',
        'Ext.grid.RowEditorButtons'
    ],

    /**
     * @cfg {Boolean} [removeUnmodified=false]
     * If configured as `true`, then canceling an edit on a newly inserted
     * record which has not been modified will delete that record from the store.
     */

    //<locale>
    saveBtnText: 'Update',
    //</locale>
    //<locale>
    cancelBtnText: 'Cancel',
    //</locale>
    //<locale>
    errorsText: 'Errors',
    //</locale>
    //<locale>
    dirtyText: 'You need to commit or cancel your changes',
    //</locale>

    lastScrollLeft: 0,
    lastScrollTop: 0,

    border: false,
    tabGuard: true,

    _wrapCls: Ext.baseCSSPrefix + 'grid-row-editor-wrap',

    errorCls: Ext.baseCSSPrefix + 'grid-row-editor-errors-item',
    buttonUI: 'default',

    // Change the hideMode to offsets so that we get accurate measurements when
    // the roweditor is hidden for laying out things like a TriggerField.
    hideMode: 'offsets',

    _cachedNode: false,

    initComponent: function() {
        var me = this,
            grid = me.editingPlugin.grid,
            Container = Ext.container.Container,
            form, normalCt, lockedCt;

        me.cls = Ext.baseCSSPrefix + 'grid-editor ' + Ext.baseCSSPrefix + 'grid-row-editor';

        me.layout = {
            type: 'hbox',
            align: 'middle'
        };

        me.lockable = grid.lockable;

        // Create field containing structure for when editing a lockable grid.
        if (me.lockable) {
            me.items = [
                // Locked columns container shrinkwraps the fields
                lockedCt = me.lockedColumnContainer = new Container({
                    id: grid.id + '-locked-editor-cells',
                    scrollable: {
                        x: false,
                        y: false
                    },
                    layout: {
                        type: 'hbox',
                        align: 'middle'
                    },
                    // Locked grid has a border, we must be exactly the same width
                    margin: '0 1 0 0'
                }),

                // Normal columns container flexes the remaining RowEditor width
                normalCt = me.normalColumnContainer = new Container({
                    // not user scrollable, but needs a Scroller instance for syncing with view
                    scrollable: {
                        x: false,
                        y: false
                    },
                    flex: 1,
                    id: grid.id + '-normal-editor-cells',
                    layout: {
                        type: 'hbox',
                        align: 'middle'
                    }
                })
            ];

            // keep horizontal position of fields in sync with view's horizontal scroll position
            lockedCt.getScrollable().addPartner(grid.lockedGrid.view.getScrollable(), 'x');
            normalCt.getScrollable().addPartner(grid.normalGrid.view.getScrollable(), 'x');

            grid.lockedGrid.on({
                collapse: me.onGridResize,
                expand: me.onGridResize,
                beginfloat: me.onBeginFloat,
                scope: me
            });
        } else {
            // initialize a scroller instance for maintaining horizontal scroll position
            me.setScrollable({
                x: false,
                y: false
            });

            // keep horizontal position of fields in sync with view's horizontal scroll position
            me.getScrollable().addPartner(grid.view.getScrollable(), 'x');

            me.lockedColumnContainer = me.normalColumnContainer = me;
        }

        me.callParent();

        if (me.fields) {
            me.addFieldsForColumn(me.fields, true);
            me.insertColumnEditor(me.fields);
            delete me.fields;
        }

        me.mon(Ext.GlobalEvents, {
            scope: me,
            show: me.repositionIfVisible
        });

        form = me.getForm();
        form.trackResetOnLoad = true;
        form.on('validitychange', me.onValidityChange, me);
        form.on('errorchange', me.onErrorChange, me);
    },

    //
    // Grid listener added when this is rendered.
    // Keep our containing element sized correctly
    //
    onGridResize: function() {
        if (this.rendered) {
            var me = this,
                clientWidth = me.getClientWidth(),
                grid = me.editingPlugin.grid,
                gridBody = grid.body,
                btns = me.getFloatingButtons();

            me.wrapEl.setLocalX(gridBody.getOffsetsTo(grid)[0] + gridBody.getBorderWidth('l') - grid.el.getBorderWidth('l'));

            me.setWidth(clientWidth);
            btns.setLocalX((clientWidth - btns.getWidth()) / 2);
            if (me.lockable) {
                me.lockedColumnContainer.setWidth(grid.normalGrid.el.getLeft(true));
            }
        }
    },

    onBeginFloat: function(lockedGrid) {
        if (lockedGrid.isSliding && this.isVisible()) {
            return false;
        }
    },

    syncAllFieldWidths: function() {
        var me = this,
            editors = me.query('[isEditorComponent]'),
            len = editors.length,
            column, i;

        me.preventReposition = true;

        // In a locked grid, a RowEditor uses 2 inner containers, so need to use CQ to retrieve
        // configured editors which were stamped with the isEditorComponent property in Editing.createColumnField
        for (i = 0; i < len; ++i) {
            column = editors[i].column;
            if (column.isVisible()) {
                me.onColumnShow(column);
            }
        }

        me.preventReposition = false;
    },

    syncFieldWidth: function(column) {
        var field = column.getEditor(),
            width;

        field._marginWidth = (field._marginWidth || field.el.getMargin('lr'));
        width = column.getWidth() - field._marginWidth;
        field.setWidth(width);
        if (field.xtype === 'displayfield') {
            // displayfield must have the width set on the inputEl for ellipsis to work
            field.inputWidth = width;
        }
    },

    onValidityChange: function(form, valid) {
        this.updateButton(valid);
    },

    onErrorChange: function() {
        var me = this,
            valid;

        if (me.errorSummary && me.isVisible()) {
            valid = me.getForm().isValid();
            me[valid ? 'hideToolTip' : 'showToolTip']();
        }
    },

    updateButton: function(valid){
        var buttons = this.floatingButtons;
        if (buttons) {
            buttons.child('#update').setDisabled(!valid);
        } else {
            // set flag so we can disabled when created if needed
            this.updateButtonDisabled = !valid;
        }
    },

    afterRender: function() {
        var me = this,
            plugin = me.editingPlugin,
            grid = plugin.grid;

        me.scroller = grid.getScrollable();

        me.callParent(arguments);

        // The scrollingViewEl is the TableView which scrolls
        me.scrollingView = grid.lockable ? grid.normalGrid.view : grid.view;
        me.scrollingViewEl = me.scrollingView.el;
        me.scroller.on('scroll', me.onViewScroll, me);

        // Prevent from bubbling click events to the grid view
        me.mon(me.el, {
            click: Ext.emptyFn,
            stopPropagation: true
        });

        // Ensure that the editor width always matches the total header width
        me.mon(grid, 'resize', me.onGridResize, me);

        if (me.lockable) {
            grid.lockedGrid.view.on('resize', 'onGridResize', me);
        }

        me.el.swallowEvent([
            'keypress',
            'keydown'
        ]);

        me.initKeyNav();

        me.mon(plugin.view, {
            beforerefresh: me.onBeforeViewRefresh,
            refresh: me.onViewRefresh,
            itemremove: me.onViewItemRemove,
            scope: me
        });

        me.syncAllFieldWidths();

        if (me.floatingButtons) {
            me.body.dom.setAttribute('aria-owns', me.floatingButtons.id);
        }
    },

    initKeyNav: function() {
        var me = this,
            plugin = me.editingPlugin;

        me.keyNav = new Ext.util.KeyNav(me.el, {
            tab: {
                fn: me.onFieldTab,
                scope: me
            },
            enter: plugin.onEnterKey,
            esc: plugin.onEscKey,
            scope: plugin
        });
    },

    onBeforeViewRefresh: function(view) {
        var me = this,
            viewDom = view.el.dom;

        if (me.el.dom.parentNode === viewDom) {
            viewDom.removeChild(me.el.dom);
        }
    },

    onViewRefresh: function(view) {
        var me = this,
            context = me.context,
            row;

        // Ignore refresh caused by the completion process
        if (!me.completing) {
            // Recover our row node after a view refresh
            if (context && (row = view.getRow(context.record))) {
                context.row = row;
                me.reposition();
                if (me.tooltip && me.tooltip.isVisible()) {
                    me.tooltip.setTarget(context.row);
                }
            } else {
                me.editingPlugin.cancelEdit();
            }
        }
    },

    onViewItemRemove: function(records, index, items, view) {
        var me = this,
            context = me.context,
            grid,
            store,
            gridView,
            plugin;

        // If the itemremove is due to refreshing, or we are not visible ignore it.
        // If the row for the current context record has gone after the
        // refresh, editing will be canceled there. See onViewRefresh above.
        if (!view.refreshing && context) {
            plugin = me.editingPlugin;
            grid = plugin.grid;
            store = grid.getStore();
            gridView = me.editingPlugin.view;

            // Checking if this is a deleted record or an element being derendered
            if (store.getById(me.getRecord().getId()) && !me._cachedNode) {
                // if this is an item being derendered and is also being edited
                // the flag _cachedNode will be set to true and an itemadd event will
                // be added to monitor when the editor should be reactivated.
                if (plugin.editing) {
                    me._cachedNode = true;
                    me.mon(gridView, {
                        itemadd: me.onViewItemAdd,
                        scope: me
                    });
                }
            } else if (!me._cachedNode) {
                me.activeField = null;
                me.editingPlugin.cancelEdit();
            }
        }
    },

    onViewItemAdd: function(records, index, items, view) {
        var me = this,
            plugin = me.editingPlugin,
            gridView, idx, record;

        // Checks if BufferedRenderer is adding the items
        // if there was an item being edited, and it belongs to this batch
        // then update the row and node associations.
        if (me._cachedNode && me.context) {
            gridView = plugin.view;
            // Checks if there is an array of records being added
            // and if within this array, any record matches the one being edited before
            // if it does, the editor context is updated, the itemadd
            // event listener is removed and _cachedNode is cleared.
            if ((idx = Ext.Array.indexOf(records, me.context.record)) !== -1) {
                record = records[idx];
                me.context.node = record;
                me.context.row = gridView.getRow(record);
                me.context.cell = gridView.getCellByPosition(me.context, true);
                me.clearCache();
            }
        }
    },

    onViewScroll: function() {
        var me = this,
            viewEl = me.editingPlugin.view.el,
            scrollingView = me.scrollingView,
            scrollTop  = me.scroller.getPosition().y,
            scrollLeft = scrollingView.getScrollX(),
            scrollTopChanged = scrollTop !== me.lastScrollTop,
            row;

        me.lastScrollTop  = scrollTop;
        me.lastScrollLeft = scrollLeft;
        if (me.isVisible()) {
            row = Ext.getDom(me.context.row);

            // Only reposition if the row is in the DOM (buffered rendering may mean the context row is not there)
            if (row && viewEl.contains(row)) {
                // This makes sure the Editor is repositioned if it was scrolled out of buffer range
                if (me.getLocalY()) {
                    me.setLocalY(0);
                }

                if (scrollTopChanged) {
                    // The row element in the context may be stale due to buffered rendering removing out-of-view rows, then re-inserting newly rendered ones
                    me.context.row = row;
                    me.reposition(null, true);
                    if ((me.tooltip && me.tooltip.isVisible())) {
                        me.repositionTip();
                    }
                }
            }
            // If row is NOT in the DOM, ensure the editor is out of sight
            else {
                me.setLocalY(-400);
                me.floatingButtons.hide();
            }
        }
    },

    onColumnResize: function(column, width) {
        var me = this;

        if (me.rendered && !me.editingPlugin.reconfiguring) {
            // Need to ensure our lockable/normal horizontal scrollrange is set
            me.onGridResize();
            me.onViewScroll();

            // The layout will have zeroed scroll position on the header, and we will
            // have synced to that, so resync to the correct state.
            if (me.lockable) {
                me.lockedColumnContainer.getScrollable().syncWithPartners();
                me.normalColumnContainer.getScrollable().syncWithPartners();
            } else {
                me.getScrollable().syncWithPartners();
            }
            if (!column.isGroupHeader) {
                me.syncFieldWidth(column);
                me.repositionIfVisible();
            }
        }
    },

    onColumnHide: function(column) {
        if (!this.editingPlugin.reconfiguring && !column.isGroupHeader) {
            column.getEditor().hide();
            this.repositionIfVisible();
        }
    },

    onColumnShow: function(column) {
        var me = this;

        if (me.rendered && !me.editingPlugin.reconfiguring && !column.isGroupHeader && column.getEditor) {
            column.getEditor().show();
            me.syncFieldWidth(column);
            if (!me.preventReposition) {
                me.repositionIfVisible();
            }
        }
    },

    onColumnMove: function(column, fromIdx, toIdx) {
        var me = this,
            locked = column.isLocked(),
            fieldContainer = locked ? me.lockedColumnContainer : me.normalColumnContainer,
            columns, i, len, after, offset;

        // If moving a group, move each leaf header
        if (column.isGroupHeader) {
            Ext.suspendLayouts();
            after = toIdx > fromIdx;
            offset = after ? 1 : 0;
            columns = column.getGridColumns();
            for (i = 0, len = columns.length; i < len; ++i) {
                column = columns[i];
                toIdx = column.getIndex();
                if (after) {
                    ++offset;
                }
                me.setColumnEditor(column, toIdx + offset, fieldContainer);
            }
            Ext.resumeLayouts(true);
        } else {
            me.setColumnEditor(column, column.getIndex(), fieldContainer);
        }
    },

    setColumnEditor: function(column, idx, fieldContainer) {
        this.addFieldsForColumn(column);
        fieldContainer.insert(idx, column.getEditor());
    },

    onColumnAdd: function(column) {

        // If a column header added, process its leaves
        if (column.isGroupHeader) {
            column = column.getGridColumns();
        }
        //this.preventReposition = true;
        this.addFieldsForColumn(column);
        this.insertColumnEditor(column);
        this.preventReposition = false;
    },

    insertColumnEditor: function(column) {
        var me = this,
            field,
            fieldContainer,
            len, i;

        if (Ext.isArray(column)) {
            for (i = 0, len = column.length; i < len; i++) {
                me.insertColumnEditor(column[i]);
            }
            return;
        }

        if (!column.getEditor) {
            return;
        }

        fieldContainer = column.isLocked() ? me.lockedColumnContainer : me.normalColumnContainer;

        // Insert the column's field into the editor panel.
        fieldContainer.insert(column.getIndex(), field = column.getEditor());

        // Ensure the view scrolls the field into view on focus
        field.on('focus', me.onFieldFocus, me);

        me.needsSyncFieldWidths = true;
    },

    onFieldFocus: function(field) {
        // Cache the active field so that we can restore focus into its cell onHide

        // Makes the cursor always be placed at the end of the textfield
        // when the field is being edited for the first time (IE/Edge only).
        if ((Ext.isIE || Ext.isEdge) && field.selectText) {
            field.selectText(field.inputEl.dom.value.length);
        }

        this.activeField = field;
        this.context.setColumn(field.column);

        // skipFocusScroll should be true right after the editor has been started
        if (!this.skipFocusScroll) {
            field.column.getView().getScrollable().scrollIntoView(field.el);
        } else {
            this.skipFocusScroll = null;
        }
    },

    onFieldTab: function(e) {
        var me = this,
            activeField = me.activeField,
            rowIdx = me.context.rowIdx,
            forwards = !e.shiftKey,
            target = activeField[forwards ? 'nextNode' : 'previousNode'](':focusable'),
            count;

        // We must control where the focus goes on Tab key press in fields.
        // The reason is that if there are elements with tabIndex > 0 elsewhere
        // in the document, natural tabbing might go out of the RowEditor, and
        // it might take an undeterminable amount of Tab key presses to get back
        // to the RowEditor.
        e.stopEvent();

        // No field to TAB to, navigate forwards or backwards
        if (!target || !target.isDescendant(me)) {
            // Tabbing out of a dirty editor - wrap to the update button
            if (me.isDirty() && !me.autoUpdate) {
                me.floatingButtons.child('#update').focus();
            }
            else {
                count = me.view.dataSource.getCount();

                // Editor is clean - navigate to next or previous row
                rowIdx = rowIdx + (forwards ? 1 : -1);

                // Wrap around if we reached the end
                if (rowIdx < 0) {
                    rowIdx = count -1;
                }
                else if (rowIdx >= count) {
                    rowIdx = 0;
                }

                if (forwards) {
                    target = me.down(':focusable:not([isButton]):first');

                    // If going back to the first column, scroll back to field.
                    // If we're in a locking view, this has to be done programatically to avoid jarring
                    // when navigating from the locked back into the normal side
                    activeField.column.getView().getScrollable().scrollIntoView(activeField.ownerCt.child(':focusable').el);
                }
                else {
                    target = me.down(':focusable:not([isButton]):last');
                }

                // We need to park focus on a tab guard while the fields
                // are being updated with the values from new row. Also
                // we might need to scroll the view, and RowEditor transition
                // can be animated. We don't want screen readers to announce
                // the transitions.
                me.tabGuardBeforeEl.focus();

                me.editingPlugin.startEdit(rowIdx, target.column);
            }
        }
        else {
            target.focus();
        }
    },

    destroyColumnEditor: function(column) {
        var field;
        if (column.hasEditor() && (field = column.getEditor())) {
            field.destroy();
        }
    },

    getFloatingButtons: function() {
        var me = this,
            btns = me.floatingButtons;

        if (!btns && !me.destroying && !me.destroyed) {
            me.floatingButtons = btns = new Ext.grid.RowEditorButtons({
                ownerCmp: me,
                rowEditor: me
            });
        }
        return btns;
    },

    repositionIfVisible: function(c) {
        var me = this,
            view = me.view;

        // If we're showing ourselves, jump out
        // If the component we're showing doesn't contain the view
        if (c && (c === me || !c.el.isAncestor(view.el))) {
            return;
        }

        if (me.isVisible() && view.isVisible(true)) {
            me.reposition();
        }
    },

    isLayoutChild: function(ownerCandidate) {
        // RowEditor is not a floating component, but won't be laid out by the grid
        return false;
    },

    getRefOwner: function() {
        return this.editingPlugin.grid;
    },

    getRefItems: function(deep) {
        var me = this,
            result, buttons;

        if (me.lockable) {
            // refItems must include ALL children. Must include the two containers
            // because we don't know what is being searched for.
            result = [me.lockedColumnContainer];
            result.push.apply(result, me.lockedColumnContainer.getRefItems(deep));
            result.push(me.normalColumnContainer);
            result.push.apply(result, me.normalColumnContainer.getRefItems(deep));
        } else {
            result = me.callParent(arguments);
        }

        buttons = me.getFloatingButtons();

        if (buttons) {
            result.push.apply(result, buttons.getRefItems(deep));
        }

        return result;
    },

    reposition: function(animateConfig, fromScrollHandler) {
        var me = this,
            context = me.context,
            row = context && context.row,
            wrapEl = me.wrapEl,
            rowTop,
            localY,
            deltaY,
            afterPosition;

        // Position this editor if the context row is rendered (buffered rendering may mean that it's not in the DOM at all)
        if (row && Ext.isElement(row)) {

            deltaY = me.syncButtonPosition(context);

            rowTop = me.calculateLocalRowTop(row);
            localY = me.calculateEditorTop(rowTop);

            // If not being called from scroll handler...
            // If the editor's top will end up above the fold
            // or the bottom will end up below the fold,
            // organize an afterPosition handler which will bring it into view and focus the correct input field
            afterPosition = function() {
                me.syncEditorClip();
                me.wrapAnim = null;

                if (!fromScrollHandler) {
                    if (deltaY) {
                        me.scroller.scrollBy(0, deltaY, true);
                    }
                    me.focusColumnField(context.column);
                }
            };

            // Get the y position of the row relative to its top-most static parent.
            // offsetTop will be relative to the table, and is incorrect
            // when mixed with certain grid features (e.g., grouping).
            if (animateConfig) {
                me.wrapAnim = wrapEl.addAnimation(Ext.applyIf({
                    to: {
                        top: localY
                    },
                    duration: animateConfig.duration || 125,
                    callback: afterPosition
                }, animateConfig));
            }
            else {
                wrapEl.setLocalY(localY);
                afterPosition();
            }
        }
    },

    /**
     * @private
     * Returns the scroll delta required to scroll the context row into view in order to make
     * the whole of this editor visible.
     * @return {Number} the scroll delta. Zero if scrolling is not required.
     */
    getScrollDelta: function() {
        var me = this,
            scrollingViewDom = me.scroller.getElement().dom,
            context = me.context,
            body = me.body,
            deltaY = 0,
            clientHeight, scrollHeight, editorHeight;

        if (context) {
            deltaY = Ext.fly(context.row).getOffsetsTo(scrollingViewDom)[1];
            if (deltaY < 0) {
                deltaY -= body.getBorderPadding().beforeY;
            }
            else if (deltaY > 0) {
                clientHeight = scrollingViewDom.clientHeight;
                scrollHeight = scrollingViewDom.scrollHeight;
                editorHeight = me.getHeight() + me.floatingButtons.getHeight();

                // There might be not enough height to scroll
                if (clientHeight === scrollHeight && editorHeight > clientHeight) {
                    return 0;
                }

                deltaY = Math.max(deltaY + editorHeight - clientHeight - body.getBorderWidth('b'), 0);

                if (deltaY > 0) {
                    deltaY -= body.getBorderPadding().afterY;
                }
            }
        }
        return deltaY;
    },

    //
    // Calculates the top pixel position of the passed row within the view's scroll space.
    // So in a large, scrolled grid, this could be several thousand pixels.
    //
    calculateLocalRowTop: function(row) {
        var grid = this.editingPlugin.grid;
        return Ext.fly(row).getOffsetsTo(grid)[1] - grid.el.getBorderWidth('t') + this.lastScrollTop;
    },

    // Given the top pixel position of a row in the scroll space,
    // calculate the editor top position in the view's encapsulating element.
    // This will only ever be in the visible range of the view's element.
    calculateEditorTop: function(rowTop) {
        var result = rowTop - this.lastScrollTop;

        if (this._buttonsOnTop) {
            result -= (this.body.dom.offsetHeight - this.context.row.offsetHeight - this.body.getBorderPadding().afterY);
        } else {
            result -= this.body.getBorderPadding().beforeY;
        }

        return result;
    },

    getClientWidth: function() {
        var me = this,
            grid = me.editingPlugin.grid,
            lockedCmp,
            result;

        if (me.lockable) {
            lockedCmp = (grid.lockedGrid.collapsed && grid.lockedGrid.placeholder) || grid.lockedGrid;
            result = lockedCmp.getRegion().union(grid.scrollBody.el.getClientRegion()).width;
        }
        else {
            result = grid.view.el.dom.clientWidth;
        }
        return result;
    },

    getEditor: function(fieldInfo) {
        var me = this;

        if (Ext.isNumber(fieldInfo)) {
            // In a locked grid, a RowEditor uses 2 inner containers, so need to use CQ to retrieve
            // configured editors which were stamped with the isEditorComponent property in Editing.createColumnField
            return me.query('[isEditorComponent]')[fieldInfo];
        } else if (fieldInfo.isHeader && !fieldInfo.isGroupHeader) {
            return fieldInfo.getEditor();
        }
    },

    addFieldsForColumn: function(column, initial) {
        var me = this,
            i, len, field, style;

        if (Ext.isArray(column)) {
            for (i = 0, len = column.length; i < len; i++) {
                me.addFieldsForColumn(column[i], initial);
            }
            return;
        }

        if (column.getEditor) {

            // Get a default display field if necessary
            field = column.getEditor(null, me.getDefaultFieldCfg());

            if (column.align === 'right') {
                style = field.fieldStyle;
                if (style) {
                    if (Ext.isObject(style)) {
                        // Create a copy so we don't clobber the object
                        style = Ext.apply({}, style);
                    } else {
                        style = Ext.dom.Element.parseStyles(style);
                    }
                    if (!style.textAlign && !style['text-align']) {
                        style.textAlign = 'right';
                    }
                } else {
                    style = 'text-align:right';
                }

                field.fieldStyle = style;

             }

            if (column.xtype === 'actioncolumn') {
                field.fieldCls += ' ' + Ext.baseCSSPrefix + 'form-action-col-field';
            }

            if (me.isVisible() && me.context) {
                if (field.is('displayfield')) {
                    me.renderColumnData(field, me.context.record, column);
                } else {
                    field.suspendEvents();
                    field.setValue(me.context.record.get(column.dataIndex));
                    field.resumeEvents();
                }
            }
            if (column.hidden) {
                me.onColumnHide(column);
            } else if (column.rendered && !initial) {
                // Setting after initial render
                me.onColumnShow(column);
            }
        }
    },

    getDefaultFieldCfg: function() {
        return {
            xtype: 'displayfield',
            skipLabelForAttribute: true,
            // Override Field's implementation so that the default display fields will not return values. This is done because
            // the display field will pick up column renderers from the grid.
            getModelData: function() {
                return null;
            }
        };
    },

    loadRecord: function(record) {
        var me     = this,
            form   = me.getForm(),
            fields = form.getFields(),
            items  = fields.items,
            length = items.length,
            i, displayFields,
            isValid, item;

        // temporarily suspend events on form fields before loading record to prevent the fields' change events from firing
        for (i = 0; i < length; i++) {
            item = items[i];
            item.suspendEvents();
            item.resetToInitialValue();
        }

        form.loadRecord(record);

        for (i = 0; i < length; i++) {
            items[i].resumeEvents();
        }

        // Because we suspend the events, none of the field events will get propagated to
        // the form, so the valid state won't be correct.
        if (form.hasInvalidField() === form.wasValid) {
            delete form.wasValid;
        }
        isValid = form.isValid();
        if (me.errorSummary) {
            if (isValid) {
                me.hideToolTip();
            } else {
                me.showToolTip();
            }
        }
        me.updateButton(isValid);

        // render display fields so they honor the column renderer/template
        displayFields = me.query('>displayfield');
        length = displayFields.length;

        for (i = 0; i < length; i++) {
            me.renderColumnData(displayFields[i], record);
        }
    },

    renderColumnData: function(field, record, activeColumn) {
        var me = this,
            grid = me.editingPlugin.grid,
            headerCt = grid.headerCt,
            view = me.scrollingView,
            store = view.dataSource,
            column = activeColumn || field.column,
            value = record.get(column.dataIndex),
            renderer = column.editRenderer || column.renderer,
            metaData,
            rowIdx,
            colIdx,
            scope = (column.usingDefaultRenderer && !column.scope) ? column : column.scope;

        // honor our column's renderer (TemplateHeader sets renderer for us!)
        if (renderer) {
            metaData = { tdCls: '', style: '' };
            rowIdx = store.indexOf(record);
            colIdx = headerCt.getHeaderIndex(column);

            value = renderer.call(
                scope || headerCt.ownerCt,
                value,
                metaData,
                record,
                rowIdx,
                colIdx,
                store,
                view
            );
        }

        field.setRawValue(value);
    },

    beforeEdit: function() {
        var me = this,
            scrollDelta;

        // Can't show the editor on a fragile, floated locked side
        if (me.lockable && me.editingPlugin.grid.lockedGrid.floatedFromCollapse) {
            return false;
        }

        if (me.isVisible() && (me.isDirty() || me.context.record.phantom)) {
            if (me.autoUpdate) {
                me.editingPlugin.completeEdit();
            }
            else if (me.autoCancel) {
                me.editingPlugin.cancelEdit();
            }
            else if (me.errorSummary) {
                // Scroll the visible RowEditor that is in error state back into view
                scrollDelta = me.getScrollDelta();

                if (scrollDelta) {
                    me.scrollingViewEl.scrollBy(0, scrollDelta, true);
                }

                me.showToolTip();

                return false;
            }
        }
    },

    /**
     * Start editing the specified grid at the specified position.
     * @param {Ext.data.Model} record The Store data record which backs the row to be edited.
     * @param {Ext.data.Model} columnHeader The Column object defining the column to be focused
     */
    startEdit: function(record, columnHeader) {
        var me = this,
            editingPlugin = me.editingPlugin,
            grid = editingPlugin.grid,
            context = me.context = editingPlugin.context,
            alreadyVisible = me.isVisible(),
            wrapEl = me.wrapEl,
            wasRendered = me.rendered,
            label;

        if (me._cachedNode) {
            me.clearCache();
        }
        // Ensure that the render operation does not lay out
        // The show call will update the layout
        Ext.suspendLayouts();

        if (!wasRendered) {
            me.width = me.getClientWidth();
            me.render(grid.el, grid.el.dom.firstChild);
            // The wrapEl is a container for the editor and buttons.  We use a wrap el
            // (instead of rendering the buttons inside the editor) so that the editor and
            // buttons can be clipped separately when overflowing.
            // See https://sencha.jira.com/browse/EXTJS-13851
            wrapEl = me.wrapEl = me.el.wrap();
            // Change the visibilityMode to offsets so that we get accurate measurements
            // when the roweditor is hidden for laying out things like a TriggerField.
            wrapEl.setVisibilityMode(3);

            wrapEl.addCls(me._wrapCls);
            me.getFloatingButtons().render(wrapEl);
            // On first show we need to ensure that we have the scroll positions cached
            me.onViewScroll();
        }

        me.setLocalY(0);

        // Select at the clicked position.
        context.grid.getSelectionModel().selectByPosition({
            row: record,
            column: columnHeader
        });

        if (me.rendered && me.formAriaLabel) {
            label = Ext.String.formatEncode(me.formAriaLabel, me.formAriaLabelRowBase + context.rowIdx);
            me.body.dom.setAttribute('aria-label', label);
        }

        // Make sure the container el is correctly sized.
        me.onGridResize();

        // Layout the form with the new content if we are already visible.
        // Otherwise, just allow resumption, and the show will update the layout.
        Ext.resumeLayouts(alreadyVisible);
        if (alreadyVisible) {
            me.reposition(true);
        } else {
            // this will prevent the onFieldFocus method from calling
            // scrollIntoView right after startEdit as this will be
            // handled by the Editing plugin.
            me.skipFocusScroll = true;

            me.show();
        }

        // Reload the record data.
        // After positioning so that any error tip will be aligned correctly.
        me.loadRecord(record);

        // Sync our scroll position on first show
        if (!wasRendered) {
            if (me.lockable) {
                me.lockedColumnContainer.getScrollable().syncWithPartners();
                me.normalColumnContainer.getScrollable().syncWithPartners();
            } else {
                me.getScrollable().syncWithPartners();
            }
        }
    },

    // determines the amount by which the row editor will overflow, and flips the buttons
    // to the top of the editor if the required scroll amount is greater than the available
    // scroll space. Returns the scrollDelta required to scroll the editor into view after
    // adjusting the button position.
    syncButtonPosition: function(context) {
        var me = this,
            scrollDelta = me.getScrollDelta(),
            floatingButtons = me.getFloatingButtons(),
            scrollingView = me.scrollingView,
            // If this is negative, it means we're not scrolling so lets just ignore it
            scrollHeight = Math.max(0, me.scroller.getSize().y - me.scroller.getClientSize().y),
            overflow = scrollDelta - (scrollHeight - me.scroller.getPosition().y);

        floatingButtons.show();

        // If that's the last visible row, buttons should be at the top regardless of scrolling,
        // but not if there is just one row which is both first and last.
        if (overflow > 0 || (context.rowIdx > 0 && context.isLastRenderedRow())) {
            if (!me._buttonsOnTop) {
                floatingButtons.setButtonPosition('top');
                me._buttonsOnTop = true;
                me.layout.setAlign('bottom');
                me.updateLayout();
            }
            scrollDelta = 0;
        } else if (me._buttonsOnTop !== false) {
            floatingButtons.setButtonPosition('bottom');
            me._buttonsOnTop = false;
            me.layout.setAlign('top');
            me.updateLayout();
        }
        // Ensure button Y position is synced with Editor height even if button
        // orientation doesn't change
        else {
            floatingButtons.setButtonPosition(floatingButtons.position);
        }

        return scrollDelta;
    },

    syncEditorClip: function() {
        // Since the editor is rendered to the grid el, all its visible parts must be clipped when scrolled
        // outside of the grid view area so that it does not overlap the scrollbar or docked items.
        var me = this,
            tip = me.tooltip,
            // Clipping region must be *within* scrollbars, so in the case of locking view, we cannot
            // use the lockingView's el because that *contains* two grids. We must use the scroller el.
            clipRegion = me.scroller.getElement().getConstrainRegion();

        me.clipTo(clipRegion);
        me.floatingButtons.clipTo(clipRegion);
        if (tip && tip.isVisible()) {
            tip.clipTo(clipRegion, 5);
        }
    },

    focusColumnField: function(column) {
        var field, didFocus;

        if (column && !column.destroyed) {
            if (column.isVisible()) {
                field = this.getEditor(column);
                if (field && field.isFocusable(true)) {
                    didFocus = true;
                    field.focus();
                }
            }
            if (!didFocus) {
                this.focusColumnField(column.next());
            }
        }
    },

    cancelEdit: function() {
        var me     = this,
            form   = me.getForm(),
            fields = form.getFields(),
            items  = fields.items,
            length = items.length,
            i,
            record = me.context.record;

        if (me._cachedNode) {
            me.clearCache();
        }
        me.hide();

        // If we are editing a new record, and we cancel still in invalid state, then remove it.
        if (record && record.phantom && !record.modified && me.removeUnmodified) {
            me.editingPlugin.grid.store.remove(record);
        }

        form.clearInvalid();

        // temporarily suspend events on form fields before reseting the form to prevent the fields' change events from firing
        for (i = 0; i < length; i++) {
            items[i].suspendEvents();
        }

        form.reset();

        for (i = 0; i < length; i++) {
            items[i].resumeEvents();
        }
    },

    /*
    * @private
    */
    clearCache : function() {
        var me = this;
        me.mun(me.editingPlugin.view, {
            itemadd : me.onViewItemAdd,
            scope: me
        });
        me._cachedNode = false;
    },

    completeEdit: function() {
        var me = this,
            form = me.getForm();

        if (!form.isValid()) {
            return false;
        }

        me.completing = true;
        form.updateRecord(me.context.record);
        me.hide();
        me.completing = false;
        return true;
    },

    onShow: function() {
        var me = this;

        me.wrapEl.show();
        me.callParent(arguments);

        if (me.needsSyncFieldWidths) {
            me.suspendLayouts();
            me.preventReposition = true;
            me.syncAllFieldWidths();
            me.preventReposition = false;
            me.resumeLayouts(true);
        }

        delete me.needsSyncFieldWidths;

        if (me.rendered) {
            me.initTabGuards(true);
        }

        me.reposition();
    },

    onHide: function() {
        var me = this,
            context = me.context,
            column,
            focusContext,
            activeEl = Ext.Element.getActiveElement();

        me.context = null;

        // If they used ESC or ENTER in a Field
        if (me.el.contains(activeEl) && me.activeField) {
            column = me.activeField.column;
        }
        // If they used a button
        else {
            column = context.column;
        }

        focusContext = new Ext.grid.CellContext(column.getView()).setPosition(context.record, column);
        focusContext.view.getNavigationModel().setPosition(focusContext);

        me.activeField = null;
        me.wrapEl.hide();

        me.callParent(arguments);

        // RowEditor is hidden via offsets so need to deactivate tab guards manually
        if (me.rendered) {
            me.initTabGuards(false);
        }

        if (me.tooltip) {
            me.hideToolTip();
        }
    },

    onResize: function(width, height) {
        this.wrapEl.setSize(width, height);
    },

    isDirty: function() {
        return this.getForm().isDirty();
    },

    getToolTip: function() {
        var me = this,
            tip = me.tooltip,
            grid = me.editingPlugin.grid;

        if (!tip) {
            me.tooltip = tip = new Ext.tip.ToolTip({
                cls: Ext.baseCSSPrefix + 'grid-row-editor-errors',
                title: me.errorsText,
                autoHide: false,
                closable: true,
                closeAction: 'disable',
                anchor: 'left',
                anchorToTarget: true,
                targetOffset: [Ext.getScrollbarSize().width, 0],
                constrainPosition: true,
                constrainTo: document.body
            });
            grid.add(tip);

            // Layout may change the grid's positioning.
            me.mon(grid, {
                afterlayout: me.onGridLayout,
                scope: me
            });
        }
        return tip;
    },

    hideToolTip: function() {
        var me = this,
            tip = me.getToolTip();
        if (tip.rendered) {
            tip.disable();
        }
    },

    showToolTip: function(wrapAnim) {
        var me = this,
            tip = me.getToolTip();

        // If called while we are moving, wait till new position.
        if (!wrapAnim && me.wrapAnim) {
            return me.wrapAnim.on({
                afteranimate: me.showToolTip,
                scope: me,
                single: true
            });
        }
        tip.update(me.getErrors());
        me.repositionTip();
        tip.enable();
    },

    onGridLayout: function() {
        if (this.tooltip && this.tooltip.isVisible()) {
            this.repositionTip();
        }
    },

    repositionTip: function() {
        var me = this,
            tip = me.getToolTip();

        if (tip.isVisible()) {
            tip.handleAfterShow();
        } else {
            tip.showBy(me.el);
        }
        me.syncEditorClip();
    },

    getErrors: function() {
        var me        = this,
            errors    = [],
            fields    = me.query('>[isFormField]'),
            length    = fields.length,
            i, fieldErrors, field;

        for (i = 0; i < length; i++) {
            field = fields[i];
            fieldErrors = field.getErrors();
            if (fieldErrors.length) {
                errors.push(me.createErrorListItem(fieldErrors[0], field.column.text));
            }
        }

        // Only complain about unsaved changes if all the fields are valid
        if (!errors.length && !me.autoCancel && me.isDirty()) {
            errors[0] = me.createErrorListItem(me.dirtyText);
        }

        return '<ul class="' + Ext.baseCSSPrefix + 'list-plain">' + errors.join('') + '</ul>';
    },

    createErrorListItem: function(e, name) {
        e = name ? name + ': ' + e : e;
        return '<li class="' + this.errorCls + '">' + e + '</li>';
    },

    doDestroy: function() {
        var me = this;

        if (me.wrapAnim) {
            Ext.fx.Manager.removeAnim(me.wrapAnim);
            me.wrapAnim = null;
        }

        me.floatingButtons = me.tooltip = Ext.destroy(me.floatingButtons, me.tooltip);

        me.callParent();
    }
});


text:
package gitdb

import (
	"github.com/scootdev/scoot/ice"
	"github.com/scootdev/scoot/os/temp"
	snap "github.com/scootdev/scoot/snapshot"
	"github.com/scootdev/scoot/snapshot/bundlestore"
	"github.com/scootdev/scoot/snapshot/git/repo"
)

type module struct{}

// Module returns a module that supports typical GitDB usage
func Module() ice.Module {
	return module{}
}

// Install installs setup functions to use GitDB
func (m module) Install(b *ice.MagicBag) {
	b.PutMany(
		func(tmp *temp.TempDir) RepoIniter {
			return &NewRepoIniter{tmp: tmp}
		},
		func(store bundlestore.Store) *BundlestoreConfig {
			return &BundlestoreConfig{Store: store}
		},
		func() *StreamConfig {
			return nil
		},
		func() *TagsConfig {
			return nil
		},
		func() AutoUploadDest {
			return AutoUploadBundlestore
		},
		MakeDBNewRepo,
		func(db *DB) snap.DB { return db },
	)
}

// NewRepoIniter creates a new Repo in a temp dir
type NewRepoIniter struct {
	tmp *temp.TempDir
}

// Init creates a new temp dir and a repo in it
func (i *NewRepoIniter) Init() (*repo.Repository, error) {
	repoTmp, err := i.tmp.TempDir("gitdb-repo-")
	if err != nil {
		return nil, err
	}

	return repo.InitRepo(repoTmp.Dir)
}

redpajama_set_name: RedPajamaGithub


text:
define(["dojo/_base/declare",
        "dojo/_base/lang",
        "dojo/on",
        "dojo/aspect",
        "dojo/json",
        "dojo/dom-construct",
        "dijit/_WidgetBase",
        "dijit/_TemplatedMixin",
        "dijit/_WidgetsInTemplateMixin",
        "dojo/text!./templates/SpatialFilterPane.html",
        "dojo/i18n!./nls/resources",
        "./DropPane",
        "./SpatialFilter",
        "dijit/form/CheckBox"],
function(declare, lang, on, aspect, JSON, domConstruct,
         _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, template, i18n,
         DropPane, SpatialFilter, CheckBox) {

  var oThisClass = declare("g.solr.SpatialFilterPane",
      [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin],{

    i18n: i18n,
    templateString: template,
    _resizeTimer: null,
    _searchDisabled: false,
    _useFilterCheckBox: null,

    // DropPane
    open: false,
    title: null,

    // SpatialFilter
    basemapUrl: null,
    field: "envelope_geo",
    map: null,

    postCreate: function() {
      this.inherited(arguments);
      var spatialFilter =  this.__spatialFilter;
      var dropPane =  this.__dropPane;
      var dropPaneTools = dropPane.dropPaneTools;
      var elTools = dropPaneTools.toolsNode;

      dropPaneTools.disableProperties(true);
      var el = domConstruct.create("span",{});
      elTools.insertBefore(el,dropPaneTools.propertiesNode);
      var chkBox = new CheckBox({
        id: dropPaneTools.id+"_sfcbx",
        title: this.i18n.SpatialFilter.UseFilterTip
      },el);
      this._useFilterCheckBox = chkBox;

      this.own(aspect.after(dropPane,"_onShow",lang.hitch(this,function(e) {
        this.repositionMap();
      })));
      this.own(on(spatialFilter,"MapLoad",lang.hitch(this,function(e) {
        this.repositionMap();
      })));
      this.own(on(spatialFilter,"QClauseRemoved",lang.hitch(this,function(e) {
        spatialFilter.searchDisabled = true;
        chkBox.set("checked",false);
        spatialFilter.useFilter = false;
        setTimeout(lang.hitch(this,function(){spatialFilter.searchDisabled = false;}),100);
      })));
      this.own(on(chkBox,"Change",lang.hitch(this,function(e) {
        this.setUseFilter(chkBox.get("checked"));
      })));

      spatialFilter.initializeMap();
    },

    postMixInProperties: function() {
      this.inherited(arguments);
      if (!this.title) {
        this.title = this.i18n.SpatialFilter.Title;
      }
      if (this.map != null) {
        this.map = JSON.stringify(this.map);
      }
    },

    repositionMap: function() {
      var dropPane = this.__dropPane;
      var map = this.__spatialFilter.map;
      if (map) {
        clearTimeout(this._resizeTimer);
        this._resizeTimer = setTimeout(function(){
          if (dropPane.open) {
            map.resize();
            map.reposition();
          }
        },500);
      }
    },

    setUseFilter: function(bUseFilter) {
      var dropPane = this.__dropPane;
      var spatialFilter =  this.__spatialFilter;
      var map = spatialFilter.map;
      spatialFilter.useFilter = bUseFilter;
      clearTimeout(this._resizeTimer);
      if (map && dropPane.open) {
        map.resize();
        map.reposition();
      }
      spatialFilter.search();
    }

  });

  return oThisClass;
});


text:
/**
* <auto-generated />
* This file was generated by a StringTemplate 4 template.
* Don't change it directly as your change would get overwritten. Instead, make changes
* to the .stg file (i.e. the StringTemplate 4 template file) and save it to regenerate this file.
*
* For more infor on StringTemplate 4 template please go to -
* https://github.com/antlr/antlrcs
*
* @author  Kola Oyewumi
* @version 1.0.0
* @since   2017-01-03
*
* A class which represents the prospects table.
*/

package com.sugaronrest.modules;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.sugaronrest.restapicalls.Module;
import com.sugaronrest.restapicalls.CustomDateDeserializer;
import com.sugaronrest.restapicalls.CustomDateSerializer;

import java.util.Date;

@Module(name = "Prospects", tablename = "prospects")
@JsonRootName(value = "prospects")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Prospects {
    public String getId() {
        return id;
    }

    public void setId(String value) {
        id = value;
    }
    public Date getDateEntered() {
        return dateEntered;
    }

    public void setDateEntered(Date value) {
        dateEntered = value;
    }
    public Date getDateModified() {
        return dateModified;
    }

    public void setDateModified(Date value) {
        dateModified = value;
    }
    public String getModifiedUserId() {
        return modifiedUserId;
    }

    public void setModifiedUserId(String value) {
        modifiedUserId = value;
    }
    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String value) {
        createdBy = value;
    }
    public String getDescription() {
        return description;
    }

    public void setDescription(String value) {
        description = value;
    }
    public Integer getDeleted() {
        return deleted;
    }

    public void setDeleted(Integer value) {
        deleted = value;
    }
    public String getAssignedUserId() {
        return assignedUserId;
    }

    public void setAssignedUserId(String value) {
        assignedUserId = value;
    }
    public String getSalutation() {
        return salutation;
    }

    public void setSalutation(String value) {
        salutation = value;
    }
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String value) {
        firstName = value;
    }
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String value) {
        lastName = value;
    }
    public String getTitle() {
        return title;
    }

    public void setTitle(String value) {
        title = value;
    }
    public String getDepartment() {
        return department;
    }

    public void setDepartment(String value) {
        department = value;
    }
    public Integer getDoNotCall() {
        return doNotCall;
    }

    public void setDoNotCall(Integer value) {
        doNotCall = value;
    }
    public String getPhoneHome() {
        return phoneHome;
    }

    public void setPhoneHome(String value) {
        phoneHome = value;
    }
    public String getPhoneMobile() {
        return phoneMobile;
    }

    public void setPhoneMobile(String value) {
        phoneMobile = value;
    }
    public String getPhoneWork() {
        return phoneWork;
    }

    public void setPhoneWork(String value) {
        phoneWork = value;
    }
    public String getPhoneOther() {
        return phoneOther;
    }

    public void setPhoneOther(String value) {
        phoneOther = value;
    }
    public String getPhoneFax() {
        return phoneFax;
    }

    public void setPhoneFax(String value) {
        phoneFax = value;
    }
    public String getPrimaryAddressStreet() {
        return primaryAddressStreet;
    }

    public void setPrimaryAddressStreet(String value) {
        primaryAddressStreet = value;
    }
    public String getPrimaryAddressCity() {
        return primaryAddressCity;
    }

    public void setPrimaryAddressCity(String value) {
        primaryAddressCity = value;
    }
    public String getPrimaryAddressState() {
        return primaryAddressState;
    }

    public void setPrimaryAddressState(String value) {
        primaryAddressState = value;
    }
    public String getPrimaryAddressPostalcode() {
        return primaryAddressPostalcode;
    }

    public void setPrimaryAddressPostalcode(String value) {
        primaryAddressPostalcode = value;
    }
    public String getPrimaryAddressCountry() {
        return primaryAddressCountry;
    }

    public void setPrimaryAddressCountry(String value) {
        primaryAddressCountry = value;
    }
    public String getAltAddressStreet() {
        return altAddressStreet;
    }

    public void setAltAddressStreet(String value) {
        altAddressStreet = value;
    }
    public String getAltAddressCity() {
        return altAddressCity;
    }

    public void setAltAddressCity(String value) {
        altAddressCity = value;
    }
    public String getAltAddressState() {
        return altAddressState;
    }

    public void setAltAddressState(String value) {
        altAddressState = value;
    }
    public String getAltAddressPostalcode() {
        return altAddressPostalcode;
    }

    public void setAltAddressPostalcode(String value) {
        altAddressPostalcode = value;
    }
    public String getAltAddressCountry() {
        return altAddressCountry;
    }

    public void setAltAddressCountry(String value) {
        altAddressCountry = value;
    }
    public String getAssistant() {
        return assistant;
    }

    public void setAssistant(String value) {
        assistant = value;
    }
    public String getAssistantPhone() {
        return assistantPhone;
    }

    public void setAssistantPhone(String value) {
        assistantPhone = value;
    }
    public int getTrackerKey() {
        return trackerKey;
    }

    public void setTrackerKey(int value) {
        trackerKey = value;
    }
    public Date getBirthdate() {
        return birthdate;
    }

    public void setBirthdate(Date value) {
        birthdate = value;
    }
    public String getLeadId() {
        return leadId;
    }

    public void setLeadId(String value) {
        leadId = value;
    }
    public String getAccountName() {
        return accountName;
    }

    public void setAccountName(String value) {
        accountName = value;
    }
    public String getCampaignId() {
        return campaignId;
    }

    public void setCampaignId(String value) {
        campaignId = value;
    }

    @JsonProperty("id")
    private String id;

    @JsonProperty("date_entered")
    @JsonDeserialize(using = CustomDateDeserializer.class)
    @JsonSerialize(using = CustomDateSerializer.class)
    private Date dateEntered;

    @JsonProperty("date_modified")
    @JsonDeserialize(using = CustomDateDeserializer.class)
    @JsonSerialize(using = CustomDateSerializer.class)
    private Date dateModified;

    @JsonProperty("modified_user_id")
    private String modifiedUserId;

    @JsonProperty("created_by")
    private String createdBy;

    @JsonProperty("description")
    private String description;

    @JsonProperty("deleted")
    private Integer deleted;

    @JsonProperty("assigned_user_id")
    private String assignedUserId;

    @JsonProperty("salutation")
    private String salutation;

    @JsonProperty("first_name")
    private String firstName;

    @JsonProperty("last_name")
    private String lastName;

    @JsonProperty("title")
    private String title;

    @JsonProperty("department")
    private String department;

    @JsonProperty("do_not_call")
    private Integer doNotCall;

    @JsonProperty("phone_home")
    private String phoneHome;

    @JsonProperty("phone_mobile")
    private String phoneMobile;

    @JsonProperty("phone_work")
    private String phoneWork;

    @JsonProperty("phone_other")
    private String phoneOther;

    @JsonProperty("phone_fax")
    private String phoneFax;

    @JsonProperty("primary_address_street")
    private String primaryAddressStreet;

    @JsonProperty("primary_address_city")
    private String primaryAddressCity;

    @JsonProperty("primary_address_state")
    private String primaryAddressState;

    @JsonProperty("primary_address_postalcode")
    private String primaryAddressPostalcode;

    @JsonProperty("primary_address_country")
    private String primaryAddressCountry;

    @JsonProperty("alt_address_street")
    private String altAddressStreet;

    @JsonProperty("alt_address_city")
    private String altAddressCity;

    @JsonProperty("alt_address_state")
    private String altAddressState;

    @JsonProperty("alt_address_postalcode")
    private String altAddressPostalcode;

    @JsonProperty("alt_address_country")
    private String altAddressCountry;

    @JsonProperty("assistant")
    private String assistant;

    @JsonProperty("assistant_phone")
    private String assistantPhone;

    @JsonProperty("tracker_key")
    private int trackerKey;

    @JsonProperty("birthdate")
    @JsonDeserialize(using = CustomDateDeserializer.class)
    @JsonSerialize(using = CustomDateSerializer.class)
    private Date birthdate;

    @JsonProperty("lead_id")
    private String leadId;

    @JsonProperty("account_name")
    private String accountName;

    @JsonProperty("campaign_id")
    private String campaignId;

}


text:
package controller.kanban

import application.KanbanService
import controller.{ ApiController, Keys }
import domain.kanban.{ KanbanId, KanbanRepository, KanbanStatus }
import domain.user.User
import form.kanban.Edit
import scalikejdbc.DB
import skinny.validator._

/**
 * かんばん登録・変更・削除のController.
 */
class EditController extends ApiController {
  protectFromForgery()
  override val authentications = None

  /**
   * 詳細情報取得.
   */
  def detail: String = {
    val kanbanId = params.getAs[Long]("kanbanId").getOrElse(-1L)
    val includeArchive = params.getAs[Boolean]("includeArchive").getOrElse(false)
    val userInfo = session.getAs[User](Keys.Session.UserInfo).get

    DB localTx { implicit session =>
      val kanbanService = injector.getInstance(classOf[KanbanService])
      kanbanService.findById(kanbanId, includeArchive, userInfo)
    } match {
      case Some(detail) =>
        createJsonResult(detail)
      case _ =>
        val errorMsg = createErrorMsg(Keys.ErrMsg.Key, "noData", Seq())
        createJsonResult(errorMsg)
    }
  }

  /**
   * 登録.
   */
  def create: String = {
    validateAndCreateForm match {
      case Right(form) =>
        val userInfo = session.getAs[User](Keys.Session.UserInfo).get
        val kanbanId = DB.localTx { implicit session =>
          val kanbanService = injector.getInstance(classOf[KanbanService])
          kanbanService.create(form.kanbanTitle, form.kanbanDescription, userInfo.userId.get.id)
        }
        createJsonResult("success", Result(kanbanId = kanbanId))

      case Left(v) => createJsonResult(v)
    }
  }

  /**
   * 添付ファイル紐付け.
   */
  def attachmentFile: String = {
    val kanbanId = KanbanId(params.getAs[Long]("kanbanId").getOrElse(-1L))
    val attachmentFileIds = multiParams.getAs[Long]("attachmentFileIds").getOrElse(Seq())
    DB.localTx { implicit session =>
      val kanbanRepository = injector.getInstance(classOf[KanbanRepository])
      kanbanRepository.storeKanbanAttachmentFile(kanbanId, attachmentFileIds)
    }
    createJsonResult("success")
  }

  /**
   * validate & 入力パラメータ取得.
   *
   * @return Right:入力Form / Left:validateエラーメッセージ
   */
  protected def validateAndCreateForm: Either[Map[String, Seq[String]], Edit] = {
    val validator = Validator(
      param("id" -> params("id")) is longValue,
      param("kanbanTitle" -> params("kanbanTitle")) is required & maxLength(256),
      param("lockVersion" -> params("lockVersion")) is longValue
    )
    if (validator.hasErrors) Left(createValidateErrorMsg(validator)) else {
      Right(Edit(
        id = params.getAs[String]("id").getOrElse(""),
        kanbanTitle = params.getAs[String]("kanbanTitle").getOrElse(""),
        kanbanDescription = params.getAs[String]("kanbanDescription").getOrElse(""),
        archiveStatus = params.getAs[String]("archiveStatus").getOrElse(KanbanStatus.Open.code),
        lockVersion = params.getAs[String]("lockVersion").getOrElse("0")
      ))
    }
  }

  /**
   * JSON戻り値.
   * @param kanbanId かんばんID
   */
  case class Result(kanbanId: Long)
}


text:
 #define LLVMSRTL_STARTUP

 #include <llvmsrtl/types.h>

 #include <llvmsrtl/startup.h>
 #include <llvmsrtl/gc.h>
 #include <llvmsrtl/info.h>

 #include <llvmsrtl/System/string.h>
 #include <llvmsrtl/System/convert.h>
 #include <llvmsrtl/System/console.h>
 #include <llvmsrtl/System/environment.h>

#endif


text:
namespace mojo {
namespace examples {

namespace {

const PP_Instance kInstanceId = 1;

}  // namespace

// A non-abstract subclass of ppapi::MessageLoopShared that represents the
// message loop of the main thread.
// TODO(yzshen): Build a more general ppapi::MessageLoopShared subclass to fully
// support PPB_MessageLoop.
class MojoPpapiGlobals::MainThreadMessageLoopResource
    : public ppapi::MessageLoopShared {
 public:
  explicit MainThreadMessageLoopResource(
      base::MessageLoopProxy* main_thread_message_loop)
      : MessageLoopShared(ForMainThread()),
        main_thread_message_loop_(main_thread_message_loop) {}

  // ppapi::MessageLoopShared implementation.
  virtual void PostClosure(const tracked_objects::Location& from_here,
                           const base::Closure& closure,
                           int64 delay_ms) OVERRIDE {
    main_thread_message_loop_->PostDelayedTask(
        from_here, closure, base::TimeDelta::FromMilliseconds(delay_ms));
  }

  virtual base::MessageLoopProxy* GetMessageLoopProxy() OVERRIDE {
    return main_thread_message_loop_.get();
  }

  virtual bool CurrentlyHandlingBlockingMessage() OVERRIDE {
    return false;
  }

  // ppapi::thunk::PPB_MessageLoop_API implementation.
  virtual int32_t AttachToCurrentThread() OVERRIDE {
    NOTIMPLEMENTED();
    return PP_ERROR_FAILED;
  }

  virtual int32_t Run() OVERRIDE {
    NOTIMPLEMENTED();
    return PP_ERROR_FAILED;
  }

  virtual int32_t PostWork(PP_CompletionCallback callback,
                           int64_t delay_ms) OVERRIDE {
    NOTIMPLEMENTED();
    return PP_ERROR_FAILED;
  }

  virtual int32_t PostQuit(PP_Bool should_destroy) OVERRIDE {
    NOTIMPLEMENTED();
    return PP_ERROR_FAILED;
  }

 private:
  virtual ~MainThreadMessageLoopResource() {}

  scoped_refptr<base::MessageLoopProxy> main_thread_message_loop_;
  DISALLOW_COPY_AND_ASSIGN(MainThreadMessageLoopResource);
};

MojoPpapiGlobals::MojoPpapiGlobals(Delegate* delegate)
    : delegate_(delegate),
      plugin_instance_(NULL),
      resource_tracker_(ppapi::ResourceTracker::THREAD_SAFE) {}

MojoPpapiGlobals::~MojoPpapiGlobals() {}

PP_Instance MojoPpapiGlobals::AddInstance(PluginInstance* instance) {
  DCHECK(!plugin_instance_);
  plugin_instance_ = instance;
  resource_tracker_.DidCreateInstance(kInstanceId);
  return kInstanceId;
}

void MojoPpapiGlobals::InstanceDeleted(PP_Instance instance) {
  DCHECK_EQ(instance, kInstanceId);
  DCHECK(plugin_instance_);
  resource_tracker_.DidDeleteInstance(instance);
  plugin_instance_ = NULL;
}

PluginInstance* MojoPpapiGlobals::GetInstance(PP_Instance instance) {
  if (instance == kInstanceId)
    return plugin_instance_;
  return NULL;
}

ScopedMessagePipeHandle MojoPpapiGlobals::CreateGLES2Context() {
  return delegate_->CreateGLES2Context();
}

ppapi::ResourceTracker* MojoPpapiGlobals::GetResourceTracker() {
  return &resource_tracker_;
}

ppapi::VarTracker* MojoPpapiGlobals::GetVarTracker() {
  NOTIMPLEMENTED();
  return NULL;
}

ppapi::CallbackTracker* MojoPpapiGlobals::GetCallbackTrackerForInstance(
    PP_Instance instance) {
  if (instance == kInstanceId && plugin_instance_)
    return plugin_instance_->plugin_module()->callback_tracker();
  return NULL;
}

void MojoPpapiGlobals::LogWithSource(PP_Instance instance,
                                     PP_LogLevel level,
                                     const std::string& source,
                                     const std::string& value) {
  NOTIMPLEMENTED();
}

void MojoPpapiGlobals::BroadcastLogWithSource(PP_Module module,
                                              PP_LogLevel level,
                                              const std::string& source,
                                              const std::string& value) {
  NOTIMPLEMENTED();
}

ppapi::thunk::PPB_Instance_API* MojoPpapiGlobals::GetInstanceAPI(
    PP_Instance instance) {
  if (instance == kInstanceId && plugin_instance_)
    return plugin_instance_;
  return NULL;
}

ppapi::thunk::ResourceCreationAPI* MojoPpapiGlobals::GetResourceCreationAPI(
    PP_Instance instance) {
  if (instance == kInstanceId && plugin_instance_)
    return plugin_instance_->resource_creation();
  return NULL;
}

PP_Module MojoPpapiGlobals::GetModuleForInstance(PP_Instance instance) {
  NOTIMPLEMENTED();
  return 0;
}

ppapi::MessageLoopShared* MojoPpapiGlobals::GetCurrentMessageLoop() {
  if (base::MessageLoopProxy::current().get() == GetMainThreadMessageLoop()) {
    if (!main_thread_message_loop_resource_.get()) {
      main_thread_message_loop_resource_ = new MainThreadMessageLoopResource(
          GetMainThreadMessageLoop());
    }
    return main_thread_message_loop_resource_.get();
  }

  NOTIMPLEMENTED();
  return NULL;
}

base::TaskRunner* MojoPpapiGlobals::GetFileTaskRunner() {
  NOTIMPLEMENTED();
  return NULL;
}

std::string MojoPpapiGlobals::GetCmdLine() {
  NOTIMPLEMENTED();
  return std::string();
}

void MojoPpapiGlobals::PreCacheFontForFlash(const void* logfontw) {
  NOTIMPLEMENTED();
}

}  // namespace examples
}  // namespace mojo


text:
import {Component, OnInit} from 'angular2/core';
import {Router} from 'angular2/router';
import {Hero} from './hero';
import {Logger} from './logger.service';
import {HeroService} from './hero.service';

@Component({
  selector: 'my-dashboard',
  templateUrl: 'app/dashboard.component.html',
  styleUrls: ['app/dashboard.component.css']
})
export class DashboardComponent implements OnInit {
  public heroes: Hero[] = [];

  constructor(private _heroService: HeroService, private _router: Router,
              private _logger: Logger) { }

  ngOnInit() {
      this._heroService.getHeroes()
        .subscribe(heroes => {
            var maxHeroes = heroes.length < 4 ? heroes.length : 4;
            this.heroes = heroes.slice(0, maxHeroes);
            this._logger.log("We got " + this.heroes.length + " heros");
        });
  }

  gotoDetail(hero: Hero) {
    this._router.navigate(['HeroDetail', { id: hero.id }]);
  }
}


text:
package org.fhcrc.cpl.viewer.commandline.modules;

import org.fhcrc.cpl.toolbox.ApplicationContext;
import org.fhcrc.cpl.toolbox.commandline.arguments.*;
import org.fhcrc.cpl.toolbox.filehandler.TabLoader;
import org.fhcrc.cpl.toolbox.commandline.CommandLineModuleExecutionException;
import org.fhcrc.cpl.toolbox.commandline.CommandLineModule;
import org.apache.log4j.Logger;

import java.io.*;
import java.util.*;

/**
 * Command linemodule for plotting the mass calibration of a feature file
 */
public class CollapseSpreadsheetRowsCLM extends BaseViewerCommandLineModuleImpl
        implements CommandLineModule
{
    protected static Logger _log = Logger.getLogger(CollapseSpreadsheetRowsCLM.class);

    protected String collapseColumnName = null;
    protected File inFile;
    protected File outFile;
    protected String separatorString = ";";
    protected List<String> otherColsToCollapse = new ArrayList<String>();
    protected boolean shouldCollapseToUnique = false;

    public CollapseSpreadsheetRowsCLM()
    {
        init();
    }

    protected void init()
    {
        mCommandName = "collapsespreadsheetrows";
        mShortDescription = "collapse multiple rows in a spreadsheet with the same value for collapsecolumn";
        CommandLineArgumentDefinition[] argDefs =
                {
                        createUnnamedFileArgumentDefinition(true,"input spreadsheet"),
                        new StringArgumentDefinition("collapsecolumn", true, "column to split on"),
                        new FileToWriteArgumentDefinition("out", false, "output file"),
                        new StringArgumentDefinition("separator", false,
                                "String to split on", separatorString),
                        new StringListArgumentDefinition("othercolstocollapse", false,
                                "other columns to collapse (rather than keep one value). Any column NOT on this list " +
                                        "must have only one unique value, or an error is thrown."),
                        new BooleanArgumentDefinition("collapsetounique", false,
                                "for other columns, collapse into unique values.", false),
                };
        addArgumentDefinitions(argDefs);
    }

    public void assignArgumentValues()
            throws ArgumentValidationException
    {
        inFile = getUnnamedFileArgumentValue();
        collapseColumnName = getStringArgumentValue("collapsecolumn");
        separatorString = getStringArgumentValue("separator");
        outFile = getFileArgumentValue("out");
        otherColsToCollapse = getStringListArgumentValue("othercolstocollapse");

        if (otherColsToCollapse == null)
            otherColsToCollapse = new ArrayList<String>();
        if (!otherColsToCollapse.isEmpty()) {
            ApplicationContext.infoMessage("collapsing other columns:");
            for (String col : otherColsToCollapse)
                ApplicationContext.infoMessage("\t" + col);
        }
        shouldCollapseToUnique = getBooleanArgumentValue("collapsetounique");
    }

    /**
     * do the actual work
     */
    public void execute() throws CommandLineModuleExecutionException
    {
        PrintWriter outPW = null;
        try
        {
            outPW = new PrintWriter(outFile);

            TabLoader loader = new TabLoader(inFile);
            List<TabLoader.ColumnDescriptor> columns =
                    new ArrayList<TabLoader.ColumnDescriptor>();
            StringBuffer headerLine = new StringBuffer();
            boolean firstColumn = true;
            for (TabLoader.ColumnDescriptor column : loader.getColumns())
            {
                columns.add(column);
                if (firstColumn)
                    firstColumn = false;
                else
                    headerLine.append("\t");
                headerLine.append(column.name);
            }
            outPW.println(headerLine.toString());
            outPW.flush();

            Map<String, List<Map>> keyRowsMap = new HashMap<String, List<Map>>();

            Map[] rowsAsMaps = (Map[])loader.load();

            int lineNum = 0;
            for (Map row : rowsAsMaps)
            {
                lineNum++;
                Object collapseVal = row.get(collapseColumnName);
                if (collapseVal == null) {
                    throw new CommandLineModuleExecutionException("Null collapse value for line " + lineNum);
                }
                String key = collapseVal.toString();

                List<Map> rows = keyRowsMap.get(key);
                if (rows == null) {
                    rows = new ArrayList<Map>();
                    keyRowsMap.put(key, rows);
                }
                rows.add(row);
            }

            for (String key : keyRowsMap.keySet()) {
                StringBuffer lineBuf = new StringBuffer();
                List<Map> rows = keyRowsMap.get(key);
                boolean firstCol = true;
                for (TabLoader.ColumnDescriptor column : loader.getColumns()) {
                    String valString = "";

                    if (key.equals(collapseColumnName))
                        valString = key;
                    else {
                        if (shouldCollapseToUnique) {
                            Set<String> uniqueValsThisCol = new HashSet<String>();
                            for (Map row : rows) {
                                String val = "";
                                if (row.containsKey(column.name) && row.get(column.name) != null)
                                    val = row.get(column.name).toString();
                                uniqueValsThisCol.add(val);
                            }
                            boolean firstVal = true;
                            for (String val : uniqueValsThisCol) {
                                if (!firstVal)
                                    valString = valString + separatorString;
                                valString = valString + val;
                                firstVal = false;
                            }
                        } else {
                            List<String> allValsThisCol = new ArrayList<String>();
                            for (Map row : rows) {
                                String val = "";
                                if (row.containsKey(column.name) && row.get(column.name) != null)
                                    val = row.get(column.name).toString();
                                allValsThisCol.add(val);
                            }

                            if (otherColsToCollapse.contains(column.name)) {
                                boolean firstVal = true;
                                for (String val : allValsThisCol) {
                                    if (!firstVal)
                                        valString = valString + separatorString;
                                    valString = valString + val;
                                    firstVal = false;
                                }
                            }
                            else {
                                Set<String> uniqueVals = new HashSet<String> (allValsThisCol);
                                if (uniqueVals.size() > 1 && uniqueVals.contains("")) {
                                    uniqueVals.remove("");
                                }
                                if (uniqueVals.size() > 1)       {
                                    boolean firstVal = true;
                                    for (String val : uniqueVals) {
                                        if (!firstVal)
                                            valString = valString + separatorString;
                                            valString = valString + val;
                                    }
    //                                ApplicationContext.infoMessage("Vals:");
    //                                for (String val : uniqueVals)
    //                                    ApplicationContext.infoMessage("\t" + val);
    //                                throw new CommandLineModuleExecutionException("Key " + key + ", col " + column.name +
    //                                        ", vals: " + uniqueVals.size());
                                }
                                else {
                                    valString = uniqueVals.iterator().next();
                                }
                            }
                        }
                    }

                    lineBuf.append(firstCol ? "" : "\t");
                    lineBuf.append(valString);

                    firstCol = false;
                }
                outPW.println(lineBuf.toString());
                outPW.flush();

            }

        }
        catch (Exception e)
        {
            throw new CommandLineModuleExecutionException(e);
        }
        finally
        {
            if (outPW != null)
                outPW.close();
        }
    }

}


text:
    Based on a plugin by topkecleon. Licensed under GNU AGPLv3
    https://github.com/topkecleon/otouto/blob/master/LICENSE.
    Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
    This code is licensed under the MIT. See LICENSE for details.
]]

local calc = {}
local mattata = require('mattata')
local http = require('socket.http')
local url = require('socket.url')

function calc:init()
    calc.commands = mattata.commands(self.info.username):command('calc'):command('calculate'):command('calculator').table
    calc.help = '/calc <expression> - Solves the given mathematical expression using mathjs.org.'
    calc.aliases = {
        ['?'] = '/',
        ['divided by'] = '/',
        ['times by'] = '*',
        ['times'] = '*',
        ['multiplied by'] = '*',
        [' x '] = '*',
        ['minus'] = '-',
        ['subtract'] = '-',
        ['take away'] = '-',
        ['to the power of'] = '^',
        ['raised to'] = '^',
        ['π'] = math.pi,
        ['pi'] = math.pi,
        ['plus'] = '+',
        ['added to'] = '+',
        ['add'] = '+',
        ['point'] = '.',
        ['dot'] = '.',
        ['percent'] = '%%',
        ['percentage'] = '%%',
        ['²'] = '^2'
    }
    calc.numbers = {
        ['zero'] = 0,
        ['one'] = 1,
        ['two'] = 2,
        ['three'] = 3,
        ['four'] = 4,
        ['five'] = 5,
        ['six'] = 6,
        ['seven'] = 7,
        ['eight'] = 8,
        ['nine'] = 9,
        ['ten'] = 10,
        ['eleven'] = 11,
        ['twelve'] = 12,
        ['thirteen'] = 13,
        ['fourteen'] = 14,
        ['fifteen'] = 15,
        ['sixteen'] = 16,
        ['seventeen'] = 17,
        ['eighteen'] = 18,
        ['nineteen'] = 19,
        ['twenty'] = 20,
        ['thirty'] = 30,
        ['forty'] = 40,
        ['fifty'] = 50,
        ['sixty'] = 60,
        ['seventy'] = 70,
        ['eighty'] = 80,
        ['ninety'] = 90
    }
    calc.units = {
        ['hundred'] = '100',
        ['thousand'] = '1000',
        ['million'] = '1000000',
        ['billion'] = '1000000000',
        ['trillion'] = '1000000000000',
        ['quadrillion'] = '1000000000000000',
        ['quintillion'] = '1000000000000000000',
        ['sextillion'] = '1000000000000000000000',
        ['septillion'] = '1000000000000000000000000',
        ['octillion'] = '1000000000000000000000000000',
        ['nonillion'] = '1000000000000000000000000000000',
        ['decillion'] = '1000000000000000000000000000000000',
        ['undecillion'] = '1000000000000000000000000000000000000',
        ['duodecillion'] = '1000000000000000000000000000000000000000',
        ['tredecillion'] = '1000000000000000000000000000000000000000000',
        ['quattuordecillion'] = '1000000000000000000000000000000000000000000000',
        ['quindecillion'] = '1000000000000000000000000000000000000000000000000',
        ['sexdecillion'] = '1000000000000000000000000000000000000000000000000000',
        ['septendecillion'] = '1000000000000000000000000000000000000000000000000000000',
        ['octodecillion'] = '1000000000000000000000000000000000000000000000000000000000',
        ['novemdecillion'] = '1000000000000000000000000000000000000000000000000000000000000',
        ['vigintillion'] = '1000000000000000000000000000000000000000000000000000000000000000'
    }
    calc.url = 'https://api.mathjs.org/v4/?expr='
end

function calc.convert(str, language)
    str = str:lower()
    local results = {}
    local prev = nil
    for word in str:gmatch('[%w²π]+') do
        if word ~= 'and' then -- don't process "and"
            local top = #results
            local number = tonumber(word)
            if not number then
                number = calc.numbers[word]
            end
            if number then
                if prev == 'number' then
                    local prev_num = table.remove(results, top)
                    number = number + prev_num
                end
                table.insert(results, number)
                prev = 'number'
            else
                local unit = tonumber(calc.units[word])
                if not unit then
                    return false, string.format(language['calc']['2'], word)
                end
                prev = 'unit'
                if top == 0 then
                    return false, language['calc']['3']
                end
                local interim = 0
                while top > 0 and results[top] < unit do
                    interim = interim + table.remove(results, top)
                    top = #results
                end
                table.insert(results, interim * unit)
            end
        end
    end
    if #results == 0 then
        return false, 'No number found!'
    end
    local final = 0
    for _, res in ipairs(results) do
        final = final + res
    end
    return final
end

function calc.process_input(input, language)
    input = input:gsub('percent of', 'percent')
    for k, v in pairs(calc.aliases) do
        input = input:gsub(k, v)
    end
    for phrase in input:gmatch('[%w%s]+') do
        local new, err = calc.convert(phrase, language)
        if new then
            input = input:gsub(phrase, new)
        else
            return false, err
        end
    end
    return input
end

function calc.on_inline_query(_, inline_query, _, language)
    local input = mattata.input(inline_query.query)
    if not input then
        return false
    end
    input = calc.process_input(input, language)
    local str, res = http.request(calc.url .. url.escape(input))
    if res ~= 200 or not str then
        return false
    end
    local description = language['calc']['1']
    local message_content = mattata.input_text_message_content(str)
    local result = mattata.inline_result()
    :type('article')
    :id(1)
    :title(str)
    :description(description)
    :input_message_content(message_content)
    return mattata.answer_inline_query(inline_query.id, result)
end

function calc.on_message(_, message, _, language)
    local input = mattata.input(message.text)
    local err
    if not input then
        return mattata.send_reply(message, calc.help)
    end
    input, err = calc.process_input(input, language)
    if not input then
        return mattata.send_reply(message, err)
    end
    local str, res = http.request(calc.url .. url.escape(input))
    if res ~= 200 then
        local response = language['errors']['results']
        return mattata.send_reply(message, response)
    end
    return mattata.send_message(message.chat.id, str)
end

return calc


text:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Modelo;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 *
 * @author Yair Lopez Poveda <ylopezp@correo.udistrital.edu.co>
 */
public class ServicioGeneral implements IServicio{

    protected MedioTransporte objTransporte;
    private String ciudadOrigen;
    private String ciudadDestino;
    public static HashMap<String,Integer> idCiudad;
    public static Map<HashSet, Double> NoKm;

    public ServicioGeneral() {
    }

    public ServicioGeneral(MedioTransporte objTransporte, String ciudadOrigen, String ciudadDestino) {
        this.objTransporte = objTransporte;
        this.ciudadOrigen = ciudadOrigen;
        this.ciudadDestino = ciudadDestino;
    }

    static{
        idCiudad = new HashMap<String, Integer>();
        NoKm = new HashMap<HashSet, Double>();
        idCiudad.put("bogota", 1);
        idCiudad.put("neiva", 2);
        idCiudad.put("santa marta", 3);
        idCiudad.put("pasto", 4);
        NoKm.put(new HashSet(Arrays.asList(1,2)), 297.2);
        NoKm.put(new HashSet(Arrays.asList(1,3)), 978.0);
        NoKm.put(new HashSet(Arrays.asList(1,4)), 272.4);
        NoKm.put(new HashSet(Arrays.asList(2,3)), 1134.7);
        NoKm.put(new HashSet(Arrays.asList(2,4)), 430.2);
        NoKm.put(new HashSet(Arrays.asList(3,4)), 1583.5);
    }

    public MedioTransporte getObjTransporte() {
        return objTransporte;
    }

    public void setObjTransporte(MedioTransporte objTransporte) {
        this.objTransporte = objTransporte;
    }

    @Override
    public double calcularCostoTotal() {
        return objTransporte.CostoKM*DistanciaKm();
    }

    public double DistanciaKm(){
        return NoKm.get(new HashSet(Arrays.asList(idCiudad.get(ciudadOrigen),idCiudad.get(ciudadDestino))));
    }

    @Override
    public double calcularCostoPorPasajero() {
        return calcularCostoTotal()/objTransporte.NPasajeros;
    }

    public String getCiudadOrigen() {
        return ciudadOrigen;
    }

    public void setCiudadOrigen(String ciudadOrigen) {
        this.ciudadOrigen = ciudadOrigen;
    }

    public String getCiudadDestino() {
        return ciudadDestino;
    }

    public void setCiudadDestino(String ciudadDestino) {
        this.ciudadDestino = ciudadDestino;
    }

    @Override
    public String toString() {
        return "Servicio General\n\n" + objTransporte + "\nCiudad de origen : "
                + ciudadOrigen + "\nCiudad de destino : " + ciudadDestino + '\n';
    }

}