<commit_before>// This example demonstrates how to generate ExtJS models, stores, grids, comboboxes and forms from yesod-dsl JSON output
// requires jQuery and underscore
$(function() {
    // url to yesod-dsl JSON output
    $.get("resources/services.json").done(function(defs) {

        // fill in user interface texts here or customize translate-function below
        var strings = {
            'Search' : 'Search',
            'usergroupscombo.emptyText' : 'Filter by user group',
            'userlist.title' : 'Users',
            'userlist.paging.displayMsg' : 'Users {0} - {1} / {2}',
            'userlist.paging.emptyMsg' : 'No users',
            'grouplist.title' : 'userlist.title',
            'grouplist.paging.displayMsg' : 'userlist.paging.displayMsg',
            'grouplist.paging.emptyMsg' : 'userslist.paging.emptyMsg'
        };

        // customize generated ExtJS classes
        var config = {
            name: 'MyApp',
            urlBase: 'services/data',
            defaultTextFieldPlugins: ['clearbutton'], // http://www.eekboom.de/ClearButton.html
            defaultPageSize: 100,
            defaultStoreFilters: [
                {
                    field:'hideDeleted',
                    value:"true"
                }
            ],
            routes: {
                users : {
                    grids : [
                        {
                            widget: 'userlist',
                            fields: ['name'],
                            preload:true,
                            toolbar: [
                                {
                                    xtype:'usergroupscombo',
                                    filterField: 'userGroupId'
                                }
                            ]
                        },
                        {
                            // user grid without user group filter
                            widget: 'groupuserlist',
                            fields: ['name'],
                            searchField: false
                        }
                     ]
                }
            }
        };
        function createStore(storeCls) {
            var store = Ext.create(storeCls);
            config.defaultStoreFilters.forEach(function(cf) {
                store.addFilter(
                    new Ext.util.Filter({
                        id: cf.field,
                        property: cf.field,
                        value: cf.value,
                    }), false
                );
            });
            return store;
        }

        // customized ExtJS ComboBox to fetch a record by ID field (call configStore when value set)
        Ext.define(config.name + '.view.Combo',{
            extend: 'Ext.form.field.ComboBox',
            minChars : 1,
            typeAhead: true,
            store:'ext-empty-store',
            queryMode: 'remote',
            pageSize:10,
            valueField: 'id',
            displayField: 'name',
            plugins: config.defaultTextFieldPlugins || [],
            initComponent: function() {
                this.callParent(arguments);
                this.store = createStore(this.myStore);
            },
            configStore: function(extraFilters) {
                var value = this.getValue()
                this.store.addFilter(
                    new Ext.util.Filter({
                        id: 'id',
                        property: 'id',
                        value: ''+value
                    }), false
                );
                var combo = this;
                (function(c,v) {
                   c.store.load(function() {
                        c.setValue(v);
                        c.store.filters.removeAtKey('id');

                        if (c.getFilters) {
                            var filters = c.getFilters();
                            for (var i = 0; i < filters.length; i++) {
                                c.store.addFilter(filters[i], false);
                            }
                            if (extraFilters) {
                                for (var i = 0; i < extraFilters.length; i++) {
                                    c.store.addFilter(extraFilters[i], false);
                                }
                            }

                        }
                    });
                })(combo,value);
            }
        });

        function endsWith(str, suffix) {
            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }
        function translate(k,d) {
            if (k in strings) {
                while (k in strings) {
                    k = strings[k];
                }
                return k;
            } else if (d) {
                return d;
            } else {
                if (endsWith(k, ".search"))
                    return strings["Search"];
                return k;
            }
        };

        function idTooltip(record) {
            return "ID " + record.get('id');
        }

        defs.routes.forEach(function (r) {
            r.handlers.forEach(function (h) {

                var name = '', url = config.urlBase;
                r.path.forEach(function (pp) {
                    url += "/";
                    if (pp.type == "string") {
                        name += pp.value;
                        url += pp.value
                    } else {
                        name += pp.references;
                        url += '(ID)';
                    }
                });
                var modelName = config.name + '.model.' + name,
                    storeName = config.name + '.store.' + name,
                    comboName = config.name + '.view.' + name + '.Combo',
                    routeCfg = config.routes[name] || {};

                // create models and stores for GET handlers without parameters
                if (h.type == "GET" && r.path.length == 1 && r.path[0].type == "string") {

                    Ext.define(modelName, {
                        extend: 'Ext.data.Model',
                        fields: h.outputs
                    }, function (model) {
                        Ext.define(storeName, {
                            extend: 'Ext.data.Store',
                            model: modelName,
                            pageSize: config.defaultPageSize,
                            remoteFilter: true,
                            remoteSort: true,
                            proxy: {
                                type: 'rest',
                                url: url,
                                reader: {
                                    type: 'json',
                                    root: 'result',
                                    totalProperty: 'totalCount'
                                }
                            }
                        }, function(storeClass) {
                            var store = createStore(storeClass);

                            // ComboBox for entities with 'name' field
                            if (_.find(h.outputs, function (o) { return o.name == 'name'; })) {
                                Ext.define(comboName, {
                                    extend: config.name + '.view.Combo',
                                    alias: 'widget.' + name + 'combo',
                                    emptyText: translate(name + 'combo.emptyText'),
                                    myStore: storeName
                                });
                            }
                            // grids on demand by config
                            var grids = routeCfg['grids'] || [];
                            grids.forEach(function(gridCfg) {

                                var widgetName = gridCfg.widget || (name + 'list');
                                var listName  = config.name + '.view.' + name + '.' + widgetName;
                                if (gridCfg.preload) {
                                    Ext.onReady(function () { store.load() });
                                }
                                Ext.define(listName, {
                                    extend: 'Ext.grid.Panel',
                                    alias: 'widget.' + widgetName,
                                    multiSelect: true,
                                    title: translate(widgetName + ".title"),
                                    store: store,
                                    allowDeselect : true,
                                    requires: ['Ext.toolbar.Paging', 'Ext.ux.grid.FiltersFeature'],
                                    viewConfig: {
                                        listeners: {
                                            render: function(view) {
                                                var tooltip = gridCfg.tooltip || idTooltip;
                                                source.Utils.createToolTip(view, tooltip);
                                            }
                                        }
                                    },
                                    initComponent: function() {
                                        this.columns = _.filter(_.map(h.outputs, function(o) {

                                                                    var fields = gridCfg.fields,
                                                                        fieldCfg = gridCfg[o.name] || {};

                                                                    if (fields && fields.indexOf(o.name) == -1)
                                                                        return undefined;
                                                                    if (fieldCfg.hidden) {
                                                                        return undefined;
                                                                    } else {
                                                                        var defaultFlex = 10;
                                                                        if (o.name == 'id')
                                                                            defaultFlex = 1;
                                                                        return {
                                                                            "header" : translate(widgetName + "." + o.name + ".header", o.name),
                                                                            "dataIndex" : o.name,
                                                                            "flex" : fieldCfg.flex || defaultFlex,
                                                                            "filterable" : fieldCfg.filterable || true

                                                                        };
                                                                    }
                                                                }, function (c) {
                                                                    return c != undefined;
                                                                }));
                                        this.bbar = Ext.create('Ext.PagingToolbar', {
                                            store: store,
                                            displayInfo: true,
                                            displayMsg: translate(widgetName + '.paging.displayMsg'),
                                            emptyMsg: translate(listName + '.paging.emptyMsg'),
                                            items: ['-']
                                        });
                                        this.callParent(arguments);
                                    },
                                    features: [{ ftype : 'filters', encode:true}],
                                    dockedItems: (function () {
                                        var toolbar = _.map(gridCfg.toolbar || [], function(tb) {
                                                if (endsWith(tb.xtype, 'combo')) {
                                                    return {
                                                        xtype: tb.xtype,
                                                        listeners: {
                                                            select: function(combo) {
                                                                store.filters.removeAtKey(tb.filterField);
                                                                store.addFilter(new Ext.util.Filter({
                                                                        id: tb.filterField,
                                                                        property: tb.filterField,
                                                                        value: ''+combo.getValue()
                                                                    }));
                                                            },
                                                            change: function(combo) {
                                                                if (combo.getValue() == '') {
                                                                    store.filters.removeAtKey(tb.filterField);
                                                                    store.reload();
                                                                }
                                                            }
                                                        }
                                                    };
                                                } else
                                                    console.log("unsupported toolbar item xtype: " + tb.xtype);
                                            });
                                        if (gridCfg.searchField != false) {
                                            toolbar.push({
                                                xtype: 'textfield',
                                                itemId: 'textSearch',
                                                flex:1,
                                                emptyText: translate(widgetName + '.search'),
                                                listeners: {
                                                    change: {
                                                        buffer: 500,
                                                        fn: function(textField) {
                                                            store.filters.removeAtKey('query');
                                                            if (textField.getValue() != '') {
                                                                store.addFilter(new Ext.util.Filter({
                                                                    id: 'query',
                                                                    property: 'query',
                                                                    value: '' + textField.getValue()
                                                                }));
                                                            } else {
                                                                store.reload();
                                                            }
                                                        }
                                                    }
                                                },
                                                plugins: config.defaultTextFieldPlugins || []
                                            });
                                        }
                                        return toolbar;
                                    })()
                                });
                            });
                        });
                    });

                } else if (h.type != "GET") {
                   // TODO

                }

            });
        });
    });
});
<commit_msg>improved ExtJS model/store/grid/combobox creation from yesod-dsl JSON output<commit_after>// requires underscore.js
var yesodDsl = function(defs, strings, config) {
    function createStore(storeCls, storeId) {
        var store = Ext.create(storeCls, { storeId:storeId });
        config.defaultStoreFilters.forEach(function(cf) {
            store.addFilter(
                new Ext.util.Filter({
                    id: cf.field,
                    property: cf.field,
                    value: cf.value,
                }), false
            );
        });
        return store;
    }

    // customized ExtJS ComboBox to fetch a record by ID field (call configStore when value set)
    Ext.define(config.name + '.view.Combo',{
        extend: 'Ext.form.field.ComboBox',
        minChars : 1,
        typeAhead: true,
        store:'ext-empty-store',
        queryMode: 'remote',
        pageSize:10,
        valueField: 'id',
        displayField: 'name',
        plugins: config.defaultTextFieldPlugins || [],
        initComponent: function() {
            this.callParent(arguments);
            this.store = createStore(this.myStore);
        },
        configStore: function(extraFilters) {
            var value = this.getValue()
            this.store.addFilter(
                new Ext.util.Filter({
                    id: 'id',
                    property: 'id',
                    value: ''+value
                }), false
            );
            var combo = this;
            (function(c,v) {
               c.store.load(function() {
                    c.setValue(v);
                    c.store.filters.removeAtKey('id');

                    if (c.getFilters) {
                        var filters = c.getFilters();
                        for (var i = 0; i < filters.length; i++) {
                            c.store.addFilter(filters[i], false);
                        }
                    }
                    if (extraFilters) {
                        for (var i = 0; i < extraFilters.length; i++) {
                            c.store.addFilter(extraFilters[i], false);
                        }
                    }
                });
            })(combo,value);
        }
    });

    function endsWith(str, suffix) {
        return str.indexOf(suffix, str.length - suffix.length) !== -1;
    }
    function translate(k,d) {
        var parts = k.split(".");
        if (k in strings) {
            while (k in strings) {
                k = strings[k];
            }
            parts = k.split(".");

            return k;
        } else if (parts[parts.length - 1] in strings) {
            k = parts[parts.length - 1];
            while (k in strings) {
                k = strings[k];
            }
            return k;

        } else if (d) {
            return d;
        } else {
            return k;
        }
    };

    function idTooltip(record) {
        return "ID " + record.get('id');
    }

    defs.routes.forEach(function (r) {
        r.handlers.forEach(function (h) {

            var name = '', url = config.urlBase;
            r.path.forEach(function (pp) {
                url += "/";
                if (pp.type == "string") {
                    name += pp.value;
                    url += pp.value
                } else {
                    name += pp.references;
                    url += '(ID)';
                }
            });
            var modelName = config.name + '.model.' + name,
                storeName = config.name + '.store.' + name,
                comboName = config.name + '.view.' + name + '.Combo',
                routeCfg = config.routes[name] || {};

            // create models and stores for GET handlers without parameters
            if (h.type == "GET" && r.path.length == 1 && r.path[0].type == "string") {

                Ext.define(modelName, {
                    extend: 'Ext.data.Model',
                    fields: h.outputs
                }, function (model) {
                    Ext.define(storeName, {
                        extend: 'Ext.data.Store',
                        model: modelName,
                        pageSize: config.defaultPageSize,
                        remoteFilter: true,
                        remoteSort: true,
                        proxy: {
                            type: 'rest',
                            url: url,
                            reader: {
                                type: 'json',
                                root: 'result',
                                totalProperty: 'totalCount'
                            }
                        }
                    }, function(storeClass) {
                        Ext.data.StoreManager.register(storeClass);

                        // ComboBox for entities with 'name' field
                        if (_.find(h.outputs, function (o) { return o.name == 'name'; }) || routeCfg.combo) {
                            var tpl = undefined, displayTpl = undefined, comboCfg = routeCfg.combo || {};

                            if (comboCfg.field) {
                                tpl = Ext.create('Ext.XTemplate',
                                    '<tpl for=".">',
                                        '<div class="x-boundlist-item">{' + comboCfg.field + '}</div>',
                                    '</tpl>');
                                displayTpl = Ext.create('Ext.XTemplate',
                                    '<tpl for=".">',
                                        '{' + comboCfg.field + '}',
                                    '</tpl>');
                            }
                            Ext.define(comboName, {
                                extend: config.name + '.view.Combo',
                                alias: 'widget.' + name + 'combo',
                                tpl: tpl,
                                displayTpl: displayTpl,
                                emptyText: translate(name + 'combo.emptyText'),
                                myStore: storeName,
                                getFilters: comboCfg.getFilters
                            });
                        }

                        var globalStore = createStore(storeClass, name);
                        // grids on demand by config
                        var grids = routeCfg['grids'] || [];
                        grids.forEach(function(gridCfg) {
                            var store = undefined;
                            if (gridCfg.globalStore == true) {
                                store = globalStore;
                            } else {
                                store = createStore(storeClass);
                            }

                            (gridCfg.filters || []).forEach(function (f) {
                                store.addFilter(new Ext.util.Filter({
                                        id: f.field,
                                        property: f.field,
                                        value: f.value,
                                    }), false)
                            });
                            var widgetName = gridCfg.widget || (name + 'list');
                            var listName  = config.name + '.view.' + name + '.' + widgetName;
                            Ext.define(listName, {
                                extend: 'Ext.grid.Panel',
                                alias: 'widget.' + widgetName,
                                multiSelect: true,
                                title: translate(widgetName + ".title"),
                                store: store,
                                allowDeselect : true,
                                requires: ['Ext.toolbar.Paging', 'Ext.ux.grid.FiltersFeature'],
                                viewConfig: {
                                    listeners: {
                                        render: function(view) {
                                            var tooltip = gridCfg.tooltip || idTooltip;
                                            source.Utils.createToolTip(view, tooltip);
                                        }
                                    }
                                },
                                initComponent: function() {
                                    var grid = this;
                                    this.columns = _.map(gridCfg.columns, function(c) {
                                                        var field = undefined,
                                                            filterable = undefined,
                                                            renderer = undefined,
                                                            flex = undefined,
                                                            header = undefined;
                                                        if (typeof c == 'string') {
                                                            field = c;
                                                            header = c;
                                                        } else {
                                                            field = c.field;
                                                            filterable = c.filterable;
                                                            renderer = c.renderer;
                                                            flex = c.flex;
                                                            header = c.header || field;
                                                        }
                                                        return {
                                                            "header" : translate(widgetName + "." + header, header),
                                                            "dataIndex" : field,
                                                            "flex" : flex || 1,
                                                            "filterable" : filterable || true,
                                                            "renderer" : renderer
                                                        };
                                                    });
                                    var displayMsg = translate(widgetName + '.paging', true);
                                    if (displayMsg === true)
                                        displayMsg = translate(widgetName + '.title') + " {0} - {1} / {2}";

                                    this.bbar = Ext.create('Ext.PagingToolbar', {
                                        store: store,
                                        displayInfo: true,
                                        displayMsg: displayMsg,
                                        emptyMsg: translate(widgetName + '.emptyPaging'),
                                        items: ['-'].concat(_.map(gridCfg.bottomToolbar || [], function(tb) {
                                            return {
                                                name:tb.name,
                                                text:translate(widgetName +"." + tb.name),
                                                listeners: {
                                                    click: function(button) {
                                                        if (tb.action == 'remove') {
                                                            var selected = button.up(widgetName).getSelectionModel().getSelection();
                                                            Ext.MessageBox.confirm(translate(widgetName + '.' + tb.name + '.title'),
                                                                                translate(widgetName + '.' + tb.name + '.message').replace('{0}', ''+selected.length),
                                                                                function (btn) {
                                                                                if (btn == 'yes') {
                                                                                store.remove(selected);
                                                                                store.sync()
                                                                                }
                                                                                });
                                                        }
                                                    }
                                                }
                                            };
                                        }))
                                    });
                                    this.callParent(arguments);

                                    if (gridCfg.preload != false) {
                                        store.load();
                                    }
                                },
                                features: [{ ftype : 'filters', encode:true}],
                                dockedItems: (function () {
                                    var toolbar = _.map(gridCfg.toolbar || [], function(tb) {
                                            if (endsWith(tb.xtype, 'combo')) {
                                                return {
                                                    xtype: tb.xtype,
                                                    listeners: {
                                                        select: function(combo) {
                                                            store.filters.removeAtKey(tb.filterField);
                                                            store.addFilter(new Ext.util.Filter({
                                                                    id: tb.filterField,
                                                                    property: tb.filterField,
                                                                    value: ''+combo.getValue()
                                                                }));
                                                        },
                                                        change: function(combo) {
                                                            if (combo.getValue() == '') {
                                                                store.filters.removeAtKey(tb.filterField);
                                                                store.reload();
                                                            }
                                                        }
                                                    }
                                                };
                                            } else
                                                console.log("unsupported toolbar item xtype: " + tb.xtype);
                                        });
                                    if (gridCfg.searchField != false) {
                                        toolbar.push({
                                            xtype: 'textfield',
                                            itemId: 'textSearch',
                                            flex:1,
                                            emptyText: translate(widgetName + '.search'),
                                            listeners: {
                                                change: {
                                                    buffer: 500,
                                                    fn: function(textField) {
                                                        store.filters.removeAtKey('query');
                                                        if (textField.getValue() != '') {
                                                            store.addFilter(new Ext.util.Filter({
                                                                id: 'query',
                                                                property: 'query',
                                                                value: '' + textField.getValue()
                                                            }));
                                                        } else {
                                                            store.reload();
                                                        }
                                                    }
                                                }
                                            },
                                            plugins: config.defaultTextFieldPlugins || []
                                        });
                                    }
                                    return toolbar;
                                })()
                            });
                        });
                    });
                });

            } else if (h.type != "GET") {
               // TODO

            }

        });
    });
};
<|endoftext|>


