<commit_before>define(function(require) {
    'use strict';

    var FiltersManager;
    var template = require('tpl!orofilter/templates/filters-container.html');
    var $ = require('jquery');
    var _ = require('underscore');
    var __ = require('orotranslation/js/translator');
    var mediator = require('oroui/js/mediator');
    var tools = require('oroui/js/tools');
    var BaseView = require('oroui/js/app/views/base/view');
    var MultiselectDecorator = require('./multiselect-decorator');
    var filterWrapper = require('./datafilter-wrapper');
    var FiltersStateView = require('./app/views/filters-state-view');
    var persistentStorage = require('oroui/js/persistent-storage');

    /**
     * View that represents all grid filters
     *
     * @export  orofilter/js/filters-manager
     * @class   orofilter.FiltersManager
     * @extends BaseView
     *
     * @event updateList    on update of filter list
     * @event updateFilter  on update data of specific filter
     * @event disableFilter on disable specific filter
     */
    FiltersManager = BaseView.extend({
        /**
         * List of filter objects
         *
         * @type {Object}
         * @property
         */
        filters: null,

        /**
         * Template
         */
        template: template,

        /**
         * Mode of filters displaying
         *
         * @type {Integer}
         * @property
         */
        viewMode: NaN,

        /**
         * Filter list input selector
         *
         * @property
         */
        filterSelector: '[data-action=add-filter-select]',

        /**
         * Add filter button hint
         *
         * @property
         */
        addButtonHint: __('oro_datagrid.label_add_filter'),

        /**
         * Set label for reset button
         *
         * @property
         */
        multiselectResetButtonLabel: __('oro_datagrid.label_reset_button'),

        /**
         * Select widget object
         *
         * @property {oro.MultiselectDecorator}
         */
        selectWidget: null,

        /**
         * Select widget constructor
         *
         * @property
         */
        MultiselectDecorator: MultiselectDecorator,

        /**
         *  Parameters Select widget constructor
         *
         * @property
         */
        multiselectParameters: {},

        /**
         * ImportExport button selector
         *
         * @property
         */
        buttonSelector: '.ui-multiselect.filter-list',

        /**
         * jQuery object that will be target for append multiselect dropdown menus
         *
         * @property
         */
        dropdownContainer: 'body',

        /** @property */
        events: {
            'change [data-action=add-filter-select]': '_onChangeFilterSelect',
            'click .reset-filter-button': '_onReset',
            'click a[data-name="filters-dropdown"]': '_onDropdownToggle',
            'click [data-role="reset-filters"]': '_onReset'
        },

        /**
         * Initialize filter list options
         *
         * @param {Object} options
         * @param {Object} [options.filters]
         * @param {String} [options.addButtonHint]
         */
        initialize: function(options) {
            var prop = ['addButtonHint', 'multiselectResetButtonLabel', 'stateViewElement', 'viewMode'];
            this.template = this.getTemplateFunction();
            this.filters = {};

            _.extend(this, _.pick(options, prop));

            if (options.filters) {
                _.extend(this.filters, options.filters);
            }

            var filterListeners = {
                'update': this._onFilterUpdated,
                'disable': this._onFilterDisabled,
                'showCriteria': this._onFilterShowCriteria
            };

            if (tools.isMobile()) {
                var outsideActionEvents = 'click.' + this.cid + ' shown.bs.dropdown.' + this.cid;
                filterListeners.updateCriteriaClick = this._onUpdateCriteriaClick;
                $('body').on(outsideActionEvents, this._onOutsideActionEvent.bind(this));
            }

            _.each(this.filters, function(filter) {
                if (filter.wrappable) {
                    _.extend(filter, filterWrapper);
                }

                this.listenTo(filter, filterListeners);
            }, this);

            if ('filtersStateElement' in options) {
                var $container = this.$el.closest('body, .ui-dialog');
                var filtersStateView = new FiltersStateView({
                    el: $container.find(options.filtersStateElement).first(),
                    filters: options.filters
                });

                this.subview('filters-state', filtersStateView);
                this.listenTo(filtersStateView, 'clicked', function() {
                    this.setViewMode(FiltersManager.MANAGE_VIEW_MODE);
                });
            }

            var selectedFilters = this._calculateSelectedFilters();
            mediator.on(
                'filterManager:selectedFilters:count:' + this.collection.options.gridName,
                selectedFilters
            );

            FiltersManager.__super__.initialize.apply(this, arguments);
        },

        /**
         * @inheritDoc
         */
        dispose: function() {
            if (this.disposed) {
                return;
            }
            $('body').off('.' + this.cid);
            _.each(this.filters, function(filter) {
                filter.dispose();
            });
            delete this.filters;
            if (this.selectWidget) {
                this.selectWidget.dispose();
                delete this.selectWidget;
            }
            FiltersManager.__super__.dispose.call(this);
        },

        /**
         * Triggers when filter is updated
         *
         * @param {oro.filter.AbstractFilter} filter
         * @protected
         */
        _onFilterUpdated: function(filter) {
            this._resetHintContainer();
            this.trigger('updateFilter', filter);

            this._publishCountSelectedFilters();
        },

        /**
         * Triggers when filter is disabled
         *
         * @param {oro.filter.AbstractFilter} filter
         * @protected
         */
        _onFilterDisabled: function(filter) {
            this.trigger('disableFilter', filter);
            this.disableFilter(filter);
            this.trigger('afterDisableFilter', filter);

            this._publishCountSelectedFilters();
        },

        _onFilterShowCriteria: function(shownFilter) {
            _.each(this.filters, function(filter) {
                if (filter !== shownFilter) {
                    _.result(filter, 'ensurePopupCriteriaClosed');
                }
            });

            this._publishCountSelectedFilters();
        },

        /**
         * Returns list of filter raw values
         */
        getValues: function() {
            var values = {};
            _.each(this.filters, function(filter) {
                if (filter.enabled) {
                    values[filter.name] = filter.getValue();
                }
            }, this);

            return values;
        },

        /**
         * Sets raw values for filters
         */
        setValues: function(values) {
            _.each(values, function(value, name) {
                if (_.has(this.filters, name)) {
                    this.filters[name].setValue(value);
                }
            }, this);
        },

        /**
         * Triggers when filter select is changed
         *
         * @protected
         */
        _onChangeFilterSelect: function() {
            this.trigger('updateList', this);
            this._processFilterStatus();
            this.trigger('afterUpdateList', this);
        },

        /**
         * Enable filter
         *
         * @param {oro.filter.AbstractFilter} filter
         * @return {*}
         */
        enableFilter: function(filter) {
            return this.enableFilters([filter]);
        },

        /**
         * Disable filter
         *
         * @param {oro.filter.AbstractFilter} filter
         * @return {*}
         */
        disableFilter: function(filter) {
            return this.disableFilters([filter]);
        },

        /**
         * Enable filters
         *
         * @param filters []
         * @return {*}
         */
        enableFilters: function(filters) {
            if (_.isEmpty(filters)) {
                return this;
            }
            var optionsSelectors = [];

            _.each(filters, function(filter) {
                if (filter.visible && !filter.isRendered()) {
                    var oldEl = filter.$el;
                    // filter rendering process replaces $el
                    filter.render();
                    // so we need to replace element which keeps place in DOM with actual filter $el after rendering
                    oldEl.replaceWith(filter.$el);
                    filter.rendered();
                }
                filter.enable();
                optionsSelectors.push('option[value="' + filter.name + '"]:not(:selected)');
            }, this);

            var options = this.$(this.filterSelector).find(optionsSelectors.join(','));
            if (options.length) {
                options.prop('selected', true);
            }

            if (optionsSelectors.length) {
                this.selectWidget.multiselect('refresh');
            }

            return this;
        },

        /**
         * Disable filters
         *
         * @param filters []
         * @return {*}
         */
        disableFilters: function(filters) {
            if (_.isEmpty(filters)) {
                return this;
            }
            var optionsSelectors = [];

            _.each(filters, function(filter) {
                filter.disable();
                optionsSelectors.push('option[value="' + filter.name + '"]:selected');
            }, this);

            var options = this.$(this.filterSelector).find(optionsSelectors.join(','));
            if (options.length) {
                options.prop('selected', false);
            }

            if (optionsSelectors.length) {
                this.selectWidget.multiselect('refresh');
            }

            return this;
        },

        getTemplateData: function() {
            return {filters: this.filters};
        },

        /**
         * Render filter list
         *
         * @return {*}
         */
        render: function() {
            this.setElement(
                $(this.template(this.getTemplateData()))
            );

            this.dropdownContainer = this.$el.find('.filter-container');
            var $filterItems = this.dropdownContainer.find('.filter-items');

            _.each(this.filters, function(filter) {
                if (_.isFunction(filter.setDropdownContainer)) {
                    filter.setDropdownContainer(this.dropdownContainer);
                }
                if (!filter.enabled || !filter.visible) {
                    // append element to reserve space
                    // empty elements are hidden by default
                    $filterItems.append(filter.$el);
                    return;
                }
                filter.render();
                $filterItems.append(filter.$el);
                filter.rendered();

            }, this);

            this.trigger('rendered');

            if (_.isEmpty(this.filters)) {
                this.$el.hide();
            } else {
                this._initializeSelectWidget();
            }
            var filtersStateView = this.subview('filters-state');
            if (filtersStateView) {
                filtersStateView.render();
                if (this.viewMode === FiltersManager.MANAGE_VIEW_MODE) {
                    filtersStateView.hide();
                } else if (this.viewMode === FiltersManager.STATE_VIEW_MODE) {
                    this.$el.hide();
                }
            }

            return this;
        },

        _publishCountSelectedFilters: function() {
            var selectedFilters = this._calculateSelectedFilters();
            mediator.trigger(
                'filterManager:selectedFilters:count:' + this.collection.options.gridName,
                selectedFilters
            );
        },

        /**
         * @returns {Number} count of selected filters
         * @private
         */
        _calculateSelectedFilters: function() {
            return _.reduce(this.filters, function(memo, filter) {
                var num = (filter.enabled && !_.isEqual(filter.emptyValue, filter.value)) ? 1 : 0;

                return memo + num;
            }, 0);
        },

        _resetHintContainer: function() {
            var $container = this.dropdownContainer.find('.filter-items-hint');
            var show = false;
            $container.children('span').each(function() {
                if (this.style.display !== 'none') {
                    show = true;
                    return false;
                }
            });
            if (show) {
                $container.show();
            } else {
                $container.hide();
            }

            mediator.trigger('filterManager:selectedFilters:count:' + this.collection.options.gridName, 0);
        },

        /**
         * Initialize multiselect widget
         *
         * @protected
         */
        _initializeSelectWidget: function() {
            var $button;
            var multiselectDefaults = {
                multiple: true,
                selectedList: 0,
                classes: 'select-filter-widget',
                position: {
                    my: 'left top+2',
                    at: 'left bottom'
                }
            };
            var options = _.extend(
                multiselectDefaults,
                {
                    selectedText: this.addButtonHint,
                    beforeopen: _.bind(function() {
                        _.each(this.filters, function(filter) {
                            filter.close();
                        });
                        this.selectWidget.onBeforeOpenDropdown();
                    }, this),
                    open: _.bind(function() {
                        this.selectWidget.onOpenDropdown();
                        this._setDropdownWidth();
                    }, this),
                    refresh: _.bind(function() {
                        this.selectWidget.onRefresh();
                    }, this),
                    appendTo: this.dropdownContainer
                },
                this.multiselectParameters
            );

            this.selectWidget = new this.MultiselectDecorator({
                element: this.$(this.filterSelector),
                parameters: options
            });

            this.selectWidget.setViewDesign(this);
            $button = this.selectWidget.multiselect('instance').button;
            this._setButtonDesign($button);
            this._setButtonReset();
        },
        /**
         * Set design for filter manager button
         *
         * @protected
         */
        _setButtonDesign: function($button) {
            $button.find('span:first').replaceWith(
                '' + this.addButtonHint +
                ''
            );
        },

        /**
         *  Create html node
         *
         * @returns {*|jQuery|HTMLElement}
         * @private
         */
        _createButtonReset: function() {
            return $(
                '
' +
                    '' +
                        '' + this.multiselectResetButtonLabel + '' +
                    '' +
                '
'
            );
        },

        /**
         * Set button for reset filters
         *
         * @protected
         */
        _setButtonReset: function() {
            var $footerContainer = this._createButtonReset();
            var instance = this.selectWidget.multiselect('instance');
            instance.menu.append($footerContainer);
        },

        /**
         * Set design for select dropdown
         *
         * @protected
         */
        _setDropdownWidth: function() {
            var widget = this.selectWidget.getWidget();
            var requiredWidth = this.selectWidget.getMinimumDropdownWidth() + 24;
            widget.width(requiredWidth).css('min-width', requiredWidth + 'px');
            widget.find('input[type="search"]').width(requiredWidth - 30);
        },

        /**
         * Activate/deactivate all filter depends on its status
         *
         * @protected
         */
        _processFilterStatus: function() {
            var activeFilters = this.$(this.filterSelector).val();

            _.each(this.filters, function(filter, name) {
                if (!filter.enabled && _.indexOf(activeFilters, name) !== -1) {
                    this.enableFilter(filter);
                } else if (filter.enabled && _.indexOf(activeFilters, name) === -1) {
                    this.disableFilter(filter);
                }
            }, this);
        },

        /**
         * Reset button click handler
         */
        _onReset: function() {
            this.collection.state.filters = {};
            this.collection.trigger('updateState', this.collection);
            mediator.trigger('datagrid:doRefresh:' + this.collection.inputName);
        },

        /**
         * Dropdown button toggle handler
         * @param e
         * @private
         */
        _onDropdownToggle: function(e) {
            e.preventDefault();
            this.$el.find('> .dropdown').toggleClass('open');
        },

        /**
         * Handles click on body element
         * closes the filters-dropdown if event target does not belong to the view element
         *
         * @param {jQuery.Event} e
         * @protected
         */
        _onOutsideActionEvent: function(e) {
            if (!_.contains($(e.target).parents(), this.el)) {
                this.closeDropdown();
            }
        },

        /**
         * Close dropdown
         */
        closeDropdown: function() {
            this.$('.dropdown').removeClass('oro-open');
        },

        /**
         * On mobile closes filter box if value is changed
         */
        _onUpdateCriteriaClick: function(filter) {
            filter.once('update', this.closeDropdown, this);
            _.defer(_.bind(filter.off, filter, 'update', this.closeDropdown, this));
        },

        getViewMode: function() {
            return this.viewMode;
        },

        setViewMode: function(mode) {
            if (this.viewMode === mode) {
                return;
            }
            if (mode === FiltersManager.STATE_VIEW_MODE) {
                this.$el.hide();
                _.result(this.subview('filters-state'), 'show');
            } else if (mode === FiltersManager.MANAGE_VIEW_MODE) {
                if (!_.isEmpty(this.filters)) {
                    this.$el.show();
                }
                _.result(this.subview('filters-state'), 'hide');
            } else {
                return;
            }
            this.viewMode = mode;
            persistentStorage.setItem(FiltersManager.STORAGE_KEY, mode);
            this.trigger('changeViewMode', mode);
        }
    });

    _.extend(FiltersManager, {
        MANAGE_VIEW_MODE: 0,
        STATE_VIEW_MODE: 1,
        STORAGE_KEY: 'filter-view-mode-state'
    });

    return FiltersManager;
});
<commit_msg>BB-10905: Refactor includes filters templates with good parts<commit_after>define(function(require) {
    'use strict';

    var FiltersManager;
    var template = require('tpl!orofilter/templates/filters-container.html');
    var $ = require('jquery');
    var _ = require('underscore');
    var __ = require('orotranslation/js/translator');
    var mediator = require('oroui/js/mediator');
    var tools = require('oroui/js/tools');
    var BaseView = require('oroui/js/app/views/base/view');
    var MultiselectDecorator = require('./multiselect-decorator');
    var filterWrapper = require('./datafilter-wrapper');
    var FiltersStateView = require('./app/views/filters-state-view');
    var persistentStorage = require('oroui/js/persistent-storage');

    /**
     * View that represents all grid filters
     *
     * @export  orofilter/js/filters-manager
     * @class   orofilter.FiltersManager
     * @extends BaseView
     *
     * @event updateList    on update of filter list
     * @event updateFilter  on update data of specific filter
     * @event disableFilter on disable specific filter
     */
    FiltersManager = BaseView.extend({
        /**
         * List of filter objects
         *
         * @type {Object}
         * @property
         */
        filters: null,

        /**
         * Template
         */
        template: template,

        /**
         * Mode of filters displaying
         *
         * @type {Integer}
         * @property
         */
        viewMode: NaN,

        /**
         * Filter list input selector
         *
         * @property
         */
        filterSelector: '[data-action=add-filter-select]',

        /**
         * Add filter button hint
         *
         * @property
         */
        addButtonHint: __('oro_datagrid.label_add_filter'),

        /**
         * Set label for reset button
         *
         * @property
         */
        multiselectResetButtonLabel: __('oro_datagrid.label_reset_button'),

        /**
         * Select widget object
         *
         * @property {oro.MultiselectDecorator}
         */
        selectWidget: null,

        /**
         * Select widget constructor
         *
         * @property
         */
        MultiselectDecorator: MultiselectDecorator,

        /**
         *  Parameters Select widget constructor
         *
         * @property
         */
        multiselectParameters: {},

        /**
         * ImportExport button selector
         *
         * @property
         */
        buttonSelector: '.ui-multiselect.filter-list',

        /**
         * jQuery object that will be target for append multiselect dropdown menus
         *
         * @property
         */
        dropdownContainer: 'body',

        /** @property */
        events: {
            'change [data-action=add-filter-select]': '_onChangeFilterSelect',
            'click .reset-filter-button': '_onReset',
            'click a[data-name="filters-dropdown"]': '_onDropdownToggle',
            'click [data-role="reset-filters"]': '_onReset'
        },

        /**
         * Initialize filter list options
         *
         * @param {Object} options
         * @param {Object} [options.filters]
         * @param {String} [options.addButtonHint]
         */
        initialize: function(options) {
            var prop = ['addButtonHint', 'multiselectResetButtonLabel', 'stateViewElement', 'viewMode'];
            this.template = this.getTemplateFunction();
            this.filters = {};

            _.extend(this, _.pick(options, prop));

            if (options.filters) {
                _.extend(this.filters, options.filters);
            }

            var filterListeners = {
                'update': this._onFilterUpdated,
                'disable': this._onFilterDisabled,
                'showCriteria': this._onFilterShowCriteria
            };

            if (tools.isMobile()) {
                var outsideActionEvents = 'click.' + this.cid + ' shown.bs.dropdown.' + this.cid;
                filterListeners.updateCriteriaClick = this._onUpdateCriteriaClick;
                $('body').on(outsideActionEvents, this._onOutsideActionEvent.bind(this));
            }

            _.each(this.filters, function(filter) {
                if (filter.wrappable) {
                    _.extend(filter, filterWrapper);
                }

                this.listenTo(filter, filterListeners);
            }, this);

            if ('filtersStateElement' in options) {
                var $container = this.$el.closest('body, .ui-dialog');
                var filtersStateView = new FiltersStateView({
                    el: $container.find(options.filtersStateElement).first(),
                    filters: options.filters
                });

                this.subview('filters-state', filtersStateView);
                this.listenTo(filtersStateView, 'clicked', function() {
                    this.setViewMode(FiltersManager.MANAGE_VIEW_MODE);
                });
            }

            var selectedFilters = this._calculateSelectedFilters();
            mediator.on(
                'filterManager:selectedFilters:count:' + this.collection.options.gridName,
                selectedFilters
            );

            FiltersManager.__super__.initialize.apply(this, arguments);
        },

        /**
         * @inheritDoc
         */
        dispose: function() {
            if (this.disposed) {
                return;
            }
            $('body').off('.' + this.cid);
            _.each(this.filters, function(filter) {
                filter.dispose();
            });
            delete this.filters;
            if (this.selectWidget) {
                this.selectWidget.dispose();
                delete this.selectWidget;
            }
            FiltersManager.__super__.dispose.call(this);
        },

        /**
         * Triggers when filter is updated
         *
         * @param {oro.filter.AbstractFilter} filter
         * @protected
         */
        _onFilterUpdated: function(filter) {
            this._resetHintContainer();
            this.trigger('updateFilter', filter);

            this._publishCountSelectedFilters();
        },

        /**
         * Triggers when filter is disabled
         *
         * @param {oro.filter.AbstractFilter} filter
         * @protected
         */
        _onFilterDisabled: function(filter) {
            this.trigger('disableFilter', filter);
            this.disableFilter(filter);
            this.trigger('afterDisableFilter', filter);

            this._publishCountSelectedFilters();
        },

        _onFilterShowCriteria: function(shownFilter) {
            _.each(this.filters, function(filter) {
                if (filter !== shownFilter) {
                    _.result(filter, 'ensurePopupCriteriaClosed');
                }
            });

            this._publishCountSelectedFilters();
        },

        /**
         * Returns list of filter raw values
         */
        getValues: function() {
            var values = {};
            _.each(this.filters, function(filter) {
                if (filter.enabled) {
                    values[filter.name] = filter.getValue();
                }
            }, this);

            return values;
        },

        /**
         * Sets raw values for filters
         */
        setValues: function(values) {
            _.each(values, function(value, name) {
                if (_.has(this.filters, name)) {
                    this.filters[name].setValue(value);
                }
            }, this);
        },

        /**
         * Triggers when filter select is changed
         *
         * @protected
         */
        _onChangeFilterSelect: function() {
            this.trigger('updateList', this);
            this._processFilterStatus();
            this.trigger('afterUpdateList', this);
        },

        /**
         * Enable filter
         *
         * @param {oro.filter.AbstractFilter} filter
         * @return {*}
         */
        enableFilter: function(filter) {
            return this.enableFilters([filter]);
        },

        /**
         * Disable filter
         *
         * @param {oro.filter.AbstractFilter} filter
         * @return {*}
         */
        disableFilter: function(filter) {
            return this.disableFilters([filter]);
        },

        /**
         * Enable filters
         *
         * @param filters []
         * @return {*}
         */
        enableFilters: function(filters) {
            if (_.isEmpty(filters)) {
                return this;
            }
            var optionsSelectors = [];

            _.each(filters, function(filter) {
                if (filter.visible && !filter.isRendered()) {
                    var oldEl = filter.$el;
                    // filter rendering process replaces $el
                    filter.render();
                    // so we need to replace element which keeps place in DOM with actual filter $el after rendering
                    oldEl.replaceWith(filter.$el);
                    filter.rendered();
                }
                filter.enable();
                optionsSelectors.push('option[value="' + filter.name + '"]:not(:selected)');
            }, this);

            var options = this.$(this.filterSelector).find(optionsSelectors.join(','));
            if (options.length) {
                options.prop('selected', true);
            }

            if (optionsSelectors.length) {
                this.selectWidget.multiselect('refresh');
            }

            return this;
        },

        /**
         * Disable filters
         *
         * @param filters []
         * @return {*}
         */
        disableFilters: function(filters) {
            if (_.isEmpty(filters)) {
                return this;
            }
            var optionsSelectors = [];

            _.each(filters, function(filter) {
                filter.disable();
                optionsSelectors.push('option[value="' + filter.name + '"]:selected');
            }, this);

            var options = this.$(this.filterSelector).find(optionsSelectors.join(','));
            if (options.length) {
                options.prop('selected', false);
            }

            if (optionsSelectors.length) {
                this.selectWidget.multiselect('refresh');
            }

            return this;
        },

        getTemplateData: function() {
            return {filters: this.filters};
        },

        /**
         * Render filter list
         *
         * @return {*}
         */
        render: function() {
            this.setElement(
                $(this.template(this.getTemplateData()))
            );

            this.dropdownContainer = this.$el.find('.filter-container');
            var $filterItems = this.dropdownContainer.find('.filter-items');

            _.each(this.filters, function(filter) {
                if (_.isFunction(filter.setDropdownContainer)) {
                    filter.setDropdownContainer(this.dropdownContainer);
                }
                if (!filter.enabled || !filter.visible) {
                    // append element to reserve space
                    // empty elements are hidden by default
                    $filterItems.append(filter.$el);
                    return;
                }
                filter.render();
                $filterItems.append(filter.$el);
                filter.rendered();

            }, this);

            this.trigger('rendered');

            if (_.isEmpty(this.filters)) {
                this.$el.hide();
            } else {
                this._initializeSelectWidget();
            }
            var filtersStateView = this.subview('filters-state');
            if (filtersStateView) {
                filtersStateView.render();
                if (this.viewMode === FiltersManager.MANAGE_VIEW_MODE) {
                    filtersStateView.hide();
                } else if (this.viewMode === FiltersManager.STATE_VIEW_MODE) {
                    this.$el.hide();
                }
            }

            return this;
        },

        /**
         * @param {Number} count
         * @private
         */
        _publishCountSelectedFilters: function(count) {
            var selectedFilters = count || this._calculateSelectedFilters();
            mediator.trigger(
                'filterManager:selectedFilters:count:' + this.collection.options.gridName,
                selectedFilters
            );
        },

        /**
         * @returns {Number} count of selected filters
         * @private
         */
        _calculateSelectedFilters: function() {
            return _.reduce(this.filters, function(memo, filter) {
                var num = (filter.enabled && !_.isEqual(filter.emptyValue, filter.value)) ? 1 : 0;

                return memo + num;
            }, 0);
        },

        _resetHintContainer: function() {
            var $container = this.dropdownContainer.find('.filter-items-hint');
            var show = false;
            $container.children('span').each(function() {
                if (this.style.display !== 'none') {
                    show = true;
                    return false;
                }
            });
            if (show) {
                $container.show();
            } else {
                $container.hide();
            }

            this._publishCountSelectedFilters(0);
        },

        /**
         * Initialize multiselect widget
         *
         * @protected
         */
        _initializeSelectWidget: function() {
            var $button;
            var multiselectDefaults = {
                multiple: true,
                selectedList: 0,
                classes: 'select-filter-widget',
                position: {
                    my: 'left top+2',
                    at: 'left bottom'
                }
            };
            var options = _.extend(
                multiselectDefaults,
                {
                    selectedText: this.addButtonHint,
                    beforeopen: _.bind(function() {
                        _.each(this.filters, function(filter) {
                            filter.close();
                        });
                        this.selectWidget.onBeforeOpenDropdown();
                    }, this),
                    open: _.bind(function() {
                        this.selectWidget.onOpenDropdown();
                        this._setDropdownWidth();
                    }, this),
                    refresh: _.bind(function() {
                        this.selectWidget.onRefresh();
                    }, this),
                    appendTo: this.dropdownContainer
                },
                this.multiselectParameters
            );

            this.selectWidget = new this.MultiselectDecorator({
                element: this.$(this.filterSelector),
                parameters: options
            });

            this.selectWidget.setViewDesign(this);
            $button = this.selectWidget.multiselect('instance').button;
            this._setButtonDesign($button);
            this._setButtonReset();
        },
        /**
         * Set design for filter manager button
         *
         * @protected
         */
        _setButtonDesign: function($button) {
            $button.find('span:first').replaceWith(
                '' + this.addButtonHint +
                ''
            );
        },

        /**
         *  Create html node
         *
         * @returns {*|jQuery|HTMLElement}
         * @private
         */
        _createButtonReset: function() {
            return $(
                '
' +
                    '' +
                        '' + this.multiselectResetButtonLabel + '' +
                    '' +
                '
'
            );
        },

        /**
         * Set button for reset filters
         *
         * @protected
         */
        _setButtonReset: function() {
            var $footerContainer = this._createButtonReset();
            var instance = this.selectWidget.multiselect('instance');
            instance.menu.append($footerContainer);
        },

        /**
         * Set design for select dropdown
         *
         * @protected
         */
        _setDropdownWidth: function() {
            var widget = this.selectWidget.getWidget();
            var requiredWidth = this.selectWidget.getMinimumDropdownWidth() + 24;
            widget.width(requiredWidth).css('min-width', requiredWidth + 'px');
            widget.find('input[type="search"]').width(requiredWidth - 30);
        },

        /**
         * Activate/deactivate all filter depends on its status
         *
         * @protected
         */
        _processFilterStatus: function() {
            var activeFilters = this.$(this.filterSelector).val();

            _.each(this.filters, function(filter, name) {
                if (!filter.enabled && _.indexOf(activeFilters, name) !== -1) {
                    this.enableFilter(filter);
                } else if (filter.enabled && _.indexOf(activeFilters, name) === -1) {
                    this.disableFilter(filter);
                }
            }, this);
        },

        /**
         * Reset button click handler
         */
        _onReset: function() {
            this.collection.state.filters = {};
            this.collection.trigger('updateState', this.collection);
            mediator.trigger('datagrid:doRefresh:' + this.collection.inputName);
        },

        /**
         * Dropdown button toggle handler
         * @param e
         * @private
         */
        _onDropdownToggle: function(e) {
            e.preventDefault();
            this.$el.find('> .dropdown').toggleClass('open');
        },

        /**
         * Handles click on body element
         * closes the filters-dropdown if event target does not belong to the view element
         *
         * @param {jQuery.Event} e
         * @protected
         */
        _onOutsideActionEvent: function(e) {
            if (!_.contains($(e.target).parents(), this.el)) {
                this.closeDropdown();
            }
        },

        /**
         * Close dropdown
         */
        closeDropdown: function() {
            this.$('.dropdown').removeClass('oro-open');
        },

        /**
         * On mobile closes filter box if value is changed
         */
        _onUpdateCriteriaClick: function(filter) {
            filter.once('update', this.closeDropdown, this);
            _.defer(_.bind(filter.off, filter, 'update', this.closeDropdown, this));
        },

        getViewMode: function() {
            return this.viewMode;
        },

        setViewMode: function(mode) {
            if (this.viewMode === mode) {
                return;
            }
            if (mode === FiltersManager.STATE_VIEW_MODE) {
                this.$el.hide();
                _.result(this.subview('filters-state'), 'show');
            } else if (mode === FiltersManager.MANAGE_VIEW_MODE) {
                if (!_.isEmpty(this.filters)) {
                    this.$el.show();
                }
                _.result(this.subview('filters-state'), 'hide');
            } else {
                return;
            }
            this.viewMode = mode;
            persistentStorage.setItem(FiltersManager.STORAGE_KEY, mode);
            this.trigger('changeViewMode', mode);
        }
    });

    _.extend(FiltersManager, {
        MANAGE_VIEW_MODE: 0,
        STATE_VIEW_MODE: 1,
        STORAGE_KEY: 'filter-view-mode-state'
    });

    return FiltersManager;
});
<|endoftext|>