<commit_before>module.exports = {
  "env": {
    "browser": true,
    "es6": true,
    "node": true,
  },
  "extends": "eslint:recommended",
  "globals": {
    "atom": true,
  },
  "parser": "babel-eslint",
  "parserOptions": {
    "sourceType": "module",
  },
  "rules": {
    "comma-dangle": [
      2,
      "only-multiline"
    ],
    "curly": [
      1,
      "all"
    ],
    "indent": [
      1,
      2
    ],
    "linebreak-style": [
      2,
      "unix"
    ],
    "no-console": [
      2,
      {"allow": ["warn", "error", "debug"]},
    ],
    "prefer-const": 2,
    "quotes": [
      2,
      "single",
      "avoid-escape"
    ],
    "semi": [
      2,
      "always"
    ],
    "sort-imports": [
      1,
      {
        "ignoreCase": false,
        "ignoreMemberSort": false,
        "memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
      }
    ],
  },
};
<commit_msg>Add Jasmine to env<commit_after>module.exports = {
  "env": {
    "browser": true,
    "es6": true,
    "node": true,
    "jasmine": true
  },
  "extends": "eslint:recommended",
  "globals": {
    "atom": true,
  },
  "parser": "babel-eslint",
  "parserOptions": {
    "sourceType": "module",
  },
  "rules": {
    "comma-dangle": [
      2,
      "only-multiline"
    ],
    "curly": [
      1,
      "all"
    ],
    "indent": [
      1,
      2
    ],
    "linebreak-style": [
      2,
      "unix"
    ],
    "no-console": [
      2,
      {"allow": ["warn", "error", "debug"]},
    ],
    "prefer-const": 2,
    "quotes": [
      2,
      "single",
      "avoid-escape"
    ],
    "semi": [
      2,
      "always"
    ],
    "sort-imports": [
      1,
      {
        "ignoreCase": false,
        "ignoreMemberSort": false,
        "memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
      }
    ],
  },
};
<|endoftext|>


<commit_before>module.exports = {
  root: true,
  parser: '@typescript-eslint/parser',
  globals: {
    __DEV__: true,
  },
  env: {
    node: true,
    browser: true,
  },
  settings: {
    react: {version: '16.9.0'},
  },
  extends: [
    'sanity',
    'sanity/react',
    'sanity/import',
    'plugin:@typescript-eslint/recommended',
    'plugin:react-hooks/recommended',
    'prettier/@typescript-eslint',
    'prettier',
    'prettier/react',
    'sanity/typescript',
  ],
  rules: {
    'import/no-extraneous-dependencies': 'off', // because of parts
    'import/no-unresolved': ['error', {ignore: ['.*:.*']}], // because of parts
    'prettier/prettier': 'error',
    'sort-imports': 'off', // prefer import/order
  },
  plugins: ['import', '@typescript-eslint', 'prettier', 'react'],
}
<commit_msg>[chore] Move `sanity/typescript` before prettier extensions<commit_after>module.exports = {
  root: true,
  parser: '@typescript-eslint/parser',
  globals: {
    __DEV__: true,
  },
  env: {
    node: true,
    browser: true,
  },
  settings: {
    react: {version: '16.9.0'},
  },
  extends: [
    'sanity',
    'sanity/react',
    'sanity/import',
    'plugin:@typescript-eslint/recommended',
    'plugin:react-hooks/recommended',
    'sanity/typescript',
    'prettier/@typescript-eslint',
    'prettier',
    'prettier/react',
  ],
  rules: {
    'import/no-extraneous-dependencies': 'off', // because of parts
    'import/no-unresolved': ['error', {ignore: ['.*:.*']}], // because of parts
    'prettier/prettier': 'error',
    'sort-imports': 'off', // prefer import/order
  },
  plugins: ['import', '@typescript-eslint', 'prettier', 'react'],
}
<|endoftext|>


<commit_before>const OFF = 0;
const WARN = 1;
const ERROR = 2;

module.exports = {
  extends: "eslint:recommended",
  rules: {
    "array-bracket-spacing": [ ERROR, "always" ],
    "arrow-parens": [ ERROR, "always" ],
    "arrow-spacing": [ ERROR ],
    "block-spacing": [ ERROR, "always" ],
    "brace-style": [ ERROR, "1tbs", { "allowSingleLine": true } ],
    "comma-dangle": [ ERROR, "always-multiline" ],
    "comma-spacing": [ ERROR ],
    "comma-style": [ ERROR, "last" ],
    "constructor-super": [ ERROR ],
    "curly": [ ERROR, "all" ],
    "dot-notation": [ ERROR ],
    "eqeqeq": [ ERROR, "allow-null" ],
    "func-style": [ ERROR, "declaration", { "allowArrowFunctions": true} ],
    "indent": [ ERROR, 2 ],
    "key-spacing": [ ERROR ],
    "keyword-spacing": [ ERROR ],
    "linebreak-style": [ ERROR, "unix" ],
    "new-parens": [ ERROR ],
    "max-len": [ ERROR, 80 ],
    "no-array-constructor": [ ERROR ],
    "no-case-declarations": [ ERROR ],
    "no-class-assign": [ ERROR ],
    "no-confusing-arrow": [ ERROR ],
    "no-console": [ OFF ],
    "no-const-assign": [ ERROR ],
    "no-constant-condition": [ ERROR ],
    "no-dupe-class-members": [ ERROR ],
    "no-eval": [ ERROR ],
    "no-extend-native": [ ERROR ],
    "no-extra-semi": [ ERROR ],
    "no-floating-decimal": [ ERROR ],
    "no-implicit-coercion": [ ERROR ],
    "no-implied-eval": [ ERROR ],
    "no-invalid-this": [ ERROR ],
    "no-labels": [ ERROR ],
    "no-lonely-if": [ ERROR ],
    "no-mixed-requires": [ ERROR ],
    "no-multi-spaces": [ ERROR ],
    "no-multi-str": [ ERROR ],
    "no-multiple-empty-lines": [ ERROR, { "max": 2, "maxEOF": 1 } ],
    "no-native-reassign": [ ERROR ],
    "no-new-func": [ ERROR ],
    "no-new-object": [ ERROR ],
    "no-new-require": [ ERROR ],
    "no-new-wrappers": [ ERROR ],
    "no-param-reassign": [ ERROR ],
    "no-proto": [ ERROR ],
    "no-return-assign": [ ERROR ],
    "no-self-compare": [ ERROR ],
    "no-sequences": [ ERROR ],
    "no-shadow": [ ERROR ],
    "no-shadow-restricted-names": [ ERROR ],
    "no-this-before-super": [ ERROR ],
    "no-throw-literal": [ ERROR ],
    "no-trailing-spaces": [ ERROR ],
    "no-unexpected-multiline": [ ERROR ],
    "no-unneeded-ternary": [ ERROR ],
    "no-unreachable": [ ERROR ],
    "no-use-before-define": [ ERROR, "nofunc" ],
    "no-var": [ ERROR ],
    "no-void": [ ERROR ],
    "no-with": [ ERROR ],
    "object-curly-spacing": [ ERROR, "always" ],
    "one-var": [ ERROR, { "uninitialized": "always", "initialized": "never" } ],
    "operator-assignment": [ ERROR, "always" ],
    "operator-linebreak": [ ERROR, "after" ],
    "padded-blocks": [ ERROR, "never" ],
    "prefer-const": [ ERROR ],
    "prefer-template": [ ERROR ],
    "quote-props": [ ERROR, "as-needed" ],
    "quotes": [ ERROR, "single", "avoid-escape" ],
    "semi": [ ERROR, "always" ],
    "semi-spacing": [ ERROR ],
    "space-before-blocks": [ ERROR, "always" ],
    "space-before-function-paren": [ ERROR, "never" ],
    "space-in-parens": [ ERROR, "never" ],
    "space-infix-ops": [ ERROR ],
    "space-unary-ops": [ ERROR ],
    "spaced-comment": [ ERROR, "always" ],
    "strict": [ ERROR, "global" ],
    "wrap-iife": [ ERROR, "inside" ],
    "yoda": [ ERROR, "never" ],
  },
  env: {
    "es6": true,
    "node": true,
    "mocha": true,
  },
};
<commit_msg>Adding arrow-body option with 'as-needed'<commit_after>const OFF = 0;
const WARN = 1;
const ERROR = 2;

module.exports = {
  extends: "eslint:recommended",
  rules: {
    "arrow-body-style": [ERROR, "as-needed"],
    "array-bracket-spacing": [ ERROR, "always" ],
    "arrow-parens": [ ERROR, "always" ],
    "arrow-spacing": [ ERROR ],
    "block-spacing": [ ERROR, "always" ],
    "brace-style": [ ERROR, "1tbs", { "allowSingleLine": true } ],
    "comma-dangle": [ ERROR, "always-multiline" ],
    "comma-spacing": [ ERROR ],
    "comma-style": [ ERROR, "last" ],
    "constructor-super": [ ERROR ],
    "curly": [ ERROR, "all" ],
    "dot-notation": [ ERROR ],
    "eqeqeq": [ ERROR, "allow-null" ],
    "func-style": [ ERROR, "declaration", { "allowArrowFunctions": true} ],
    "indent": [ ERROR, 2 ],
    "key-spacing": [ ERROR ],
    "keyword-spacing": [ ERROR ],
    "linebreak-style": [ ERROR, "unix" ],
    "new-parens": [ ERROR ],
    "max-len": [ ERROR, 80 ],
    "no-array-constructor": [ ERROR ],
    "no-case-declarations": [ ERROR ],
    "no-class-assign": [ ERROR ],
    "no-confusing-arrow": [ ERROR ],
    "no-console": [ OFF ],
    "no-const-assign": [ ERROR ],
    "no-constant-condition": [ ERROR ],
    "no-dupe-class-members": [ ERROR ],
    "no-eval": [ ERROR ],
    "no-extend-native": [ ERROR ],
    "no-extra-semi": [ ERROR ],
    "no-floating-decimal": [ ERROR ],
    "no-implicit-coercion": [ ERROR ],
    "no-implied-eval": [ ERROR ],
    "no-invalid-this": [ ERROR ],
    "no-labels": [ ERROR ],
    "no-lonely-if": [ ERROR ],
    "no-mixed-requires": [ ERROR ],
    "no-multi-spaces": [ ERROR ],
    "no-multi-str": [ ERROR ],
    "no-multiple-empty-lines": [ ERROR, { "max": 2, "maxEOF": 1 } ],
    "no-native-reassign": [ ERROR ],
    "no-new-func": [ ERROR ],
    "no-new-object": [ ERROR ],
    "no-new-require": [ ERROR ],
    "no-new-wrappers": [ ERROR ],
    "no-param-reassign": [ ERROR ],
    "no-proto": [ ERROR ],
    "no-return-assign": [ ERROR ],
    "no-self-compare": [ ERROR ],
    "no-sequences": [ ERROR ],
    "no-shadow": [ ERROR ],
    "no-shadow-restricted-names": [ ERROR ],
    "no-this-before-super": [ ERROR ],
    "no-throw-literal": [ ERROR ],
    "no-trailing-spaces": [ ERROR ],
    "no-unexpected-multiline": [ ERROR ],
    "no-unneeded-ternary": [ ERROR ],
    "no-unreachable": [ ERROR ],
    "no-use-before-define": [ ERROR, "nofunc" ],
    "no-var": [ ERROR ],
    "no-void": [ ERROR ],
    "no-with": [ ERROR ],
    "object-curly-spacing": [ ERROR, "always" ],
    "one-var": [ ERROR, { "uninitialized": "always", "initialized": "never" } ],
    "operator-assignment": [ ERROR, "always" ],
    "operator-linebreak": [ ERROR, "after" ],
    "padded-blocks": [ ERROR, "never" ],
    "prefer-const": [ ERROR ],
    "prefer-template": [ ERROR ],
    "quote-props": [ ERROR, "as-needed" ],
    "quotes": [ ERROR, "single", "avoid-escape" ],
    "semi": [ ERROR, "always" ],
    "semi-spacing": [ ERROR ],
    "space-before-blocks": [ ERROR, "always" ],
    "space-before-function-paren": [ ERROR, "never" ],
    "space-in-parens": [ ERROR, "never" ],
    "space-infix-ops": [ ERROR ],
    "space-unary-ops": [ ERROR ],
    "spaced-comment": [ ERROR, "always" ],
    "strict": [ ERROR, "global" ],
    "wrap-iife": [ ERROR, "inside" ],
    "yoda": [ ERROR, "never" ],
  },
  env: {
    "es6": true,
    "node": true,
    "mocha": true,
  },
};
<|endoftext|>