<commit_before><commit_msg>Update parcialdimensionar - TESTE.js<commit_after><|endoftext|>


<commit_before>/** @jsx React.DOM */
var React = require('react');
//var Autocomplete = require('react-autocomplete');
var Autocomplete = require('../../lib/main');
var Combobox = Autocomplete.Combobox;
var ComboboxOption = Autocomplete.Option;
var states = require('../states');

var App = React.createClass({

  getInitialState: function() {
    return {
      // the data the user can select from
      states: states,

      // the current selection
      selectedStateId: 'UT'
    };
  },

  // called by the combobox when the user types into the field the point is to
  // set some state to cause a redraw of the options
  handleInput: function(userInput) {
    // make sure to clear out the current selection
    this.setState({selectedStateId: null}, function() {
      // and then do our client-side filtering, need to it after setState has happened
      // so that the value doesn't get rerendered to hte old selectedStateId
      // (this might be bad implementation at this point, still exploring a better
      // way to handle this)
      this.filterStates(userInput);
    }.bind(this));
  },

  // this demo uses client-side filtering, but you can easily query a server
  // instead and then set state when the response lands
  filterStates: function(userInput) {
    if (userInput === '')
      return this.setState({states: states});
    var filter = new RegExp('^'+userInput, 'i');
    setTimeout(function() {
      this.setState({states: states.filter(function(state) {
        // you can match anything you want, not just the labels
        return filter.test(state.name) || filter.test(state.id);
      })});
    }.bind(this), 500);
  },

  // Called by the Combobox when the user makes a selection
  handleStateSelect: function(value) {
    this.setState({
      selectedStateId: value,
      // for client-side filtering you probably want to populate your list
      // again so when they open it they can choose something besides what they
      // just picked
      states: states
    });
  },

  renderComboboxOptions: function() {
    // render calls this, it creates all the options for the combobox
    return this.state.states.map(function(state) {
      return (
        <ComboboxOption
          key={state.id}
          value={state.id}
        >{state.name}</ComboboxOption>
      );
    });
  },

  render: function() {
    var menuContent = this.state.states.length ?
      this.renderComboboxOptions() :
      // if none of the options match what the user has typed, tell them

No matches
;
    return (

React Combobox

Demo Source

Selected State: {this.state.selectedStateId}

        <Combobox
          onInput={this.handleInput}
          onSelect={this.handleStateSelect}
          value={this.state.selectedStateId}
        >
          {menuContent}
        </Combobox>

<button>something else to focus</button>

    );
  }
});