<commit_before>module.exports = {
  'parserOptions': {
    'ecmaVersion': 6,
    'sourceType': 'module',
    'ecmaFeatures': {
      'jsx': true,
    }
  },

  'plugins': [
    'react',
    'import',
  ],

  'extends': [
    'eslint:recommended',
    'plugin:import/errors',
    'plugin:import/warnings',
    'plugin:import/react',
    'plugin:react/recommended',
    'airbnb',
  ],

  'settings': {
    'import/resolver': 'webpack',
  },

  'rules': {
    'import/extensions': [2, 'never'],
  },
}
<commit_msg>refactor(eslint): bring deprecated .eslintrc to a new style .eslintrc.js<commit_after>module.exports = {
  'parserOptions': {
    'ecmaVersion': 6,
    'sourceType': 'module',
    'ecmaFeatures': {
      'jsx': true,
    }
  },

  'plugins': [
    'react',
    'import',
  ],

  'extends': [
    'eslint:recommended',
    'plugin:import/errors',
    'plugin:import/warnings',
    'plugin:import/react',
    'plugin:react/recommended',
  ],

  'settings': {
    'import/resolver': 'webpack',
  },

  'rules': {
    'array-bracket-spacing': [2, 'never'],
    'block-scoped-var': 2,
    'brace-style': [2, '1tbs'],
    'camelcase': 1,
    'computed-property-spacing': [2, 'never'],
    'consistent-this': [2, 'self'],
    'curly': 2,
    'eol-last': 2,
    'eqeqeq': [2, 'smart'],
    'id-match': [2, '^(_?[a-zA-Z]+([a-zA-Z0-9]+)*)|([A-Z0-9_]+)$', {'properties': true}],
    'indent': [2, 2, {'SwitchCase': 1}],
    'key-spacing': [2, {'beforeColon': false, 'afterColon': true}],
    'linebreak-style': [2, 'unix'],
    'max-depth': [1, 3],
    'max-len': [1, 110],
    'max-nested-callbacks': [2, 3],
    'max-statements': [1, 25],
    'new-cap': 1,
    'no-extend-native': 2,
    'no-extra-semi': 2,
    'no-mixed-spaces-and-tabs': 2,
    'no-multi-spaces': 2,
    'no-multiple-empty-lines': [2, {'max': 2}],
    'no-spaced-func': 2,
    'no-trailing-spaces': 2,
    'no-undef': 2,
    'no-undef-init': 2,
    'no-unused-vars': 1,
    'no-use-before-define': [2, 'nofunc'],
    'object-curly-spacing': [2, 'never'],
    'quotes': [2, 'single', 'avoid-escape'],
    'semi': [2, 'always'],
    'semi-spacing': [2, {'before': false, 'after': true}],
    'keyword-spacing': [2, {'before': true, 'after': true, 'overrides': {}}],
    'space-before-function-paren': [2, 'never'],
    'space-in-parens': [2, 'never'],
    'space-unary-ops': [1, {'words': true, 'nonwords': false}],
    'spaced-comment': [2, 'always'],
    'yoda': [2, 'never'],

    'import/extensions': [2, 'never'],
  },
}
<|endoftext|>


<commit_before>module.exports = {
  "env": {
    "browser": true,
    "node": true
  },
  "extends": "eslint:recommended",
  "parserOptions": {
    "ecmaVersion": 3
  },
  "rules": {
    "no-unused-vars": ["error", {
      "varsIgnorePattern": "(\$(\$|\$\$|yield|post_args|[a-z])|self)",
      "argsIgnorePattern": "(\$(\$|\$\$|yield|post_args|[a-z])|self)",
    }],
    "no-extra-semi": "off",
    "no-empty": "off",
    "no-unreachable": "off",
    "no-cond-assign": "off",
    "no-prototype-builtins": "off",
    "no-constant-condition": ["error", { "checkLoops": false }],
    "no-useless-escape": "off",
    "no-fallthrough": ["error", { "commentPattern": "raise|no-break" }],
    "no-regex-spaces": "off",
    "no-control-regex": "off",
  },
  "globals": {
    "Opal": "readonly",
    "DataView": "readonly",
    "ArrayBuffer": "readonly",
    "globalThis": "readonly",
    "Uint8Array": "readonly",
    "Promise": "readonly",
    "WeakRef": "readonly",
  }
};
<commit_msg>Alphabetize eslint globals<commit_after>module.exports = {
  "env": {
    "browser": true,
    "node": true
  },
  "extends": "eslint:recommended",
  "parserOptions": {
    "ecmaVersion": 3
  },
  "rules": {
    "no-unused-vars": ["error", {
      "varsIgnorePattern": "(\$(\$|\$\$|yield|post_args|[a-z])|self)",
      "argsIgnorePattern": "(\$(\$|\$\$|yield|post_args|[a-z])|self)",
    }],
    "no-extra-semi": "off",
    "no-empty": "off",
    "no-unreachable": "off",
    "no-cond-assign": "off",
    "no-prototype-builtins": "off",
    "no-constant-condition": ["error", { "checkLoops": false }],
    "no-useless-escape": "off",
    "no-fallthrough": ["error", { "commentPattern": "raise|no-break" }],
    "no-regex-spaces": "off",
    "no-control-regex": "off",
  },
  "globals": {
    "ArrayBuffer": "readonly",
    "DataView": "readonly",
    "globalThis": "readonly",
    "Opal": "readonly",
    "Reflect": "readonly",
    "Uint8Array": "readonly",
    "WeakRef": "readonly",
  }
};
<|endoftext|>


<commit_before>module.exports = {
    "extends": "standard",
    "plugins": [
        "standard",
        "promise"
    ]
};<commit_msg>add eslint env<commit_after>module.exports = {
    "env": {
        "mocha": true
    },
    "extends": "standard",
    "plugins": [
        "standard",
        "promise"
    ]
};<|endoftext|>


<commit_before>// http://eslint.org/docs/user-guide/configuring

module.exports = {
	root: true,
	parser: 'babel-eslint',
	parserOptions: {
		sourceType: 'module'
	},
	env: {
		browser: true,
	},
	extends: 'airbnb-base',
	plugins: [
		'html',
		'import'
	],
	settings: {
		'import/resolver': {
			'webpack': {
				'config': 'build/webpack.base.conf.js'
			}
		}
	},
	rules: {
		// don't require .vue extension when importing
		'import/extensions': ['error', 'always', {
			'js': 'never',
			'vue': 'never'
		}],
		// allow optionalDependencies
		'import/no-extraneous-dependencies': ['error', {
			'devDependencies': true
		}],
		// allow debugger during development
		'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
		'no-console': process.env.NODE_ENV === 'production' ? 1 : 0,
		'no-tabs': 0,
		'indent': ['error', 'tab', {
			'SwitchCase': 1
		}],
		'max-len': ['error', 120],
		'no-param-reassign': 0,
	}
};
<commit_msg>add ts extension<commit_after>// http://eslint.org/docs/user-guide/configuring

module.exports = {
	root: true,
	parser: 'babel-eslint',
	parserOptions: {
		sourceType: 'module'
	},
	env: {
		browser: true,
	},
	extends: 'airbnb-base',
	plugins: [
		'html',
		'import'
	],
	settings: {
		'import/resolver': {
			'webpack': {
				'config': 'build/webpack.base.conf.js'
			}
		}
	},
	rules: {
		// don't require .vue extension when importing
		'import/extensions': ['error', 'always', {
			'js': 'never',
			'vue': 'never',
			'ts': 'never'
		}],
		// allow optionalDependencies
		'import/no-extraneous-dependencies': ['error', {
			'devDependencies': true
		}],
		// allow debugger during development
		'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
		'no-console': process.env.NODE_ENV === 'production' ? 1 : 0,
		'no-tabs': 0,
		'indent': ['error', 'tab', {
			'SwitchCase': 1
		}],
		'max-len': ['error', 120],
		'no-param-reassign': 0,
	}
};
<|endoftext|>


<commit_before>module.exports = {
  env: {
    browser: true,
    node: true,
    'jest/globals': true
  },
  extends: [
    'standard',
    'plugin:prettier/recommended',
    'plugin:react/recommended'
  ],
  plugins: ['@typescript-eslint', 'jest'],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    sourceType: 'module',
    project: './tsconfig.json',
    ecmaFeatures: {
      jsx: true
    }
  },
  rules: {
    '@typescript-eslint/adjacent-overload-signatures': 'error',
    'prettier/prettier': [
      'error',
      {
        singleQuote: true,
        semi: false
      }
    ],
    'standard/no-callback-literal': 'off',
    'standard/computed-property-even-spacing': 'off',
    yoda: 'off',
    'react/display-name': 'off',
    'react/prop-types': 'off',
    'import/first': 'off',
    'import/no-webpack-loader-syntax': 'off',
    camelcase: 'off',
    'no-unused-vars': 'off',
    '@typescript-eslint/no-unused-vars': [
      'error',
      {
        args: 'none',
        ignoreRestSiblings: true
      }
    ],
    'no-dupe-class-members': 'off',
    'prefer-promise-reject-errors': 'off'
  },
  globals: {
    browser: true
  }
}
<commit_msg>chore: ignore return lint<commit_after>module.exports = {
  env: {
    browser: true,
    node: true,
    'jest/globals': true
  },
  extends: [
    'standard',
    'plugin:prettier/recommended',
    'plugin:react/recommended'
  ],
  plugins: ['@typescript-eslint', 'jest'],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    sourceType: 'module',
    project: './tsconfig.json',
    ecmaFeatures: {
      jsx: true
    }
  },
  rules: {
    '@typescript-eslint/adjacent-overload-signatures': 'error',
    'prettier/prettier': [
      'error',
      {
        singleQuote: true,
        semi: false
      }
    ],
    'standard/no-callback-literal': 'off',
    'standard/computed-property-even-spacing': 'off',
    yoda: 'off',
    'react/display-name': 'off',
    'react/prop-types': 'off',
    'import/first': 'off',
    'import/no-webpack-loader-syntax': 'off',
    camelcase: 'off',
    'no-unused-vars': 'off',
    'no-useless-return': 'off',
    '@typescript-eslint/no-unused-vars': [
      'error',
      {
        args: 'none',
        ignoreRestSiblings: true
      }
    ],
    'no-dupe-class-members': 'off',
    'prefer-promise-reject-errors': 'off'
  },
  globals: {
    browser: true
  }
}
<|endoftext|>


<commit_before>/**
 * Copyright 2012 Google, Inc. All Rights Reserved.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/**
 * @fileoverview Debugger data proxy.
 *
 * @author benvanik@google.com (Ben Vanik)
 */

/**
 * Debugger data proxy.
 * This connects to a tab and sets up a debug session that is used for reading
 * out events from the page.
 *
 * @param {number} tabId Tab ID.
 * @param {!Object} pageOptions Page options.
 * @constructor
 */
var Debugger = function(tabId, pageOptions) {
  /**
   * Target tab ID.
   * @type {number}
   * @private
   */
  this.tabId_ = tabId;

  /**
   * Target debugee.
   * @type {!Object}
   * @private
   */
  this.debugee_ = {
    tabId: this.tabId_
  };

  /**
   * Page options.
   * @type {!Object}
   * @private
   */
  this.pageOptions_ = pageOptions;

  /**
   * A list of timeline records that have been recorded.
   * @type {!Array.<!Array>}
   * @private
   */
  this.records_ = [];

  /**
   * Whether this debugger is attached.
   * @type {boolean}
   * @private
   */
  this.attached_ = false;

  /**
   * Registered event handlers.
   * @type {!Object}
   * @private
   */
  this.eventHandlers_ = {
    onEvent: this.onEvent_.bind(this),
    onDetach: this.onDetach_.bind(this)
  };

  /**
   * Interval ID used for polling memory statistics.
   * @type {number|null}
   * @private
   */
  this.memoryPollIntervalId_ = null;

  /**
   * The time of the first GC event inside of an event tree.
   * Frequently the timeline will send 2-3 GC events with the same time.
   * De-dupe those by tracking the first GC and ignoring the others.
   * @type {number}
   * @private
   */
  this.lastGcStartTime_ = 0;

  // Attach to the target tab.
  chrome.debugger.attach(this.debugee_, '1.0', (function() {
    this.attached_ = true;
    this.beginListening_();
  }).bind(this));

  // Listen for incoming debugger events.
  chrome.debugger.onEvent.addListener(this.eventHandlers_.onEvent);

  // Listen for detaches. These are either from us or from the dev tools
  // being attached to a page.
  chrome.debugger.onDetach.addListener(this.eventHandlers_.onDetach);
};

/**
 * Detaches the debugger from the tab.
 */
Debugger.prototype.dispose = function() {
  if (this.memoryPollIntervalId_ !== null) {
    window.clearInterval(this.memoryPollIntervalId_);
    this.memoryPollIntervalId_ = null;
  }

  if (this.attached_) {
    this.attached_ = false;
    chrome.debugger.detach(this.debugee_);
  }

  chrome.debugger.onEvent.removeListener(this.eventHandlers_.onEvent);
  chrome.debugger.onDetach.removeListener(this.eventHandlers_.onDetach);

  this.records_.length = 0;
};

/**
 * Handles incoming debugger detaches.
 * @param {!{tabId: number}} source Source tab.
 * @private
 */
Debugger.prototype.onDetach_ = function(source) {
  if (source.tabId != this.debugee_.tabId) {
    return;
  }
  if (!this.attached_) {
    return;
  }
  this.attached_ = false;
  this.dispose();
};

/**
 * Begins listening for debugger events.
 * @private
 */
Debugger.prototype.beginListening_ = function() {
  var timelineEnabled =
      this.pageOptions_['wtf.trace.provider.browser.timeline'];
  if (timelineEnabled === undefined) {
    timelineEnabled = true;
  }
  if (timelineEnabled) {
    chrome.debugger.sendCommand(this.debugee_, 'Timeline.start', {
      // Limit call stack depth to keep messages small - if we ever need this
      // data this can be increased.
      // BUG: values of 0 are ignored:
      // https://code.google.com/p/chromium/issues/detail?id=232008
      'maxCallStackDepth': 1
    });
  }

  var memoryInfoEnabled =
      this.pageOptions_['wtf.trace.provider.browser.memoryInfo'];
  if (memoryInfoEnabled) {
    this.startMemoryPoll_();
  }
};

/**
 * Starts polling for memory information.
 * @private
 */
Debugger.prototype.startMemoryPoll_ = function() {
  function printTree(entry, depth) {
    var pad = '';
    for (var n = 0; n < depth; n++) {
      pad += '  ';
    }
    console.log(pad + entry.name + ' (' + entry.size + 'b)');
    if (entry.children) {
      for (var n = 0; n < entry.children.length; n++) {
        printTree(entry.children[n], depth + 1);
      }
    }
  }

  this.memoryPollIntervalId_ = window.setInterval((function() {
    chrome.debugger.sendCommand(this.debugee_,
        'Memory.getProcessMemoryDistribution', {
          'reportGraph': false
        }, function(results) {
          if (results && results.distribution) {
            printTree(results.distribution, 0);
          }
        });
  }).bind(this), 1000);
};

/**
 * A table of record types to functions that convert them into efficient(ish)
 * records for storage/transmission.
 * @type {!Object.<function(!Object):!Array>}
 * @private
 */
Debugger.TIMELINE_DISPATCH_ = (function() {
  // The table of available record types can be found here:
  // http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js#L70

  /**
   * Attempts to get the bounding rectangle from clip points.
   * @param {!Array.<number>} clip Clip points.
   * @return {Array.<number>} The [x,y,w,h] rect or null invalid.
   */
  function getClipRect(clip) {
    var minX = Number.MAX_VALUE;
    var minY = Number.MAX_VALUE;
    var maxX = Number.MIN_VALUE;
    var maxY = Number.MIN_VALUE;
    for (var i = 0; i < clip.length; i += 2) {
      var x = clip[i];
      var y = clip[i + 1];
      minX = Math.min(minX, x);
      minY = Math.min(minY, y);
      maxX = Math.max(maxX, x);
      maxY = Math.max(maxY, y);
    }
    if (minX == Number.MAX_VALUE) {
      return null;
    }
    return [minX, minY, maxX - minX, maxY - minY];
  };

  var dispatch = {};

  // GCEvent: garbage collections.
  dispatch['GCEvent'] = function(record) {
    return [
      'GCEvent',
      record.startTime,
      record.endTime,
      record.usedHeapSize,
      record.data.usedHeapSizeDelta
    ];
  };

  // EvaluateScript: script runtime/parsing/etc.
  dispatch['EvaluateScript'] = function(record) {
    return [
      'EvaluateScript',
      record.startTime,
      record.endTime,
      record.usedHeapSize,
      record.usedHeapSizeDelta,
      record.data.url,
      record.data.lineNumber
    ];
  };

  // ParseHTML: parsing of HTML in a page.
  dispatch['ParseHTML'] = function(record) {
    return [
      'ParseHTML',
      record.startTime,
      record.endTime
    ];
  };

  dispatch['MarkDOMContent'] = function(record) {
    return [
      'MarkDOMContent',
      record.startTime,
      record.data.isMainFrame
    ];
  };

  // ScheduleStyleRecalculation: a style has been invalidated - expect a
  // RecalculateStyles.
  dispatch['ScheduleStyleRecalculation'] = function(record) {
    return [
      'ScheduleStyleRecalculation',
      record.startTime
    ];
  };

  // RecalculateStyles: style recalculation is occurring.
  dispatch['RecalculateStyles'] = function(record) {
    return [
      'RecalculateStyles',
      record.startTime,
      record.endTime,
      record.data.elementCount
    ];
  };

  // InvalidateLayout: DOM layout was invalidated - expect a Layout.
  dispatch['InvalidateLayout'] = function(record) {
    return [
      'InvalidateLayout',
      record.startTime
    ];
  };

  // Layout: DOM layout.
  dispatch['Layout'] = function(record) {
    var rect = getClipRect(record.data.root);
    return [
      'Layout',
      record.startTime,
      record.endTime,
      record.data.totalObjects,
      record.data.dirtyObjects,
      record.data.partialLayout ? 1 : 0,
      rect ? rect[0] : 0,
      rect ? rect[1] : 0,
      rect ? rect[2] : 0,
      rect ? rect[3] : 0
    ];
  };

  // Paint: DOM element painting.
  dispatch['Paint'] = function(record) {
    var rect = getClipRect(record.data.clip);
    return [
      'Paint',
      record.startTime,
      record.endTime,
      rect ? rect[0] : 0,
      rect ? rect[1] : 0,
      rect ? rect[2] : 0,
      rect ? rect[3] : 0
    ];
  };

  // CompositeLayers: the compositor ran and composited the page.
  dispatch['CompositeLayers'] = function(record) {
    return [
      'CompositeLayers',
      record.startTime,
      record.endTime
    ];
  };

  // DecodeImage: a compressed image was decoded.
  dispatch['DecodeImage'] = function(record) {
    return [
      'DecodeImage',
      record.startTime,
      record.endTime,
      record.data.imageType
    ];
  };

  // ResizeImage: a resized version of a decoded image was required.
  dispatch['ResizeImage'] = function(record) {
    return [
      'ResizeImage',
      record.startTime,
      record.endTime,
      record.data.cached
    ];
  };

  // TODO(benvanik): explore adding the other types:
  // ResourceSendRequest
  // ResourceReceiveResponse
  // ResourceFinish
  // ResourceReceivedData
  // ScrollLayer
  // Program (may be good to show as a heatmap?)

  return dispatch;
})();

/**
 * Handles incoming debugger events.
 * @param {!{tabId: number}} source Source tab.
 * @param {string} method Remote debugger method name.
 * @param {!Object} params Parameters.
 * @private
 */
Debugger.prototype.onEvent_ = function(source, method, params) {
  if (source.tabId != this.debugee_.tabId) {
    return;
  }

  function logRecord(record, indent) {
    indent += '  ';
    console.log(indent + record.type);
    if (record.children) {
      for (var n = 0; n < record.children.length; n++) {
        logRecord(record.children[n], indent);
      }
    }
  }

  switch (method) {
    case 'Timeline.eventRecorded':
      var record = params['record'];
      this.processTimelineRecord_(record);
      //logRecord(record, '');
      break;
  }
};