React.renderComponent(<App/>, document.body);

<commit_msg>Point back at this copy.<commit_after>/** @jsx React.DOM */
var React = require('react');
//var Autocomplete = require('react-autocomplete');
var Autocomplete = require('../../lib/main');
var Combobox = Autocomplete.Combobox;
var ComboboxOption = Autocomplete.Option;
var states = require('../states');

var App = React.createClass({

  getInitialState: function() {
    return {
      // the data the user can select from
      states: states,

      // the current selection
      selectedStateId: 'UT'
    };
  },

  // called by the combobox when the user types into the field the point is to
  // set some state to cause a redraw of the options
  handleInput: function(userInput) {
    // make sure to clear out the current selection
    this.setState({selectedStateId: null}, function() {
      // and then do our client-side filtering, need to it after setState has happened
      // so that the value doesn't get rerendered to hte old selectedStateId
      // (this might be bad implementation at this point, still exploring a better
      // way to handle this)
      this.filterStates(userInput);
    }.bind(this));
  },

  // this demo uses client-side filtering, but you can easily query a server
  // instead and then set state when the response lands
  filterStates: function(userInput) {
    if (userInput === '')
      return this.setState({states: states});
    var filter = new RegExp('^'+userInput, 'i');
    setTimeout(function() {
      this.setState({states: states.filter(function(state) {
        // you can match anything you want, not just the labels
        return filter.test(state.name) || filter.test(state.id);
      })});
    }.bind(this), 500);
  },

  // Called by the Combobox when the user makes a selection
  handleStateSelect: function(value) {
    this.setState({
      selectedStateId: value,
      // for client-side filtering you probably want to populate your list
      // again so when they open it they can choose something besides what they
      // just picked
      states: states
    });
  },

  renderComboboxOptions: function() {
    // render calls this, it creates all the options for the combobox
    return this.state.states.map(function(state) {
      return (
        <ComboboxOption
          key={state.id}
          value={state.id}
        >{state.name}</ComboboxOption>
      );
    });
  },

  render: function() {
    var menuContent = this.state.states.length ?
      this.renderComboboxOptions() :
      // if none of the options match what the user has typed, tell them

No matches
;
    return (

React Combobox

Demo Source

Selected State: {this.state.selectedStateId}

        <Combobox
          onInput={this.handleInput}
          onSelect={this.handleStateSelect}
          value={this.state.selectedStateId}
        >
          {menuContent}
        </Combobox>

<button>something else to focus</button>

    );
  }
});