/**
 * Processes a timeline record and generates event data.
 * @param {!Object} record Timeline record.
 * @private
 */
Debugger.prototype.processTimelineRecord_ = function(record) {
  // Ignore if a duplicate.
  if (this.shouldIgnoreTimelineRecord_(record)) {
    return;
  }

  // Handle the record.
  var dispatch = Debugger.TIMELINE_DISPATCH_[record.type];
  if (dispatch) {
    this.records_.push(dispatch(record));
  }

  // Recursively check children.
  if (record.children && record.children.length) {
    for (var n = 0; n < record.children.length; n++) {
      this.processTimelineRecord_(record.children[n]);
    }
  }
};

/**
 * Checks to see whether a record should be ignored.
 * This is used to filter out duplicate events.
 * @param {!Object} record Timeline record.
 * @return {boolean} True to ignore the record (and children).
 * @private
 */
Debugger.prototype.shouldIgnoreTimelineRecord_ = function(record) {
  if (record.type == 'GCEvent') {
    if (record.startTime == this.lastGcStartTime_) {
      return true;
    }
    this.lastGcStartTime_ = record.startTime;
  }
  return false;
};

/**
 * Gets the list of all records.
 * @return {!Array.<!Array>} Records.
 */
Debugger.prototype.getRecords = function() {
  return this.records_;
};

/**
 * Clears all recorded records.
 */
Debugger.prototype.clearRecords = function() {
  this.records_.length = 0;
};
<commit_msg>Fix for changes to chrome.debugger. The latest Chrome prevents multiple debugger event handlers. This is a good change, as in the case of many tabs being traced this reduces overhead somewhat.<commit_after>/**
 * Copyright 2012 Google, Inc. All Rights Reserved.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/**
 * @fileoverview Debugger data proxy.
 *
 * @author benvanik@google.com (Ben Vanik)
 */

/**
 * Shared dispatch table for debugger events.
 * Modern Chromes only allow a single event handler to be registered on
 * chrome.debugger, so we have to map it back to the right place here.
 * @constructor
 */
var DebuggerDispatchTable = function() {
  /**
   * Total number of attached debugger instances.
   * @type {number}
   * @private
   */
  this.count_ = 0;

  /**
   * Registered tabs, mapped by tab ID.
   * @type {!Object.<number, !Debugger>}
   * @private
   */
  this.tabs_ = {};

  /**
   * Registered event handlers.
   * @type {!Object}
   * @private
   */
  this.eventHandlers_ = {
    onEvent: this.onEvent_.bind(this),
    onDetach: this.onDetach_.bind(this)
  };
};

/**
 * Registers a debugger instance.
 * @param {number} tabId Tab ID being debugged.
 * @param {!Debugger} target Debugger instance to send events to.
 */
DebuggerDispatchTable.prototype.register = function(tabId, target) {
  if (this.tabs_[tabId]) {
    // Replacing?
    this.count_--;
  }
  this.tabs_[tabId] = target;

  this.count_++;
  if (this.count_ == 1) {
    try {
      chrome.debugger.onEvent.addListener(this.eventHandlers_.onEvent);
      chrome.debugger.onDetach.addListener(this.eventHandlers_.onDetach);
    } catch (e) {
      // I'd rather try and fail to get a debugger attached than kill the app.
      // Terrible API.
      console.log('Unable to add debugger event listeners.');
    }
  }
};

/**
 * Unregisters a debugger instance.
 * @param {number} tabId Tab ID being debugged.
 */
DebuggerDispatchTable.prototype.unregister = function(tabId) {
  if (!this.tabs_[tabId]) {
    return;
  }
  delete this.tabs_[tabId];

  this.count_--;
  if (!this.count_) {
    chrome.debugger.onEvent.removeListener(this.eventHandlers_.onEvent);
    chrome.debugger.onDetach.removeListener(this.eventHandlers_.onDetach);
  }
};

/**
 * Handles incoming debugger events.
 * @param {!{tabId: number}} source Source tab.
 * @param {string} method Remote debugger method name.
 * @param {!Object} params Parameters.
 * @private
 */
DebuggerDispatchTable.prototype.onEvent_ = function(source, method, params) {
  var target = this.tabs_[source.tabId];
  if (!target) {
    return;
  }
  target.onEvent_(method, params);
};

/**
 * Handles incoming debugger detaches.
 * @param {!{tabId: number}} source Source tab.
 * @private
 */
DebuggerDispatchTable.prototype.onDetach_ = function(source) {
  var target = this.tabs_[source.tabId];
  if (!target) {
    return;
  }
  target.onDetach_();
};

/**
 * Debugger data proxy.
 * This connects to a tab and sets up a debug session that is used for reading
 * out events from the page.
 *
 * @param {number} tabId Tab ID.
 * @param {!Object} pageOptions Page options.
 * @constructor
 */
var Debugger = function(tabId, pageOptions) {
  /**
   * Target tab ID.
   * @type {number}
   * @private
   */
  this.tabId_ = tabId;

  /**
   * Target debugee.
   * @type {!Object}
   * @private
   */
  this.debugee_ = {
    tabId: this.tabId_
  };

  /**
   * Page options.
   * @type {!Object}
   * @private
   */
  this.pageOptions_ = pageOptions;

  /**
   * A list of timeline records that have been recorded.
   * @type {!Array.<!Array>}
   * @private
   */
  this.records_ = [];

  /**
   * Whether this debugger is attached.
   * @type {boolean}
   * @private
   */
  this.attached_ = false;

  /**
   * Interval ID used for polling memory statistics.
   * @type {number|null}
   * @private
   */
  this.memoryPollIntervalId_ = null;

  /**
   * The time of the first GC event inside of an event tree.
   * Frequently the timeline will send 2-3 GC events with the same time.
   * De-dupe those by tracking the first GC and ignoring the others.
   * @type {number}
   * @private
   */
  this.lastGcStartTime_ = 0;

  // Register us for dispatch.
  Debugger.dispatchTable_.register(this.tabId_, this);

  // Attach to the target tab.
  chrome.debugger.attach(this.debugee_, '1.0', (function() {
    this.attached_ = true;
    this.beginListening_();
  }).bind(this));
};

/**
 * Detaches the debugger from the tab.
 */
Debugger.prototype.dispose = function() {
  if (this.memoryPollIntervalId_ !== null) {
    window.clearInterval(this.memoryPollIntervalId_);
    this.memoryPollIntervalId_ = null;
  }

  if (this.attached_) {
    this.attached_ = false;
    chrome.debugger.detach(this.debugee_);
  }

  Debugger.dispatchTable_.unregister(this.tabId_);

  this.records_.length = 0;
};

/**
 * Shared dispatch table.
 * @type {!DebuggerDispatchTable}
 * @private
 */
Debugger.dispatchTable_ = new DebuggerDispatchTable();

/**
 * Handles incoming debugger detaches.
 * @private
 */
Debugger.prototype.onDetach_ = function() {
  if (!this.attached_) {
    return;
  }
  this.attached_ = false;
  this.dispose();
};

/**
 * Begins listening for debugger events.
 * @private
 */
Debugger.prototype.beginListening_ = function() {
  var timelineEnabled =
      this.pageOptions_['wtf.trace.provider.browser.timeline'];
  if (timelineEnabled === undefined) {
    timelineEnabled = true;
  }
  if (timelineEnabled) {
    chrome.debugger.sendCommand(this.debugee_, 'Timeline.start', {
      // Limit call stack depth to keep messages small - if we ever need this
      // data this can be increased.
      // BUG: values of 0 are ignored:
      // https://code.google.com/p/chromium/issues/detail?id=232008
      'maxCallStackDepth': 1
    });
  }

  var memoryInfoEnabled =
      this.pageOptions_['wtf.trace.provider.browser.memoryInfo'];
  if (memoryInfoEnabled) {
    this.startMemoryPoll_();
  }
};

/**
 * Starts polling for memory information.
 * @private
 */
Debugger.prototype.startMemoryPoll_ = function() {
  function printTree(entry, depth) {
    var pad = '';
    for (var n = 0; n < depth; n++) {
      pad += '  ';
    }
    console.log(pad + entry.name + ' (' + entry.size + 'b)');
    if (entry.children) {
      for (var n = 0; n < entry.children.length; n++) {
        printTree(entry.children[n], depth + 1);
      }
    }
  }

  this.memoryPollIntervalId_ = window.setInterval((function() {
    chrome.debugger.sendCommand(this.debugee_,
        'Memory.getProcessMemoryDistribution', {
          'reportGraph': false
        }, function(results) {
          if (results && results.distribution) {
            printTree(results.distribution, 0);
          }
        });
  }).bind(this), 1000);
};

/**
 * A table of record types to functions that convert them into efficient(ish)
 * records for storage/transmission.
 * @type {!Object.<function(!Object):!Array>}
 * @private
 */
Debugger.TIMELINE_DISPATCH_ = (function() {
  // The table of available record types can be found here:
  // http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js#L70

  /**
   * Attempts to get the bounding rectangle from clip points.
   * @param {!Array.<number>} clip Clip points.
   * @return {Array.<number>} The [x,y,w,h] rect or null invalid.
   */
  function getClipRect(clip) {
    var minX = Number.MAX_VALUE;
    var minY = Number.MAX_VALUE;
    var maxX = Number.MIN_VALUE;
    var maxY = Number.MIN_VALUE;
    for (var i = 0; i < clip.length; i += 2) {
      var x = clip[i];
      var y = clip[i + 1];
      minX = Math.min(minX, x);
      minY = Math.min(minY, y);
      maxX = Math.max(maxX, x);
      maxY = Math.max(maxY, y);
    }
    if (minX == Number.MAX_VALUE) {
      return null;
    }
    return [minX, minY, maxX - minX, maxY - minY];
  };

  var dispatch = {};

  // GCEvent: garbage collections.
  dispatch['GCEvent'] = function(record) {
    return [
      'GCEvent',
      record.startTime,
      record.endTime,
      record.usedHeapSize,
      record.data.usedHeapSizeDelta
    ];
  };

  // EvaluateScript: script runtime/parsing/etc.
  dispatch['EvaluateScript'] = function(record) {
    return [
      'EvaluateScript',
      record.startTime,
      record.endTime,
      record.usedHeapSize,
      record.usedHeapSizeDelta,
      record.data.url,
      record.data.lineNumber
    ];
  };

  // ParseHTML: parsing of HTML in a page.
  dispatch['ParseHTML'] = function(record) {
    return [
      'ParseHTML',
      record.startTime,
      record.endTime
    ];
  };

  dispatch['MarkDOMContent'] = function(record) {
    return [
      'MarkDOMContent',
      record.startTime,
      record.data.isMainFrame
    ];
  };

  // ScheduleStyleRecalculation: a style has been invalidated - expect a
  // RecalculateStyles.
  dispatch['ScheduleStyleRecalculation'] = function(record) {
    return [
      'ScheduleStyleRecalculation',
      record.startTime
    ];
  };

  // RecalculateStyles: style recalculation is occurring.
  dispatch['RecalculateStyles'] = function(record) {
    return [
      'RecalculateStyles',
      record.startTime,
      record.endTime,
      record.data.elementCount
    ];
  };

  // InvalidateLayout: DOM layout was invalidated - expect a Layout.
  dispatch['InvalidateLayout'] = function(record) {
    return [
      'InvalidateLayout',
      record.startTime
    ];
  };

  // Layout: DOM layout.
  dispatch['Layout'] = function(record) {
    var rect = getClipRect(record.data.root);
    return [
      'Layout',
      record.startTime,
      record.endTime,
      record.data.totalObjects,
      record.data.dirtyObjects,
      record.data.partialLayout ? 1 : 0,
      rect ? rect[0] : 0,
      rect ? rect[1] : 0,
      rect ? rect[2] : 0,
      rect ? rect[3] : 0
    ];
  };

  // Paint: DOM element painting.
  dispatch['Paint'] = function(record) {
    var rect = getClipRect(record.data.clip);
    return [
      'Paint',
      record.startTime,
      record.endTime,
      rect ? rect[0] : 0,
      rect ? rect[1] : 0,
      rect ? rect[2] : 0,
      rect ? rect[3] : 0
    ];
  };

  // CompositeLayers: the compositor ran and composited the page.
  dispatch['CompositeLayers'] = function(record) {
    return [
      'CompositeLayers',
      record.startTime,
      record.endTime
    ];
  };

  // DecodeImage: a compressed image was decoded.
  dispatch['DecodeImage'] = function(record) {
    return [
      'DecodeImage',
      record.startTime,
      record.endTime,
      record.data.imageType
    ];
  };

  // ResizeImage: a resized version of a decoded image was required.
  dispatch['ResizeImage'] = function(record) {
    return [
      'ResizeImage',
      record.startTime,
      record.endTime,
      record.data.cached
    ];
  };

  // TODO(benvanik): explore adding the other types:
  // ResourceSendRequest
  // ResourceReceiveResponse
  // ResourceFinish
  // ResourceReceivedData
  // ScrollLayer
  // Program (may be good to show as a heatmap?)

  return dispatch;
})();

/**
 * Handles incoming debugger events.
 * @param {string} method Remote debugger method name.
 * @param {!Object} params Parameters.
 * @private
 */
Debugger.prototype.onEvent_ = function(method, params) {
  function logRecord(record, indent) {
    indent += '  ';
    console.log(indent + record.type);
    if (record.children) {
      for (var n = 0; n < record.children.length; n++) {
        logRecord(record.children[n], indent);
      }
    }
  }

  switch (method) {
    case 'Timeline.eventRecorded':
      var record = params['record'];
      this.processTimelineRecord_(record);
      //logRecord(record, '');
      break;
  }
};

/**
 * Processes a timeline record and generates event data.
 * @param {!Object} record Timeline record.
 * @private
 */
Debugger.prototype.processTimelineRecord_ = function(record) {
  // Ignore if a duplicate.
  if (this.shouldIgnoreTimelineRecord_(record)) {
    return;
  }

  // Handle the record.
  var dispatch = Debugger.TIMELINE_DISPATCH_[record.type];
  if (dispatch) {
    this.records_.push(dispatch(record));
  }

  // Recursively check children.
  if (record.children && record.children.length) {
    for (var n = 0; n < record.children.length; n++) {
      this.processTimelineRecord_(record.children[n]);
    }
  }
};

/**
 * Checks to see whether a record should be ignored.
 * This is used to filter out duplicate events.
 * @param {!Object} record Timeline record.
 * @return {boolean} True to ignore the record (and children).
 * @private
 */
Debugger.prototype.shouldIgnoreTimelineRecord_ = function(record) {
  if (record.type == 'GCEvent') {
    if (record.startTime == this.lastGcStartTime_) {
      return true;
    }
    this.lastGcStartTime_ = record.startTime;
  }
  return false;
};

/**
 * Gets the list of all records.
 * @return {!Array.<!Array>} Records.
 */
Debugger.prototype.getRecords = function() {
  return this.records_;
};

/**
 * Clears all recorded records.
 */