React.renderComponent(<App/>, document.body);

<|endoftext|>


<commit_before>'use strict'

const _ = require('lodash')
const geojsonError = new Error('Invalid GeoJSON Feature or geometry')
const gjv = require('geojson-validation')

const stac_version = '0.6.0-rc2'

function STAC(path, endpoint, query, backend, respond = () => {}) {
  // default page and limit
  const _query = Object.assign({}, query)
  const page = parseInt(_query.page) || 1
  const limit = parseInt(_query.limit) || 1
  delete _query.page
  delete _query.limit

  console.log(`Query page=${page}, limit=${limit}`)

  // split and remove empty strings
  const resources = path.split('/').filter((x) => x)
  console.log('resources', resources)

  // make sure this is a STAC endpoint
  if (resources[0] !== 'stac') {
    const msg = 'endpoint not defined (use /stac)'
    console.log(msg, resources)
    respond(null, msg)
    return
  }

  let msg

  // /stac
  if (resources.length === 1) {
    msg = 'STAC catalog (see endpoints /search and /collections)'
    const catalog = {
      id: 'sat-api',
      description: 'A STAC API of public datasets',
      'satapi:version': stac_version,
      stac_version: stac_version,
      links: [
        { rel: 'self', href: `${endpoint}/stac` }
      ]
    }
    const api = new API(backend, _query, endpoint)
    api.search_collections((err, results) => {
      if (err) respond(err)
      results.collections.forEach((c) => {
        catalog.links.push({ rel: 'child', href: `${endpoint}/stac/collections/${c.id}` })
      })
      respond(null, catalog)
    })
  } else {
    // drop the /stac prefix
    resources.splice(0, 1)
    // STAC endpoints
    switch (resources[0]) {
    case 'api':
      msg = 'TODO - return API doc'
      console.log(msg, resources)
      respond(null, msg)
      break
    // collections endpoint
    case 'collections':
      if (resources.length === 1) {
        // all collections
        const api = new API(backend, _query, endpoint)
        api.search_collections(respond)
      } else if (resources.length === 2) {
        // specific collection
        const api = new API(backend, _query, endpoint)
        api.get_collection(resources[1], respond)
      } else if (resources[2] == 'items') {
        console.log('search items in this collection')
        // this is a search across items in this collection
        _query.collection = resources[1]
        const api = new API(backend, _query, endpoint)
        api.search_items(page, limit, respond)
      } else if (resources[2] === 'item' && resources.length === 4) {
        // Get specific item in collection
        const api = new API(backend, _query, endpoint)
        api.get_item(resources[3], respond)
      } else {
        msg = 'endpoint not defined'
        console.log(msg, resources)
        respond(null, msg)
      }
      break
    case 'search':
      // items api
      const api = new API(backend, _query, endpoint)
      api.search_items(page, limit, respond)
      break
    default:
      respond(null, 'endpoint not defined')
    }
  }

}

// Elasticsearch search class
function API(backend, params, endpoint) {
  this.backend = backend
  this.params = params
  this.endpoint = endpoint
  this.clink = `${this.endpoint}/collections`

  // process GeoJSON if provided
  if (this.params.intersects) {
    let geojson = params.intersects
    // if we receive a string, try to parse as GeoJSON, otherwise assume it is GeoJSON
    if (typeof geojson === 'string') {
      try {
        geojson = JSON.parse(geojson)
      }
      catch (e) {
        throw geojsonError
      }
    }
    if (gjv.valid(geojson)) {
      if (geojson.type === 'FeatureCollection') {
        throw geojsonError
      } else if (geojson.type !== 'Feature') {
        geojson = {
          type: 'Feature',
          properties: {},
          geometry: geojson
        }
      } else {
        throw geojsonError
      }
    }
    this.params.intersects = geojson
  }
}

// Search collections
API.prototype.search_collections = function (callback) {
  // hacky way to remove geometry from search of collections...temporary
  let geom
  if (_.has(this.params, 'intersects')) {
    geom = this.params.intersects
    this.params = _.omit(this.params, 'intersects')
  }

  this.backend.search(this.params, 'collections', 1, 100, (err, resp) => {
    // set geometry back
    if (geom) {
      this.params.intersects = geom
    }

    resp.results.forEach((a, i, arr) => {
      // self link
      arr[i].links.splice(0, 0, { rel: 'self', href: `${this.clink}/${a.id}` })
      // parent catalog
      arr[i].links.push({ rel: 'parent', href: `${this.endpoint}/stac` })
      // root catalog
      arr[i].links.push({ rel: 'root', href: `${this.endpoint}/stac` })
      // child items
      arr[i].links.push({ rel: 'items', href: `${this.clink}/${a.id}/items` })
    })

    resp.collections = resp.results
    delete resp.results

    callback(err, resp)
  })
}

// Get a single collection by name
API.prototype.get_collection = function (collection, callback) {
  const params = this.params
  this.params = { 'id': collection }
  this.search_collections((err, resp) => {
    this.params = params
    if (resp.collections.length === 1) {
      callback(err, resp.collections[0])
    } else {
      callback(err, {})
    }
  })
}

// Search items (searching both collections and items)
API.prototype.search_items = function (page = 1, limit = 1, callback) {
  // check collection first
  this.search_collections((err, resp) => {
    const collections = resp.collections.map((c) => c.id)
    if (collections.length === 0) {
      const _resp = {
        type: 'FeatureCollection',
        meta: { found: 0, returned: 0, limit: limit, page: page },
        features: []
      }
      callback(null, _resp)
    } else {
      // shallow copy of this.params
      const params = { ...this.params }
      this.params.collection = collections.join(',')

      this.backend.search(this.params, 'items', page, limit, (err, response) => {
        response.results.forEach((a, i, arr) => {
          // self link
          arr[i].links.splice(0, 0, {
            rel: 'self',
            href: `${this.clink}/${a.properties.collection}/item/${a.id}`
          })
          // parent link
          arr[i].links.push({ rel: 'parent', href: `${this.clink}/${a.properties.collection}` })
          arr[i].links.push({ rel: 'collection', href: `${this.clink}/${a.properties.collection}` })
          arr[i].links.push({ rel: 'root', href: `${this.endpoint}/stac` })
          arr[i]['type'] = 'Feature'
        })
        response.type = 'FeatureCollection'
        response.features = response.results
        delete response.results
        // add next link if not last page
        if ((page * limit) < response.meta.found) {
          params.page = page + 1
          params.limit = limit
          response.links = [{
            rel: 'next',
            title: 'Next page of results',
            href: `${this.endpoint}/stac/search?` + dictToURI(params)
          }]
        }
        callback(null, resp)
      })
    }
  })
}

API.prototype.get_item = function (id, callback) {
  this.backend.search({ id }, 'items', 1, 1, (err, resp) => {
    if (resp.results.length === 1) {
      const item = resp.results[0]
      // self link
      item.links.splice(0, 0, {
        rel: 'self',
        href: `${this.clink}/${item.properties.collection}/item/${item.id}`
      })
      // parent link
      item.links.push({ rel: 'parent', href: `${this.clink}/${item.properties.collection}` })
      item.links.push({ rel: 'collection', href: `${this.clink}/${item.properties.collection}` })
      item.links.push({ rel: 'root', href: `${this.endpoint}/stac` })
      item.type = 'Feature'
      callback(err, item)
    } else {
      callback(err, {})
    }
  })
}

// h/t https://medium.com/@mattccrampton/convert-a-javascript-dictionary-to-get-url-parameters-b77da8c78ec8
function dictToURI(dict) {
  let str = []
  for(var p in dict){
     str.push(encodeURIComponent(p) + "=" + encodeURIComponent(dict[p]));
  }
  return str.join("&")
}

module.exports.stac_version = stac_version
module.exports.STAC = STAC
<commit_msg>do some more linting<commit_after>'use strict'

const _ = require('lodash')
const geojsonError = new Error('Invalid GeoJSON Feature or geometry')
const gjv = require('geojson-validation')

const stac_version = '0.6.0-rc2'

// Elasticsearch search class
function API(backend, params, endpoint) {
  this.backend = backend
  this.params = params
  this.endpoint = endpoint
  this.clink = `${this.endpoint}/collections`

  // process GeoJSON if provided
  if (this.params.intersects) {
    let geojson = params.intersects
    // if we receive a string, try to parse as GeoJSON, otherwise assume it is GeoJSON
    if (typeof geojson === 'string') {
      try {
        geojson = JSON.parse(geojson)
      }
      catch (e) {
        throw geojsonError
      }
    }
    if (gjv.valid(geojson)) {
      if (geojson.type === 'FeatureCollection') {
        throw geojsonError
      } else if (geojson.type !== 'Feature') {
        geojson = {
          type: 'Feature',
          properties: {},
          geometry: geojson
        }
      } else {
        throw geojsonError
      }
    }
    this.params.intersects = geojson
  }
}

// Search collections
API.prototype.search_collections = function (callback) {
  // hacky way to remove geometry from search of collections...temporary
  let geom
  if (_.has(this.params, 'intersects')) {
    geom = this.params.intersects
    this.params = _.omit(this.params, 'intersects')
  }

  this.backend.search(this.params, 'collections', 1, 100, (err, resp) => {
    // set geometry back
    if (geom) {
      this.params.intersects = geom
    }

    resp.results.forEach((a, i, arr) => {
      // self link
      arr[i].links.splice(0, 0, { rel: 'self', href: `${this.clink}/${a.id}` })
      // parent catalog
      arr[i].links.push({ rel: 'parent', href: `${this.endpoint}/stac` })
      // root catalog
      arr[i].links.push({ rel: 'root', href: `${this.endpoint}/stac` })
      // child items
      arr[i].links.push({ rel: 'items', href: `${this.clink}/${a.id}/items` })
    })

    resp.collections = resp.results
    delete resp.results

    callback(err, resp)
  })
}

// Get a single collection by name
API.prototype.get_collection = function (collection, callback) {
  const params = this.params
  this.params = { 'id': collection }
  this.search_collections((err, resp) => {
    this.params = params
    if (resp.collections.length === 1) {
      callback(err, resp.collections[0])
    } else {
      callback(err, {})
    }
  })
}

// Search items (searching both collections and items)
API.prototype.search_items = function (page = 1, limit = 1, callback) {
  // check collection first
  this.search_collections((err, resp) => {
    const collections = resp.collections.map((c) => c.id)
    if (collections.length === 0) {
      const _resp = {
        type: 'FeatureCollection',
        meta: {
          found: 0, returned: 0, limit: limit, page: page
        },
        features: []
      }
      callback(null, _resp)
    } else {
      // shallow copy of this.params
      const params = { ...this.params }
      this.params.collection = collections.join(',')

      this.backend.search(this.params, 'items', page, limit, (err, response) => {
        response.results.forEach((a, i, arr) => {
          // self link
          arr[i].links.splice(0, 0, {
            rel: 'self',
            href: `${this.clink}/${a.properties.collection}/item/${a.id}`
          })
          // parent link
          arr[i].links.push({ rel: 'parent', href: `${this.clink}/${a.properties.collection}` })
          arr[i].links.push({ rel: 'collection', href: `${this.clink}/${a.properties.collection}` })
          arr[i].links.push({ rel: 'root', href: `${this.endpoint}/stac` })
          arr[i]['type'] = 'Feature'
        })
        response.type = 'FeatureCollection'
        response.features = response.results
        delete response.results
        // add next link if not last page
        if ((page * limit) < response.meta.found) {
          params.page = page + 1
          params.limit = limit
          response.links = [{
            rel: 'next',
            title: 'Next page of results',
            href: `${this.endpoint}/stac/search?` + dictToURI(params)
          }]
        }
        callback(null, resp)
      })
    }
  })
}

API.prototype.get_item = function (id, callback) {
  this.backend.search({ id }, 'items', 1, 1, (err, resp) => {
    if (resp.results.length === 1) {
      const item = resp.results[0]
      // self link
      item.links.splice(0, 0, {
        rel: 'self',
        href: `${this.clink}/${item.properties.collection}/item/${item.id}`
      })
      // parent link
      item.links.push({ rel: 'parent', href: `${this.clink}/${item.properties.collection}` })
      item.links.push({ rel: 'collection', href: `${this.clink}/${item.properties.collection}` })
      item.links.push({ rel: 'root', href: `${this.endpoint}/stac` })
      item.type = 'Feature'
      callback(err, item)
    } else {
      callback(err, {})
    }
  })
}

// h/t https://medium.com/@mattccrampton/convert-a-javascript-dictionary-to-get-url-parameters-b77da8c78ec8
function dictToURI(dict) {
  return dict.map((p) => `${encodeURIComponent(p)}=${encodeURIComponent(dict[p])}`).join('&')
}

function STAC(path, endpoint, query, backend, respond = () => {}) {
  // default page and limit
  const _query = Object.assign({}, query)
  const page = parseInt(_query.page) || 1
  const limit = parseInt(_query.limit) || 1
  delete _query.page
  delete _query.limit

  console.log(`Query page=${page}, limit=${limit}`)

  // split and remove empty strings
  const resources = path.split('/').filter((x) => x)
  console.log('resources', resources)

  // make sure this is a STAC endpoint
  if (resources[0] !== 'stac') {
    const msg = 'endpoint not defined (use /stac)'
    console.log(msg, resources)
    respond(null, msg)
    return
  }

  let msg

  // /stac
  if (resources.length === 1) {
    const catalog = {
      id: 'sat-api',
      description: 'A STAC API of public datasets',
      'satapi:version': stac_version,
      stac_version: stac_version,
      links: [
        { rel: 'self', href: `${endpoint}/stac` }
      ]
    }
    const api = new API(backend, _query, endpoint)
    api.search_collections((err, results) => {
      if (err) respond(err)
      results.collections.forEach((c) => {
        catalog.links.push({ rel: 'child', href: `${endpoint}/stac/collections/${c.id}` })
      })
      respond(null, catalog)
    })
  } else {
    // drop the /stac prefix
    resources.splice(0, 1)
    // STAC endpoints
    switch (resources[0]) {
    case 'api':
      msg = 'TODO - return API doc'
      console.log(msg, resources)
      respond(null, msg)
      break
    // collections endpoint
    case 'collections':
      if (resources.length === 1) {
        // all collections
        const api = new API(backend, _query, endpoint)
        api.search_collections(respond)
      } else if (resources.length === 2) {
        // specific collection
        const api = new API(backend, _query, endpoint)
        api.get_collection(resources[1], respond)
      } else if (resources[2] === 'items') {
        console.log('search items in this collection')
        // this is a search across items in this collection
        _query.collection = resources[1]
        const api = new API(backend, _query, endpoint)
        api.search_items(page, limit, respond)
      } else if (resources[2] === 'item' && resources.length === 4) {
        // Get specific item in collection
        const api = new API(backend, _query, endpoint)
        api.get_item(resources[3], respond)
      } else {
        msg = 'endpoint not defined'
        console.log(msg, resources)
        respond(null, msg)
      }
      break
    case 'search': {
      // items api
      const api = new API(backend, _query, endpoint)
      api.search_items(page, limit, respond)
      break
    }
    default:
      respond(null, 'endpoint not defined')
    }
  }
}

module.exports.stac_version = stac_version
module.exports.STAC = STAC
<|endoftext|>


<commit_before>var countbutton = document.getElementById('wordcount_button');
var topwordsbutton = document.getElementById('topwords_button');
var topcharactersbutton = document.getElementById('topcharacters_button');

var input_area = document.getElementById('words_textarea');

countbutton.onclick = function() {
  wordCount();
  input_area.onkeydown = function() {
    wordCount()
  }
};

topwordsbutton.onclick = function() {
  topWords();
  input_area.onkeydown = function() {
    topWords()
  }
};

topcharactersbutton.onclick = function() {
  topcharacters();
  input_area.onkeydown = function() {
    topcharacters()
  }
};

function wordCount() {

  document.getElementById('all_text').innerHTML = '';

  var words = document.getElementById("words_textarea").value.trim().split(' ');

  var para = document.createElement("p");

  if (words.length > 1) {
    var count = document.createTextNode('Your document is ' + words.length + ' words long.');
  } else if (words.length = 1) {
    var count = document.createTextNode('Your document is ' + words.length + ' word long.');
  } else if (words[0] === "") {
    var count = document.createTextNode('Your document is 0 words long.');
  }

  para.appendChild(count);

  var element = document.getElementById("all_text");
  element.appendChild(para);
}

function topWords() {

  document.getElementById('all_text').innerHTML = '';

  var words = document.getElementById("words_textarea").value.trim().split(' ');

  var counts = [];

  for (i = 0; i <= words.length - 1; i++) {
    var found = false;
    var current_word = words[i].toLowerCase();

    for (n = 0; n <= counts.length - 1; n++) {
      if (counts[n][0] == current_word) {
        counts[n][1] += 1;
        found = true;
        break;
      }
    }

    if (found == false) {
      counts.push([current_word, 1]);
    }
  }

  var sorted = counts.sort(function(a, b) {
    return b[1] - a[1]
  });

  function createTable() {
    var element = document.getElementById("all_text");

    var tbl = document.createElement('table');

    tbl.style.width = '100%';

    tbl.setAttribute('border', '1');

    var tbdy = document.createElement('tbody');

    var tr = document.createElement('tr');
    var word = document.createElement('td');
    word.innerHTML = "Word"
    var countword = document.createElement('td');
    countword.innerHTML = "Count"
    var suggestions = document.createElement('td');
    suggestions.innerHTML = "Suggestions"
    tr.appendChild(word)
    tr.appendChild(countword)
    tr.appendChild(suggestions)
    tbdy.appendChild(tr);
    tbl.appendChild(tbdy);
    element.appendChild(tbl)

    for (i = 0; i <= counts.length - 1; i++) {
      var tr = document.createElement('tr');
      var word = document.createElement('td');
      word.innerHTML = counts[i][0]
      var countword = document.createElement('td');
      countword.innerHTML = counts[i][1]
      var suggestion = document.createElement('td');

      if (counts[i][1] >= 3) {
        $.ajax({
          type: 'GET',
          url: 'http://words.bighugelabs.com/api/2/dafe2e8acd88d00e5096b17ca16157a7/' + counts[i][0] + '/json?callback=mycallback',
          dataType: 'jsonp',
          crossDomain: true,
          success: function(data) {

            if (typeof data.noun != "undefined") {
              if (typeof data.noun.syn != "undefined" && typeof data.noun.sim != "undefined") {
                suggestion.innerHTML = "noun: synonyms " + data.noun.syn.slice(0, 3) + " similar " + data.noun.sim.slice(0, 3)
              } else if (typeof data.noun.syn != "undefined" && typeof data.noun.sim === "undefined") {
                suggestion.innerHTML = "noun: synonyms " + data.noun.syn.slice(0, 3)
              } else if (typeof data.noun.syn === "undefined" && typeof data.noun.sim != "undefined") {
                suggestion.innerHTML = "noun: similar " + data.noun.sim.slice(0, 3)
              }
            }

            if (typeof data.verb != "undefined") {
              if (typeof data.verb.syn != "undefined" && typeof data.verb.sim != "undefined") {
                suggestion.innerHTML = "verb: synonyms " + data.verb.syn.slice(0, 3) + " similar " + data.verb.sim.slice(0, 3)
              } else if (typeof data.verb.syn != "undefined" && typeof data.verb.sim === "undefined") {
                suggestion.innerHTML = "verb: synonyms " + data.verb.syn.slice(0, 3)
              } else if (typeof data.verb.syn === "undefined" && typeof data.verb.sim != "undefined") {
                suggestion.innerHTML = "verb: similar " + data.verb.sim.slice(0, 3)
              }
            }

            if (typeof data.adverb != "undefined") {
              if (typeof data.adverb.syn != "undefined" && typeof data.adverb.sim != "undefined") {
                suggestion.innerHTML = "adverb: synonyms " + data.adverb.syn.slice(0, 3) + " similar " + data.adverb.sim.slice(0, 3)
              } else if (typeof data.adverb.syn != "undefined" && typeof data.adverb.sim === "undefined") {
                suggestion.innerHTML = "adverb: synonyms " + data.adverb.syn.slice(0, 3)
              } else if (typeof data.adverb.syn === "undefined" && typeof data.adverb.sim != "undefined") {
                suggestion.innerHTML = "adverb: similar " + data.adverb.sim.slice(0, 3)
              }
            }

            if (typeof data.adjective != "undefined") {
              if (typeof data.adjective.syn != "undefined" && typeof data.adjective.sim != "undefined") {
                suggestion.innerHTML = "adjective: synonyms " + data.adjective.syn.slice(0, 3) + " similar " + data.adjective.sim.slice(0, 3)
              } else if (typeof data.adjective.syn != "undefined" && typeof data.adjective.sim === "undefined") {
                suggestion.innerHTML = "adjective: synonyms " + data.adjective.syn.slice(0, 3)
              } else if (typeof data.adjective.syn === "undefined" && typeof data.adjective.sim != "undefined") {
                suggestion.innerHTML = "adjective: similar " + data.adjective.sim.slice(0, 3)
              }
            }
          }
        });
      }
      tr.appendChild(word)
      tr.appendChild(countword)
      tr.appendChild(suggestion)
      tbdy.appendChild(tr)
    }
    tbl.appendChild(tbdy)
    element.appendChild(tbl)
  }
  createTable()
};