Debugger.prototype.clearRecords = function() {
  this.records_.length = 0;
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule PrefixIntervalTree
 * @typechecks
 */

"use strict";

/**
 * An interval tree that allows to set a number at index and given the value
 * find the largest index for which prefix sum is greater than or equal to value
 * (lower bound) or greater than value (upper bound)
 * Complexity:
 *   construct: O(n)
 *   query: O(log(n))
 *   memory: O(log(n)),
 * where n is leafCount from the constructor
 */
class PrefixIntervalTree {
  constructor(/*number*/ leafCount, /*?number*/ initialLeafValue) {
    var internalLeafCount = this.getInternalLeafCount(leafCount);
    this._leafCount = leafCount;
    this._internalLeafCount = internalLeafCount;
    var nodeCount = 2 * internalLeafCount;
    var Int32Array = global.Int32Array || Array;
    this._value = new Int32Array(nodeCount);
    this._initTables(initialLeafValue || 0);

    this.get = this.get.bind(this);
    this.set = this.set.bind(this);
    this.lowerBound = this.lowerBound.bind(this);
    this.upperBound = this.upperBound.bind(this);
  }

  getInternalLeafCount(/*number*/ leafCount) /*number*/ {
    var internalLeafCount = 1;
    while (internalLeafCount < leafCount) {
      internalLeafCount *= 2;
    }
    return internalLeafCount;
  }

  _initTables(/*number*/ initialLeafValue) {
    var firstLeaf = this._internalLeafCount;
    var lastLeaf = this._internalLeafCount + this._leafCount - 1;
    var i;
    for (i = firstLeaf; i <= lastLeaf; ++i) {
      this._value[i] = initialLeafValue;
    }
    var lastInternalNode = this._internalLeafCount - 1;
    for (i = lastInternalNode; i > 0; --i) {
      this._value[i] =  this._value[2 * i] + this._value[2 * i + 1];
    }
  }

  set(/*number*/ position, /*number*/ value) {
    var nodeIndex = position + this._internalLeafCount;
    this._value[nodeIndex] = value;
    nodeIndex = Math.floor(nodeIndex / 2);
    while (nodeIndex !== 0) {
      this._value[nodeIndex] =
        this._value[2 * nodeIndex] + this._value[2 * nodeIndex + 1];
      nodeIndex = Math.floor(nodeIndex / 2);
    }
  }

  /**
   * Returns an object {index, value} for given position (including value at
   * specified position), or the same for last position if provided position
   * is out of range
   */
  get(/*number*/ position) /*object*/ {
    position = Math.min(position, this._leafCount);
    var nodeIndex = position + this._internalLeafCount;
    var result = this._value[nodeIndex];
    while (nodeIndex > 1) {
      if (nodeIndex % 2 === 1) {
        result = this._value[nodeIndex - 1] + result;
      }
      nodeIndex = Math.floor(nodeIndex / 2);
    }
    return {index: position, value: result};
  }

  /**
   * Returns an object {index, value} where index is index of leaf that was
   * found by upper bound algorithm. Upper bound finds first element for which
   * value is greater than argument
   */
  upperBound(/*number*/ value) /*object*/ {
    var result = this._upperBoundImpl(1, 0, this._internalLeafCount - 1, value);
    if (result.index > this._leafCount - 1) {
      result.index = this._leafCount - 1;
    }
    return result;
  }

  /**
   * Returns result in the same format as upperBound, but finds first element
   * for which value is greater than or equal to argument
   */
  lowerBound(/*number*/ value) /*object*/ {
    var result = this.upperBound(value);
    if (result.value > value && result.index > 0) {
      var previousValue =
        result.value - this._value[this._internalLeafCount + result.index];
      if (previousValue === value) {
        result.value = previousValue;
        result.index--;
      }
    }
    return result;
  }

  _upperBoundImpl(
    /*number*/ nodeIndex,
    /*number*/ nodeIntervalBegin,
    /*number*/ nodeIntervalEnd,
    /*number*/ value
  ) /*object*/ {
    if (nodeIntervalBegin === nodeIntervalEnd) {
      return {
        index: nodeIndex - this._internalLeafCount,
        value: this._value[nodeIndex],
      };
    }

    var nodeIntervalMidpoint =
      Math.floor((nodeIntervalBegin + nodeIntervalEnd + 1) / 2);
    if (value < this._value[nodeIndex * 2]) {
      return this._upperBoundImpl(
        2 * nodeIndex,
        nodeIntervalBegin,
        nodeIntervalMidpoint - 1,
        value
      );
    } else {
      var result = this._upperBoundImpl(
        2 * nodeIndex + 1,
        nodeIntervalMidpoint,
        nodeIntervalEnd,
        value - this._value[2 * nodeIndex]
      );
      result.value += this._value[2 * nodeIndex];
      return result;
    }
  }
}

module.exports = PrefixIntervalTree;
<commit_msg>Fix IE9 issue when creating new array filled with 0<commit_after>/**
 * Copyright (c) 2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule PrefixIntervalTree
 * @typechecks
 */

"use strict";

/**
 * An interval tree that allows to set a number at index and given the value
 * find the largest index for which prefix sum is greater than or equal to value
 * (lower bound) or greater than value (upper bound)
 * Complexity:
 *   construct: O(n)
 *   query: O(log(n))
 *   memory: O(log(n)),
 * where n is leafCount from the constructor
 */
class PrefixIntervalTree {
  constructor(/*number*/ leafCount, /*?number*/ initialLeafValue) {
    var internalLeafCount = this.getInternalLeafCount(leafCount);
    this._leafCount = leafCount;
    this._internalLeafCount = internalLeafCount;
    var nodeCount = 2 * internalLeafCount;
    var Int32Array = global.Int32Array || this._initArray;
    this._value = new Int32Array(nodeCount);
    this._initTables(initialLeafValue || 0);

    this.get = this.get.bind(this);
    this.set = this.set.bind(this);
    this.lowerBound = this.lowerBound.bind(this);
    this.upperBound = this.upperBound.bind(this);
  }

  getInternalLeafCount(/*number*/ leafCount) /*number*/ {
    var internalLeafCount = 1;
    while (internalLeafCount < leafCount) {
      internalLeafCount *= 2;
    }
    return internalLeafCount;
  }

  _initArray(/*number*/ size) /*object*/ {
    return Array.apply(null, new Array(size)).map(Number.prototype.valueOf, 0);
  }

  _initTables(/*number*/ initialLeafValue) {
    var firstLeaf = this._internalLeafCount;
    var lastLeaf = this._internalLeafCount + this._leafCount - 1;
    var i;
    for (i = firstLeaf; i <= lastLeaf; ++i) {
      this._value[i] = initialLeafValue;
    }
    var lastInternalNode = this._internalLeafCount - 1;
    for (i = lastInternalNode; i > 0; --i) {
      this._value[i] =  this._value[2 * i] + this._value[2 * i + 1];
    }
  }

  set(/*number*/ position, /*number*/ value) {
    var nodeIndex = position + this._internalLeafCount;
    this._value[nodeIndex] = value;
    nodeIndex = Math.floor(nodeIndex / 2);
    while (nodeIndex !== 0) {
      this._value[nodeIndex] =
        this._value[2 * nodeIndex] + this._value[2 * nodeIndex + 1];
      nodeIndex = Math.floor(nodeIndex / 2);
    }
  }

  /**
   * Returns an object {index, value} for given position (including value at
   * specified position), or the same for last position if provided position
   * is out of range
   */
  get(/*number*/ position) /*object*/ {
    position = Math.min(position, this._leafCount);
    var nodeIndex = position + this._internalLeafCount;
    var result = this._value[nodeIndex];
    while (nodeIndex > 1) {
      if (nodeIndex % 2 === 1) {
        result = this._value[nodeIndex - 1] + result;
      }
      nodeIndex = Math.floor(nodeIndex / 2);
    }
    return {index: position, value: result};
  }

  /**
   * Returns an object {index, value} where index is index of leaf that was
   * found by upper bound algorithm. Upper bound finds first element for which
   * value is greater than argument
   */
  upperBound(/*number*/ value) /*object*/ {
    var result = this._upperBoundImpl(1, 0, this._internalLeafCount - 1, value);
    if (result.index > this._leafCount - 1) {
      result.index = this._leafCount - 1;
    }
    return result;
  }

  /**
   * Returns result in the same format as upperBound, but finds first element
   * for which value is greater than or equal to argument
   */
  lowerBound(/*number*/ value) /*object*/ {
    var result = this.upperBound(value);
    if (result.value > value && result.index > 0) {
      var previousValue =
        result.value - this._value[this._internalLeafCount + result.index];
      if (previousValue === value) {
        result.value = previousValue;
        result.index--;
      }
    }
    return result;
  }

  _upperBoundImpl(
    /*number*/ nodeIndex,
    /*number*/ nodeIntervalBegin,
    /*number*/ nodeIntervalEnd,
    /*number*/ value
  ) /*object*/ {
    if (nodeIntervalBegin === nodeIntervalEnd) {
      return {
        index: nodeIndex - this._internalLeafCount,
        value: this._value[nodeIndex],
      };
    }

    var nodeIntervalMidpoint =
      Math.floor((nodeIntervalBegin + nodeIntervalEnd + 1) / 2);
    if (value < this._value[nodeIndex * 2]) {
      return this._upperBoundImpl(
        2 * nodeIndex,
        nodeIntervalBegin,
        nodeIntervalMidpoint - 1,
        value
      );
    } else {
      var result = this._upperBoundImpl(
        2 * nodeIndex + 1,
        nodeIntervalMidpoint,
        nodeIntervalEnd,
        value - this._value[2 * nodeIndex]
      );
      result.value += this._value[2 * nodeIndex];
      return result;
    }
  }
}

module.exports = PrefixIntervalTree;
<|endoftext|>


<commit_before>module.exports = {
  "extends": "google",
  "parserOptions": {
    "ecmaVersion": 2017,
    "sourceType": "module",
  },
  "rules": {
    // Things we do, but probably shouldn't.
    "no-var": "off",
    "no-throw-literal": "off",
    "one-var": "off",
    "brace-style": "off",
    "camelcase": "off",
    "no-unused-vars": "off",
    "new-cap": "off",

    // Things we don't care about.
    "require-jsdoc": "off",
    "valid-jsdoc": "off",
    "quote-props": "off",
    "guard-for-in": "off",

    // Thigns we might care about if clang-format did them.
    "arrow-parens": "off",
    "curly": "off",

    // TODO: Once clang-format is working, we can enable some of these.
    // Formatting rules, (probably) handled by clang-format.
    "quotes": "off",
    "eol-last": "off",
    "comma-dangle": "off",
    "max-len": "off",

    // TODO: Once clang-format is working, we can enable some of these.
    // Spacing rules, (probably) handled by clang-format.
    "padded-blocks": "off",
    "spaced-comment": "off",
    "block-spacing": "off",
    "no-trailing-spaces": "off",
    "generator-star-spacing": "off",
  },
};
<commit_msg>Denote a few more checks we probably dont care about<commit_after>module.exports = {
  "extends": "google",
  "parserOptions": {
    "ecmaVersion": 2017,
    "sourceType": "module",
  },
  "rules": {
    // Things we do, but probably shouldn't.
    "no-var": "off",
    "no-throw-literal": "off",
    "one-var": "off",
    "brace-style": "off",
    "camelcase": "off",
    "no-unused-vars": "off",
    "new-cap": "off",

    // Things we don't care about.
    "require-jsdoc": "off",
    "valid-jsdoc": "off",
    "quote-props": "off",
    "guard-for-in": "off",
    "padded-blocks": "off",
    "spaced-comment": "off",
    "block-spacing": "off",
    "no-trailing-spaces": "off",

    // Thigns we might care about if clang-format did them.
    "arrow-parens": "off",
    "curly": "off",

    // TODO: Once clang-format is working, we can enable some of these.
    // Formatting rules, (probably) handled by clang-format.
    "quotes": "off",
    "eol-last": "off",
    "comma-dangle": "off",
    "max-len": "off",

    // TODO: Once clang-format is working, we can enable some of these.
    // Spacing rules, (probably) handled by clang-format.
    "generator-star-spacing": "off",
  },
};
<|endoftext|>


<commit_before>/**
 * Created by Admin on 10.12.2015.
 */
angular.module('mySearchService', [])
    .factory('searchService', ['$http', function searchServiceFactory($http) {
        return {
            all: function (callback) {
                $http.get('data/100_complex.json')
                    .success(function (data) {
                        return callback(data);
                    })
            },
            search: function (search, callback) {

                $http.get('data/100_complex.json')
                    .success(function (data) {

                        if (!search) {
                            return callback(data);
                        }

                        var result = [];

                        search = search.toLowerCase();

                        data.forEach(function (item) {
                            Object.keys(item).forEach(function (key) {

                                if (String(item[key]).toLowerCase().indexOf(search) !== -1) {
                                    result.push(item);
                                    console.log(result);
                                }

                            })
                        });

                        return callback(result);
                    });

            },
            tree: function (callback) {
                $http.get('data/100_complex.json')
                    .success(function (data) {

                        var result = [
                            {
                                name: 'male',
                                children: [
                                    {
                                        "age": "15-35",
                                        "children": []
                                    },
                                    {
                                        "age": "36-50",
                                        "children": []
                                    },
                                    {
                                        "age": "51-65",
                                        "children": []
                                    },
                                    {
                                        "age": "over 60",
                                        "children": []
                                    }
                                ]
                            },
                            {
                                name: 'female',
                                children: [
                                    {
                                        "age": "15-35",
                                        "children": []
                                    },
                                    {
                                        "age": "36-50",
                                        "children": []
                                    },
                                    {
                                        "age": "51-65",
                                        "children": []
                                    },
                                    {
                                        "age": "over 65",
                                        "children": []
                                    }
                                ]
                            }
                        ];

                        data.forEach(function (item) {
                            result[item.gender === "male" ? 0 : 1]
                                .children[(item.age < 36) ? 0 : (item.age < 51) ? 1 : (item.age < 66) ? 2 : 3]
                                .children.push(item);
                        });

                        return callback(result);
                    });
            }

        }
    }
    ])
;<commit_msg>add viewTree<commit_after>/**
 * Created by Admin on 10.12.2015.
 */
angular.module('mySearchService', [])
    .factory('searchService', ['$http', function searchServiceFactory($http) {
        return {
            all: function (callback) {
                $http.get('data/100_complex.json')
                    .success(function (data) {
                        return callback(data);
                    })
            },
            search: function (search, callback) {

                $http.get('data/100_complex.json')
                    .success(function (data) {

                        if (!search) {
                            return callback(data);
                        }

                        var result = [];

                        search = search.toLowerCase();

                        data.forEach(function (item) {
                            Object.keys(item).forEach(function (key) {

                                if (String(item[key]).toLowerCase().indexOf(search) !== -1) {
                                    result.push(item);
                                    console.log(result);
                                }

                            })
                        });

                        return callback(result);
                    });

            },
            tree: function (callback) {
                $http.get('data/100_complex.json')
                    .success(function (data) {

                        var result = [
                            {
                                name: 'male',
                                children: [
                                    {
                                        "age": "15-35",
                                        "children": []
                                    },
                                    {
                                        "age": "36-50",
                                        "children": []
                                    },
                                    {
                                        "age": "51-65",
                                        "children": []
                                    },
                                    {
                                        "age": "over 60",
                                        "children": []
                                    }
                                ]
                            },
                            {
                                name: 'female',
                                children: [
                                    {
                                        "age": "age: 15-35",
                                        "children": []
                                    },
                                    {
                                        "age": "age: 36-50",
                                        "children": []
                                    },
                                    {
                                        "age": "age: 51-65",
                                        "children": []
                                    },
                                    {
                                        "age": "age: over 65",
                                        "children": []
                                    }
                                ]
                            }
                        ];

                        data.forEach(function (item) {
                            result[item.gender === "male" ? 0 : 1]
                                .children[(item.age < 36) ? 0 : (item.age < 51) ? 1 : (item.age < 66) ? 2 : 3]
                                .children.push(item);
                        });

                        return callback(result);
                    });
            }

        }
    }
    ])
;<|endoftext|>