function topcharacters() {
  document.getElementById('all_text').innerHTML = '';

  var characters = document.getElementById("words_textarea").value.trim().split('');

  var counts = [];

  for (i = 0; i <= characters.length - 1; i++) {
    var found = false;
    var current_letter = characters[i].toLowerCase();

    for (n = 0; n <= counts.length - 1; n++) {
      if (counts[n][0] == current_letter) {
        counts[n][1] += 1;
        found = true;
        break;
      }
    }

    if (found == false) {
      counts.push([current_letter, 1]);
    }
  }

  var sorted = counts.sort(function(a, b) {
    return b[1] - a[1]
  });

  function createTable() {
    var element = document.getElementById("all_text");

    var tbl = document.createElement('table');

    tbl.style.width = '100%';

    tbl.setAttribute('border', '1');

    var tbdy = document.createElement('tbody');

    var tr = document.createElement('tr');
    var word = document.createElement('td');
    word.innerHTML = "Character"
    var countword = document.createElement('td');
    countword.innerHTML = "Count"
    tr.appendChild(word)
    tr.appendChild(countword)
    tbdy.appendChild(tr);
    tbl.appendChild(tbdy);
    element.appendChild(tbl)

    for (i = 0; i <= counts.length - 1; i++) {
      var tr = document.createElement('tr');
      var word = document.createElement('td');
      word.innerHTML = counts[i][0]
      var countword = document.createElement('td');
      countword.innerHTML = counts[i][1]
      tr.appendChild(word)
      tr.appendChild(countword)
      tbdy.appendChild(tr);
    }
    tbl.appendChild(tbdy);
    element.appendChild(tbl)
  }
  createTable()
}
<commit_msg>fixed so innerHTML for words arent deleted, now all suggestions are being put into a single words suggestion table box<commit_after>var countbutton = document.getElementById('wordcount_button');
var topwordsbutton = document.getElementById('topwords_button');
var topcharactersbutton = document.getElementById('topcharacters_button');

var input_area = document.getElementById('words_textarea');

countbutton.onclick = function() {
  wordCount();
  input_area.onkeydown = function() {
    wordCount()
  }
};

topwordsbutton.onclick = function() {
  topWords();
  input_area.onkeydown = function() {
    topWords()
  }
};

topcharactersbutton.onclick = function() {
  topcharacters();
  input_area.onkeydown = function() {
    topcharacters()
  }
};

function wordCount() {

  document.getElementById('all_text').innerHTML = '';

  var words = document.getElementById("words_textarea").value.trim().split(' ');

  var para = document.createElement("p");

  if (words.length > 1) {
    var count = document.createTextNode('Your document is ' + words.length + ' words long.');
  } else if (words.length = 1) {
    var count = document.createTextNode('Your document is ' + words.length + ' word long.');
  } else if (words[0] === "") {
    var count = document.createTextNode('Your document is 0 words long.');
  }

  para.appendChild(count);

  var element = document.getElementById("all_text");
  element.appendChild(para);
}

function topWords() {

  document.getElementById('all_text').innerHTML = '';

  var words = document.getElementById("words_textarea").value.trim().split(' ');

  var counts = [];

  for (i = 0; i <= words.length - 1; i++) {
    var found = false;
    var current_word = words[i].toLowerCase();

    for (n = 0; n <= counts.length - 1; n++) {
      if (counts[n][0] == current_word) {
        counts[n][1] += 1;
        found = true;
        break;
      }
    }

    if (found == false) {
      counts.push([current_word, 1]);
    }
  }

  var sorted = counts.sort(function(a, b) {
    return b[1] - a[1]
  });

  function createTable() {
    var element = document.getElementById("all_text");

    var tbl = document.createElement('table');

    tbl.style.width = '100%';

    tbl.setAttribute('border', '1');

    var tbdy = document.createElement('tbody');

    var tr = document.createElement('tr');
    var word = document.createElement('td');
    word.innerHTML = "Word"
    var countword = document.createElement('td');
    countword.innerHTML = "Count"
    var suggestions = document.createElement('td');
    suggestions.innerHTML = "Suggestions"
    tr.appendChild(word)
    tr.appendChild(countword)
    tr.appendChild(suggestions)
    tbdy.appendChild(tr);
    tbl.appendChild(tbdy);
    element.appendChild(tbl)

    for (i = 0; i <= counts.length - 1; i++) {
      var tr = document.createElement('tr');
      var word = document.createElement('td');
      word.innerHTML = counts[i][0]
      var countword = document.createElement('td');
      countword.innerHTML = counts[i][1]
      var suggestion = document.createElement('td');

      if (counts[i][1] >= 3) {
        $.ajax({
          type: 'GET',
          url: 'http://words.bighugelabs.com/api/2/dafe2e8acd88d00e5096b17ca16157a7/' + counts[i][0] + '/json?callback=mycallback',
          dataType: 'jsonp',
          crossDomain: true,
          success: function(data) {

            if (typeof data.noun != "undefined") {
              if (typeof data.noun.syn != "undefined" && typeof data.noun.sim != "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "noun: synonyms " + data.noun.syn.slice(0, 3) + " similar " + data.noun.sim.slice(0, 3) + ' '
              } else if (typeof data.noun.syn != "undefined" && typeof data.noun.sim === "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "noun: synonyms " + data.noun.syn.slice(0, 3) + ' '
              } else if (typeof data.noun.syn === "undefined" && typeof data.noun.sim != "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "noun: similar " + data.noun.sim.slice(0, 3) + ' '
              }
            }

            if (typeof data.verb != "undefined") {
              if (typeof data.verb.syn != "undefined" && typeof data.verb.sim != "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "verb: synonyms " + data.verb.syn.slice(0, 3) + " similar " + data.verb.sim.slice(0, 3) + ' '
              } else if (typeof data.verb.syn != "undefined" && typeof data.verb.sim === "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "verb: synonyms " + data.verb.syn.slice(0, 3) + ' '
              } else if (typeof data.verb.syn === "undefined" && typeof data.verb.sim != "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "verb: similar " + data.verb.sim.slice(0, 3) + ' '
              }
            }

            if (typeof data.adverb != "undefined") {
              if (typeof data.adverb.syn != "undefined" && typeof data.adverb.sim != "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "adverb: synonyms " + data.adverb.syn.slice(0, 3) + " similar " + data.adverb.sim.slice(0, 3) + ' '
              } else if (typeof data.adverb.syn != "undefined" && typeof data.adverb.sim === "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "adverb: synonyms " + data.adverb.syn.slice(0, 3) + ' '
              } else if (typeof data.adverb.syn === "undefined" && typeof data.adverb.sim != "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "adverb: similar " + data.adverb.sim.slice(0, 3) + ' '
              }
            }

            if (typeof data.adjective != "undefined") {
              if (typeof data.adjective.syn != "undefined" && typeof data.adjective.sim != "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "adjective: synonyms " + data.adjective.syn.slice(0, 3) + " similar " + data.adjective.sim.slice(0, 3) + ' '
              } else if (typeof data.adjective.syn != "undefined" && typeof data.adjective.sim === "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "adjective: synonyms " + data.adjective.syn.slice(0, 3) + ' '
              } else if (typeof data.adjective.syn === "undefined" && typeof data.adjective.sim != "undefined") {
                suggestion.innerHTML = suggestion.innerHTML + "adjective: similar " + data.adjective.sim.slice(0, 3) + ' '
              }
            }
          }
        });
      }
      tr.appendChild(word)
      tr.appendChild(countword)
      tr.appendChild(suggestion)
      tbdy.appendChild(tr)
    }
    tbl.appendChild(tbdy)
    element.appendChild(tbl)
  }
  createTable()
};

function topcharacters() {
  document.getElementById('all_text').innerHTML = '';

  var characters = document.getElementById("words_textarea").value.trim().split('');

  var counts = [];

  for (i = 0; i <= characters.length - 1; i++) {
    var found = false;
    var current_letter = characters[i].toLowerCase();

    for (n = 0; n <= counts.length - 1; n++) {
      if (counts[n][0] == current_letter) {
        counts[n][1] += 1;
        found = true;
        break;
      }
    }

    if (found == false) {
      counts.push([current_letter, 1]);
    }
  }

  var sorted = counts.sort(function(a, b) {
    return b[1] - a[1]
  });

  function createTable() {
    var element = document.getElementById("all_text");

    var tbl = document.createElement('table');

    tbl.style.width = '100%';

    tbl.setAttribute('border', '1');

    var tbdy = document.createElement('tbody');

    var tr = document.createElement('tr');
    var word = document.createElement('td');
    word.innerHTML = "Character"
    var countword = document.createElement('td');
    countword.innerHTML = "Count"
    tr.appendChild(word)
    tr.appendChild(countword)
    tbdy.appendChild(tr);
    tbl.appendChild(tbdy);
    element.appendChild(tbl)

    for (i = 0; i <= counts.length - 1; i++) {
      var tr = document.createElement('tr');
      var word = document.createElement('td');
      word.innerHTML = counts[i][0]
      var countword = document.createElement('td');
      countword.innerHTML = counts[i][1]
      tr.appendChild(word)
      tr.appendChild(countword)
      tbdy.appendChild(tr);
    }
    tbl.appendChild(tbdy);
    element.appendChild(tbl)
  }
  createTable()
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";

/**
 * Problem
 * ========
 * The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.
 * 73167176531330624919225119674426574742355349194934
 * 96983520312774506326239578318016984801869478851843
 * 85861560789112949495459501737958331952853208805511
 * 12540698747158523863050715693290963295227443043557
 * 66896648950445244523161731856403098711121722383113
 * 62229893423380308135336276614282806444486645238749
 * 30358907296290491560440772390713810515859307960866
 * 70172427121883998797908792274921901699720888093776
 * 65727333001053367881220235421809751254540594752243
 * 52584907711670556013604839586446706324415722155397
 * 53697817977846174064955149290862569321978468622482
 * 83972241375657056057490261407972968652414535100474
 * 82166370484403199890008895243450658541227588666881
 * 16427171479924442928230863465674813919123162824586
 * 17866458359124566529476545682848912883142607690042
 * 24219022671055626321111109370544217506941658960408
 * 07198403850962455444362981230987879927244284909188
 * 84580156166097919133875499200524063689912560717606
 * 05886116467109405077541002256983155200055935729725
 * 71636269561882670428252483600823257530420752963450
 *
 * Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?
 *
 * Latest Run Stats
 * ====== === =====
 * real    0m0.098s
 * user    0m0.070s
 * sys     0m0.025s
 *
 */
var consLen = 13,
    maxProd = -1,
    numberString = '73167176531330624919225119674426574742355349194934\
96983520312774506326239578318016984801869478851843\
85861560789112949495459501737958331952853208805511\
12540698747158523863050715693290963295227443043557\
66896648950445244523161731856403098711121722383113\
62229893423380308135336276614282806444486645238749\
30358907296290491560440772390713810515859307960866\
70172427121883998797908792274921901699720888093776\
65727333001053367881220235421809751254540594752243\
52584907711670556013604839586446706324415722155397\
53697817977846174064955149290862569321978468622482\
83972241375657056057490261407972968652414535100474\
82166370484403199890008895243450658541227588666881\
16427171479924442928230863465674813919123162824586\
17866458359124566529476545682848912883142607690042\
24219022671055626321111109370544217506941658960408\
07198403850962455444362981230987879927244284909188\
84580156166097919133875499200524063689912560717606\
05886116467109405077541002256983155200055935729725\
71636269561882670428252483600823257530420752963450';

var digitArr = numberString.split('');

//create and initialize a helper array
var helperArr = new Array(digitArr.length-consLen);
for(var i=0; i<helperArr.length; i++){
    helperArr[i] = i;
}

helperArr.map(function(idx){
    var prod = 1;
    var endIdx = idx+consLen;
    for(var idx; idx<endIdx; idx++){
        prod*=digitArr[idx];
    }
    if(prod>maxProd){ maxProd = prod; }
});

console.log(maxProd); //should be the only print statement
<commit_msg>Add comments<commit_after>#!/usr/bin/env node
"use strict";

/**
 * Problem
 * ========
 * The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.
 * 73167176531330624919225119674426574742355349194934
 * 96983520312774506326239578318016984801869478851843
 * 85861560789112949495459501737958331952853208805511
 * 12540698747158523863050715693290963295227443043557
 * 66896648950445244523161731856403098711121722383113
 * 62229893423380308135336276614282806444486645238749
 * 30358907296290491560440772390713810515859307960866
 * 70172427121883998797908792274921901699720888093776
 * 65727333001053367881220235421809751254540594752243
 * 52584907711670556013604839586446706324415722155397
 * 53697817977846174064955149290862569321978468622482
 * 83972241375657056057490261407972968652414535100474
 * 82166370484403199890008895243450658541227588666881
 * 16427171479924442928230863465674813919123162824586
 * 17866458359124566529476545682848912883142607690042
 * 24219022671055626321111109370544217506941658960408
 * 07198403850962455444362981230987879927244284909188
 * 84580156166097919133875499200524063689912560717606
 * 05886116467109405077541002256983155200055935729725
 * 71636269561882670428252483600823257530420752963450
 *
 * Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?
 *
 * Latest Run Stats
 * ====== === =====
 * real    0m0.098s
 * user    0m0.070s
 * sys     0m0.025s
 *
 */
var consLen = 13,
    maxProd = -1,
    numberString = '73167176531330624919225119674426574742355349194934\
96983520312774506326239578318016984801869478851843\
85861560789112949495459501737958331952853208805511\
12540698747158523863050715693290963295227443043557\
66896648950445244523161731856403098711121722383113\
62229893423380308135336276614282806444486645238749\
30358907296290491560440772390713810515859307960866\
70172427121883998797908792274921901699720888093776\
65727333001053367881220235421809751254540594752243\
52584907711670556013604839586446706324415722155397\
53697817977846174064955149290862569321978468622482\
83972241375657056057490261407972968652414535100474\
82166370484403199890008895243450658541227588666881\
16427171479924442928230863465674813919123162824586\
17866458359124566529476545682848912883142607690042\
24219022671055626321111109370544217506941658960408\
07198403850962455444362981230987879927244284909188\
84580156166097919133875499200524063689912560717606\
05886116467109405077541002256983155200055935729725\
71636269561882670428252483600823257530420752963450';

var digitArr = numberString.split('');

//create and initialize a helper array
var helperArr = new Array(digitArr.length-consLen);
for(var i=0; i<helperArr.length; i++){
    helperArr[i] = i;
}

//use the helper indicies to calculate the products
helperArr.map(function(idx){
    var prod = 1;
    var endIdx = idx+consLen;
    for(var idx; idx<endIdx; idx++){
        prod*=digitArr[idx];
    }
    if(prod>maxProd){ maxProd = prod; }
});

console.log(maxProd); //should be the only print statement
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 only. with the special
 * exception on linking described in file LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 */

// global variables

var cls = getQuerystring('c');
var rel = getQuerystring('r');

function qualifier(q)
{
	if (q == 'DynamicRO' || q == 'StaticRO')
		return 'read-only';
	else
		return 'read/write';
}

function transform_type(t)
{
	switch (t) {
	case "String":
	case "Int":
	case "Float":
	case "Bool":
	case "DateTime":
		return t.toLowerCase();
	}

	switch (t[0]) {
	case "Ref":
		return '' + t[1] + ' ref';
	case "Record":
		return t[1] + ' record';
	case "Enum":
		return t[1];
	case "Set":
		return transform_type(t[1]) + ' set';
	case "Map":
		return '(' + transform_type(t[1]) + ' \u2192 ' + transform_type(t[2]) + ') map';
	}
	return 'Unknown[' + t + ']';
}

function transform_default(t)
{
	switch (t[0]) {
	case "VString":
		return '"' + t[1] + '"';
	case "VInt":
	case "VFloat":
	case "VBool":
	case "VDateTime":
	case "VEnum":
		return t[1];
	case "VRef":
		return (t[1] == "" ? "Null" : t[1]);
	case "VRecord":
		return t[1] + ' record';
		return t[1];
	case "VSet":
		return '{' + t[1].map(function(v){return transform_default(v)}) + '}';
	case "VMap":
		return '{' + t[1].map(function(v){return transform_default(v[0]) + ' \u2192 ' + transform_default(v[1])}) + '}';
	}
	return 'Unknown[' + t + ']';
}

function current_lifecycle_stage(s)
{
	if (s.length == 0)
		return 'Prototype';
	else {
		last_transition = s[s.length-1][0];
		switch (last_transition) {
		case 'Deprecated':
			return 'Deprecated';
			break;
		case 'Removed':
			return 'Removed';
			break;
		case 'Published':
		case 'Changed':
		case 'Extended':
		default:
			return '';
			break;
		}
	}
}

function make_field(fld, n)
{
	name = fld.field_name;

	html = "";
	html = '
';
	html += '<input type="button" class="small-button" value="details" onclick="showhide(document.getElementById(\'' + name + '_details\'))" />';
	html += '
' + current_lifecycle_stage(fld.lifecycle) + '
';
	html += '
' + transform_type(fld.ty) + ' ' + name + ' [' + qualifier(fld.qualifier) + ']
';

	html += '
';
	html += '
' + fld.field_description + '
';

	html += '
';
	if (fld.default_value != undefined)
		html += '
Default value:	' + transform_default(fld.default_value) + '
';
	html += '
';

	html += '
';
	for (i in fld.lifecycle) {
		l = fld.lifecycle[i];
		html += '
' + l[0] + ' in:	' + l[1] + '	' + l[2] + '
';
	}
	html += '
';
	html += '

';

	return html;
}

function make_message(msg, n)
{
	name = msg.msg_name;

	html = "";

	html += '
';
	html += '<input type="button" class="small-button" value="details" onclick="showhide(document.getElementById(\'' + name + '_details\'))" />';
	html += '
' + current_lifecycle_stage(msg.msg_lifecycle) + '
';
	html += '
' +
		(msg.msg_result != undefined ? transform_type(msg.msg_result[0]) : 'void') +
		' ' + name + ' (' +
		msg.msg_params.map(function(p){return transform_type(p.param_type)}).join(', ') +
		')
';

	html += '
' + msg.msg_doc + '
';

	html += '
';
	html += '
';

	html += '
Parameters:	';
	html += '
';
	for (i in msg.msg_params) {
		p = msg.msg_params[i];
		html += '
' + transform_type(p.param_type) + '  ' + p.param_name + '	';
		html += '' + p.param_doc + '
';
	}
	html += '

';

	html += '
Minimum role:	' + msg.msg_allowed_roles[msg.msg_allowed_roles.length - 1] + '
';
	if (msg.msg_result != undefined)
		html += '
Result:	' + msg.msg_result[1] + '
';
	if (msg.msg_errors != undefined && msg.msg_errors.length > 0) {
		html += '
Errors:	'
		html += '
';
		for (i in msg.msg_errors) {
			e = msg.msg_errors[i];
			html += '
' + e.err_name + '	';
			html += '' + e.err_doc + '
';
		}
		html += '

';
	}
	html += '
';

	html += '
';
	for (i in msg.msg_lifecycle) {
		l = msg.msg_lifecycle[i];
		html += '
' + l[0] + ' in:	' + l[1] + '	' + l[2] + '
';
	}
	html += '
';

	html += '

';

	return html;
}

function class_doc()
{
	contents = clsdoc.contents;
	fields = contents.filter(function(f){return f[0] == "Field";}).map(function(f){return f[1];});
	fields.sort(function(a, b){return a.field_name.toLowerCase().charCodeAt(0) - b.field_name.toLowerCase().charCodeAt(0);});
	messages = clsdoc.messages;
	messages = messages.filter(function(m){return m.msg_hide_from_docs == false;})
	messages.sort(function(a, b){return a.msg_name.toLowerCase().charCodeAt(0) - b.msg_name.toLowerCase().charCodeAt(0)});

	html = "";
	html += '<input type="button" class="small-button" value="details" onclick="showhide(document.getElementById(\'class_details\'))" />';
	html += '
' + current_lifecycle_stage(clsdoc.obj_lifecycle) + '
';
	html += '
Class: ' + cls + '
\n';

	html += '
' + clsdoc.description + '
';

	html += '
';
	html += '
';
	for (i in clsdoc.obj_lifecycle) {
		l = clsdoc.obj_lifecycle[i];
		html += '
' + l[0] + ' in:	' + l[1] + '	' + l[2] + '
';
	}
	html += '
';
	html += '
';

	html += '
Fields
';
	if (fields.length > 0) {
		for (i in fields)
			html += make_field(fields[i], i);
	}
	else
		html += '
None.
';

	html += '
Messages
';
	if (messages.length > 0) {
		for (i in messages)
			html += make_message(messages[i], i);
	}
	else
		html += '
None.
';

	set_content(html);
}

function compare_release_notes(a, b)
{
	function change_to_num(x) {
		if (x.indexOf('Published') > -1) return '0';
		else if (x.indexOf('Extended') > -1) return '1';
		else if (x.indexOf('Changed') > -1) return '2';
		else if (x.indexOf('Deprecated') > -1) return '3';
		else if (x.indexOf('Removed') > -1) return '4';
		else return '5';
	}
	function element_to_num(x) {
		if (x.indexOf('object') > -1) return '0';
		else if (x.indexOf('field') > -1) return '1';
		else if (x.indexOf('message') > -1) return '2';
		else return '3';
	}
	a = change_to_num(a[0]) + element_to_num(a[0]) + (a[1]+a[2]).toLowerCase();
	b = change_to_num(b[0]) + element_to_num(b[0]) + (b[1]+b[2]).toLowerCase();
	return a > b;
}

function release_doc()
{
	changes = [];

	for (i in release_info) {
		c = release_info[i];
		for (j in c.obj_changes)
			changes.push([c.obj_changes[j][0] + ' object', c.cls, '', c.obj_changes[j][2]]);
		for (j in c.field_changes)
			changes.push([c.field_changes[j][0] + ' field', c.cls, c.field_changes[j][1], c.field_changes[j][2]]);
		for (j in c.msg_changes)
			changes.push([c.msg_changes[j][0] + ' message', c.cls, c.msg_changes[j][1], c.msg_changes[j][2]]);
	}

	changes.sort(compare_release_notes);

	html = "";
	html += '
Release notes: ' + rel + '
\n';

	html += '

Change	Element	Description
';

	for (i in changes) {
		html += '
' + changes[i][0] + '	' +
			changes[i][1] + (changes[i][2] != '' ? '.' + changes[i][2] : '') + '	' + changes[i][3] + '
';
	}

	html += '
';

	set_content(html);
}

function class_list()
{
	html = '
Classes
';

	classes.sort(function(a, b){return a.toLowerCase().charCodeAt(0) - b.toLowerCase().charCodeAt(0)});
	for (i in classes) {
		c = classes[i];
		html += '' + c + '
';
	}

	append_sidebar(html);
}

function release_list()
{
	html = '
Release notes
';

	for (i in releases) {
		r = releases[i];
		html += '' + r + '
';
	}

	append_sidebar(html);
}

function build()
{
	if (cls != "") {
		class_list();
		release_list();
		class_doc();
	}
	else if (rel != "") {
		class_list();
		release_list();
		release_doc();
	}
	else {
		class_list();
		release_list();
	}
}

<commit_msg>API doc: add hook to translate release code names to something sensible<commit_after>/*
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 only. with the special
 * exception on linking described in file LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 */

// global variables

var cls = getQuerystring('c');
var rel = getQuerystring('r');

function qualifier(q)
{
	if (q == 'DynamicRO' || q == 'StaticRO')
		return 'read-only';
	else
		return 'read/write';
}

function transform_type(t)
{
	switch (t) {
	case "String":
	case "Int":
	case "Float":
	case "Bool":
	case "DateTime":
		return t.toLowerCase();
	}

	switch (t[0]) {
	case "Ref":
		return '' + t[1] + ' ref';
	case "Record":
		return t[1] + ' record';
	case "Enum":
		return t[1];
	case "Set":
		return transform_type(t[1]) + ' set';
	case "Map":
		return '(' + transform_type(t[1]) + ' \u2192 ' + transform_type(t[2]) + ') map';
	}
	return 'Unknown[' + t + ']';
}

function transform_default(t)
{
	switch (t[0]) {
	case "VString":
		return '"' + t[1] + '"';
	case "VInt":
	case "VFloat":
	case "VBool":
	case "VDateTime":
	case "VEnum":
		return t[1];
	case "VRef":
		return (t[1] == "" ? "Null" : t[1]);
	case "VRecord":
		return t[1] + ' record';
		return t[1];
	case "VSet":
		return '{' + t[1].map(function(v){return transform_default(v)}) + '}';
	case "VMap":
		return '{' + t[1].map(function(v){return transform_default(v[0]) + ' \u2192 ' + transform_default(v[1])}) + '}';
	}
	return 'Unknown[' + t + ']';
}

function current_lifecycle_stage(s)
{
	if (s.length == 0)
		return 'Prototype';
	else {
		last_transition = s[s.length-1][0];
		switch (last_transition) {
		case 'Deprecated':
			return 'Deprecated';
			break;
		case 'Removed':
			return 'Removed';
			break;
		case 'Published':
		case 'Changed':
		case 'Extended':
		default:
			return '';
			break;
		}
	}
}

function get_release_name(s)
{
	return s;
}

function make_field(fld, n)
{
	name = fld.field_name;

	html = "";
	html = '
';
	html += '<input type="button" class="small-button" value="details" onclick="showhide(document.getElementById(\'' + name + '_details\'))" />';
	html += '
' + current_lifecycle_stage(fld.lifecycle) + '
';
	html += '
' + transform_type(fld.ty) + ' ' + name + ' [' + qualifier(fld.qualifier) + ']
';

	html += '
';
	html += '
' + fld.field_description + '
';

	html += '
';
	if (fld.default_value != undefined)
		html += '
Default value:	' + transform_default(fld.default_value) + '
';
	html += '
';

	html += '
';
	for (i in fld.lifecycle) {
		l = fld.lifecycle[i];
		html += '
' + l[0] + ' in:	' + get_release_name(l[1]) + '	' + l[2] + '
';
	}
	html += '
';
	html += '

';

	return html;
}

function make_message(msg, n)
{
	name = msg.msg_name;

	html = "";

	html += '
';
	html += '<input type="button" class="small-button" value="details" onclick="showhide(document.getElementById(\'' + name + '_details\'))" />';
	html += '
' + current_lifecycle_stage(msg.msg_lifecycle) + '
';
	html += '
' +
		(msg.msg_result != undefined ? transform_type(msg.msg_result[0]) : 'void') +
		' ' + name + ' (' +
		msg.msg_params.map(function(p){return transform_type(p.param_type)}).join(', ') +
		')
';

	html += '
' + msg.msg_doc + '
';

	html += '
';
	html += '
';

	html += '
Parameters:	';
	html += '
';
	for (i in msg.msg_params) {
		p = msg.msg_params[i];
		html += '
' + transform_type(p.param_type) + '  ' + p.param_name + '	';
		html += '' + p.param_doc + '
';
	}
	html += '

';

	html += '
Minimum role:	' + msg.msg_allowed_roles[msg.msg_allowed_roles.length - 1] + '
';
	if (msg.msg_result != undefined)
		html += '
Result:	' + msg.msg_result[1] + '
';
	if (msg.msg_errors != undefined && msg.msg_errors.length > 0) {
		html += '
Errors:	'
		html += '
';
		for (i in msg.msg_errors) {
			e = msg.msg_errors[i];
			html += '
' + e.err_name + '	';
			html += '' + e.err_doc + '
';
		}
		html += '

';
	}
	html += '
';

	html += '
';
	for (i in msg.msg_lifecycle) {
		l = msg.msg_lifecycle[i];
		html += '
' + l[0] + ' in:	' + get_release_name(l[1]) + '	' + l[2] + '
';
	}
	html += '
';

	html += '

';

	return html;
}

function class_doc()
{
	contents = clsdoc.contents;
	fields = contents.filter(function(f){return f[0] == "Field";}).map(function(f){return f[1];});
	fields.sort(function(a, b){return a.field_name.toLowerCase().charCodeAt(0) - b.field_name.toLowerCase().charCodeAt(0);});
	messages = clsdoc.messages;
	messages = messages.filter(function(m){return m.msg_hide_from_docs == false;})
	messages.sort(function(a, b){return a.msg_name.toLowerCase().charCodeAt(0) - b.msg_name.toLowerCase().charCodeAt(0)});

	html = "";
	html += '<input type="button" class="small-button" value="details" onclick="showhide(document.getElementById(\'class_details\'))" />';
	html += '
' + current_lifecycle_stage(clsdoc.obj_lifecycle) + '
';
	html += '
Class: ' + cls + '
\n';

	html += '
' + clsdoc.description + '
';

	html += '
';
	html += '
';
	for (i in clsdoc.obj_lifecycle) {
		l = clsdoc.obj_lifecycle[i];
		html += '
' + l[0] + ' in:	' + get_release_name(l[1]) + '	' + l[2] + '
';
	}
	html += '
';
	html += '
';

	html += '
Fields
';
	if (fields.length > 0) {
		for (i in fields)
			html += make_field(fields[i], i);
	}
	else
		html += '
None.
';

	html += '
Messages
';
	if (messages.length > 0) {
		for (i in messages)
			html += make_message(messages[i], i);
	}
	else
		html += '
None.
';

	set_content(html);
}

function compare_release_notes(a, b)
{
	function change_to_num(x) {
		if (x.indexOf('Published') > -1) return '0';
		else if (x.indexOf('Extended') > -1) return '1';
		else if (x.indexOf('Changed') > -1) return '2';
		else if (x.indexOf('Deprecated') > -1) return '3';
		else if (x.indexOf('Removed') > -1) return '4';
		else return '5';
	}
	function element_to_num(x) {
		if (x.indexOf('class') > -1) return '0';
		else if (x.indexOf('field') > -1) return '1';
		else if (x.indexOf('message') > -1) return '2';
		else return '3';
	}
	a = change_to_num(a[0]) + element_to_num(a[0]) + (a[1]+a[2]).toLowerCase();
	b = change_to_num(b[0]) + element_to_num(b[0]) + (b[1]+b[2]).toLowerCase();
	return a > b;
}

function release_doc()
{
	changes = [];

	for (i in release_info) {
		c = release_info[i];
		for (j in c.obj_changes)
			changes.push([c.obj_changes[j][0] + ' class', c.cls, '', c.obj_changes[j][2]]);
		for (j in c.field_changes)
			changes.push([c.field_changes[j][0] + ' field', c.cls, c.field_changes[j][1], c.field_changes[j][2]]);
		for (j in c.msg_changes)
			changes.push([c.msg_changes[j][0] + ' message', c.cls, c.msg_changes[j][1], c.msg_changes[j][2]]);
	}

	changes.sort(compare_release_notes);

	html = "";
	html += '
Release notes: ' + get_release_name(rel) + '
\n';

	html += '

Change	Element	Description
';

	for (i in changes) {
		html += '
' + changes[i][0] + '	' +
			changes[i][1] + (changes[i][2] != '' ? '.' + changes[i][2] : '') + '	' + changes[i][3] + '
';
	}

	html += '
';

	set_content(html);
}

function class_list()
{
	html = '
Classes
';

	classes.sort(function(a, b){return a.toLowerCase().charCodeAt(0) - b.toLowerCase().charCodeAt(0)});
	for (i in classes) {
		c = classes[i];
		html += '' + c + '
';
	}

	append_sidebar(html);
}

function release_list()
{
	html = '
Release notes
';

	for (i in releases) {
		r = releases[i];
		html += '' + get_release_name(r) + '
';
	}

	append_sidebar(html);
}

function build()
{
	if (cls != "") {
		class_list();
		release_list();
		class_doc();
	}
	else if (rel != "") {
		class_list();
		release_list();
		release_doc();
	}
	else {
		class_list();
		release_list();
	}
}

<|endoftext|>