<commit_before>#! /usr/bin/env node

/**
    @module d3plus-test
    @summary Runs linting and unit/browser tests on source files.
    @desc Based on the .eslintrc file provided by the [d3plus-env](#module_d3plus-env) script, all source files will be linted and then passed to any browser/unit tests that have been written.
**/

const buble = require("rollup-plugin-buble"),
      commonjs = require("rollup-plugin-commonjs"),
      deps = require("rollup-plugin-node-resolve"),
      json = require("rollup-plugin-json"),
      log = require("./log")("testing suite"),
      rollup = require("rollup"),
      shell = require("shelljs"),
      {name} = JSON.parse(shell.cat("package.json"));

log.timer("linting code");
shell.exec("eslint --color index.js bin/*.js bin/**/*.js src/*.js src/**/*.js test/*.js test/**/*.js", {silent: true}, (code, stdout) => {

  if (code) {
    log.fail();
    shell.echo(stdout);
    shell.exit(code);
  }
  else {
    log.done();

    const tests = shell.ls("-R", "test/**/*.js");
    if (tests.length) {

      log.timer("compiling tests");
      tests.reverse();

      new shell.ShellString(`
import zora from "zora";
${ tests.map((file, i) => `import test${i} from "./${ file.slice(5) }";`).join("\n") }

zora()
${ tests.map((file, i) => `  .test(test${i})`).join("\n") }
  .run();
`).to("test/.index.js");

      const input = {
        input: "test/.index.js",
        plugins: [
          json(),
          deps({jsnext: true, preferBuiltins: false}),
          commonjs(),
          buble({
            exclude: ["node_modules/zora/**", "test/**"]
          })
        ]
      };

      const output = {
        amd: {id: name},
        file: "test/.bundle.js",
        format: "iife",
        name: "d3plus"
      };

      rollup.rollup(input)
        .then(bundle => {

          bundle.write(output)
            .then(() => {

              log.done();
              shell.echo("");

              shell.exec("cat test/.bundle.js | tape-run --render='faucet'", code => {

                shell.rm("test/.index.js");
                shell.rm("test/.bundle.js");
                shell.echo("");
                shell.exit(code);

              });

            });

        })
        .catch(err => {
          log.fail(err);
          log.exit();
          shell.exit(1);
        });

    }
    else {
      log.warn("no tests found");
      log.exit();
      shell.exit(0);
    }

  }

});
<commit_msg>outputs error code from tape-run if available<commit_after>#! /usr/bin/env node

/**
    @module d3plus-test
    @summary Runs linting and unit/browser tests on source files.
    @desc Based on the .eslintrc file provided by the [d3plus-env](#module_d3plus-env) script, all source files will be linted and then passed to any browser/unit tests that have been written.
**/

const buble = require("rollup-plugin-buble"),
      commonjs = require("rollup-plugin-commonjs"),
      deps = require("rollup-plugin-node-resolve"),
      json = require("rollup-plugin-json"),
      log = require("./log")("testing suite"),
      rollup = require("rollup"),
      shell = require("shelljs"),
      {name} = JSON.parse(shell.cat("package.json"));

log.timer("linting code");
shell.exec("eslint --color index.js bin/*.js bin/**/*.js src/*.js src/**/*.js test/*.js test/**/*.js", {silent: true}, (code, stdout) => {

  if (code) {
    log.fail();
    shell.echo(stdout);
    shell.exit(code);
  }
  else {
    log.done();

    const tests = shell.ls("-R", "test/**/*.js");
    if (tests.length) {

      log.timer("compiling tests");
      tests.reverse();

      new shell.ShellString(`
import zora from "zora";
${ tests.map((file, i) => `import test${i} from "./${ file.slice(5) }";`).join("\n") }

zora()
${ tests.map((file, i) => `  .test(test${i})`).join("\n") }
  .run();
`).to("test/.index.js");

      const input = {
        input: "test/.index.js",
        plugins: [
          json(),
          deps({jsnext: true, preferBuiltins: false}),
          commonjs(),
          buble({
            exclude: ["node_modules/zora/**", "test/**"]
          })
        ]
      };

      const output = {
        amd: {id: name},
        file: "test/.bundle.js",
        format: "iife",
        name: "d3plus"
      };

      rollup.rollup(input)
        .then(bundle => {

          bundle.write(output)
            .then(() => {

              log.done();
              shell.echo("");

              shell.exec("cat test/.bundle.js | tape-run --render='faucet'", (code, stdout) => {

                shell.rm("test/.index.js");
                shell.rm("test/.bundle.js");
                shell.echo(code ? stdout : "");
                shell.exit(code);

              });

            });

        })
        .catch(err => {
          log.fail(err);
          log.exit();
          shell.exit(1);
        });

    }
    else {
      log.warn("no tests found");
      log.exit();
      shell.exit(0);
    }

  }

});
<|endoftext|>


<commit_before>module.exports = function() {
	var model = {};

	model.debuglog = function(str) {
		if (debug)
			console.log("[DEBUG] " + str);
	}

	model.stripNull = function(str) {
		if (typeof str === 'undefined' || str === null)
			return "";
		else
			return str;
	}

	return model;
}()
<commit_msg>fixed naming of inner variable in utils.js<commit_after>module.exports = function() {
	var utils = {};

	utils.debuglog = function(str) {
		if (debug)
			console.log("[DEBUG] " + str);
	}

	utils.stripNull = function(str) {
		if (typeof str === 'undefined' || str === null)
			return "";
		else
			return str;
	}

	return utils;
}()
<|endoftext|>


<commit_before>(function () {
    angular
        .module('gnap-example-app')
        .config(mainRouteConfig);

    mainRouteConfig.$inject = ['$stateProvider'];

    function mainRouteConfig($stateProvider) {
        $stateProvider
            .state('main', {
                templateUrl: 'app/main/main.html',
                controller: 'MainController'
            });
    };
})();
<commit_msg>Main is an abstract state<commit_after>(function () {
    angular
        .module('gnap-example-app')
        .config(mainRouteConfig);

    mainRouteConfig.$inject = ['$stateProvider'];

    function mainRouteConfig($stateProvider) {
        $stateProvider
            .state('main', {
                abstract: true,
                templateUrl: 'app/main/main.html',
                controller: 'MainController'
            });
    };
})();
<|endoftext|>


<commit_before>/**
 * Created by lja on 2015/11/20.
 */

var type = (function () {
    'use strict';

    var class2type = {},
        toString = class2type.toString;

    ('Boolean Number String Function Array Date RegExp Object Error').split(' ').forEach(function (name) {
        class2type['[object ' + name + ']'] = name.toLowerCase();
    });

    function isWindow(obj) {
        return obj !== null && obj.window && obj === obj.window;
    }

    function isFunction(obj) {
        return class2type[toString.call(obj)] === 'function';
    }

    function isDocument(obj) {
        return obj && obj.nodeType === obj.DOCUMENT_NODE;
    }

    function isObject(obj) {
        return class2type[toString.call(obj)] === 'object';
    }

    function isArray(obj) {
        return class2type[toString.call(obj)] === 'array';
    }

    function isNumber(obj) {
        return class2type[toString.call(obj)] === 'number';
    }

    function isPlainObject(obj) {
        return isObject(obj) && !isWindow(obj) &&
            Object.getPrototypeOf(obj) === Object.prototype;
    }

    return {
        isWindow: isWindow,
        isFunction: isFunction,
        isDocument: isDocument,
        isObject: isObject,
        isPlainObject: isPlainObject,
        isArray: isArray,
        isNumber: isNumber
    };
})();

var Jackey8 = (function (type) {
    'use strict';

    var J8,
        emptyArray = [],
        slice = emptyArray.slice,
        jackey8 = {},
        table = document.createElement('table'),
        tableRow = document.createElement('tr'),
        containers = {
            'tr': document.createElement('tbody'),
            'tbody': table, 'thead': table, 'tfoot': table,
            'td': tableRow, 'th': tableRow,
            '*': document.createElement('div')
        },
    //special attributes that should be get/set via method calls
        methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
        simpleSelectorRE = /^[\w-]*$/,//字母 数字 或者下划线，不包括空格
        tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,//tag reg
        readyRE = /complete|loaded|interactive/,
        htmlFragmentRE = /^\s*<(\w+|!)[^>]*>/;//html片段

    //去除null的值
    function removeNullArray(array) {
        return emptyArray.filter.call(array, function (item) {
            return item !== null;
        });
    }

    //decorate the __proto__ and selector
    //todo: __proto__ not supported on IE
    jackey8.decorateDom = function (dom, selector) {
        dom = dom || [];
        dom.__proto__ = J8.fn;//jshint ignore:line
        dom.selector = selector;
        return dom;
    };

    //通过html片段创建dom节点
    jackey8.createNodeByHtmlFragment = function (html, name, properties) {
        var dom, nodes, container;

        //如果是简单的标签，则直接创建元素
        if (simpleSelectorRE.test(html)) {
            dom = J8(document.createElement(RegExp.$1));
        }

        if (!dom) {
            if (html.replace) {
                html = html.replace(tagExpanderRE, '<$1></$2>');
            }

            //正则选取出标签名称
            if (name === void 0) {
                name = htmlFragmentRE.test(html) && RegExp.$1;
            }

            //为了区别标签是否为table内的元素
            // 'tr': document.createElement('tbody'),
            //'tbody': table, 'thead': table, 'tfoot': table,
            //'td': tableRow, 'th': tableRow
            //其他标签都使用div作为parentNode
            if (!(name in containers)) {
                name = '*';
            }

            container = containers[name];
            container.innerHTML = '' + html;//添加到parentNode，并实现转换成dom的过程
            dom = J8.each(slice.call(container.childNodes), function () {
                container.removeChild(this);//从parentNode中移除，并返回childNodes
            });
        }

        //methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
        //如果属性在上面中，则直接赋值，否则通过attr方法去赋值
        if (type.isPlainObject(properties)) {
            nodes = J8(dom);
            J8.each(properties, function (key, value) {
                if (methodAttributes.indexOf(key) > -1) {
                    nodes[key](value);
                } else {
                    nodes.attr(key, value);
                }
            });
        }
    };

    /**
     * find selector in context
     * by id class and 复杂类型：ul li
     * @param context
     * @param selector
     */
    jackey8.queryDom = function (context, selector) {
        var found = [],
            maybeId = selector[0] === '#',
            maybeClass = selector[0] === '.',
            name = maybeId || maybeClass ? selector.slice(1) : selector,
            isSample = simpleSelectorRE.test(name);

        if (!type.isDocument(context)) {
            return found;
        }

        //如果不是简单类型（复杂类型ul li a），使用querySelectorAll
        if (!isSample) {
            found = slice.call(context.querySelectorAll(selector));
        } else {
            if (maybeId) {
                found = context.getElementById(name);
                if (found) {
                    return [found];
                }
                return [];
            }

            if (maybeClass) {
                found = context.getElementsByClassName(name);
            } else {
                found = context.getElementsByTagName(name);
            }
        }

        return slice.call(found);
    };

    //selector: empty string function object array and the instance of Jackey8
    jackey8.init = function (selector, context) {
        var dom;

        //if nothing given, return an empty collection
        if (!selector) {
            return jackey8.decorateDom();
        }

        if (typeof selector === 'string') {
            selector = selector.trim();

            //如果它是一个html片段，则创建一个节点
            //提示：在chrome21和Firefox15下面，
            // 如果不是<开头， 会抛错
            if (selector[0] === '<' && htmlFragmentRE.test(selector)) {
                //todo:
                dom = jackey8.createNodeByHtmlFragment(selector, RegExp.$1, context);
                selector = null;
            }
            //如果有parent，则先找到parent,然后使用find去找到selector
            else if (context !== void 0) {
                J8(context).find(selector);
            }
            else {
                // 正常的选取
                // 1 id 2 class 3 复杂选取
                // 作用域为document，因为如果存在context，则执行$(conetxt).find(selector)
                dom = jackey8.queryDom(document, selector);
            }
        } else if (type.isFunction(selector)) {
            J8(document).ready(selector);
        } else if (selector instanceof jackey8.decorateDom) {
            return selector;
        } else if (type.isArray(selector)) {
            dom = removeNullArray(selector);
        } else if (type.isObject(selector)) {
            //返回数组
            dom = [selector];
            selector = null;
        } else {
            dom = [];
        }

        return jackey8.decorateDom(dom, selector);
    };

    //查找selector是否存在于element元素中
    jackey8.matches = function (element, selector) {
        if (!selector || !element || element.nodeType !== 1) {
            return false;
        }

        //matchesSelector(element,selector)
        //检测该选择器selector是否匹配该元素element的属性
        var matcherSelector = element.webkitMatchesSelector ||
            element.mosMatchesSelector ||
            element.oMatchesSelector ||
            element.matchesSelector;

        if (matcherSelector) {
            return matcherSelector.call(element, selector);
        }

        var match, parent = element.parentNode, temp = !parent;

        //如果没有parentNode
        if (temp) {
            parent = document.createElement('div');
            parent.appendChild(element);
        }

        //~-1 = 0
        match = ~jackey8.queryDom(parent, selector).indexOf(element);

        if (temp) {
            parent.removeChild(element);
        }

        return !!match;

    };

    J8 = function (selector, context) {
        return jackey8.init(selector, context);
    };

    J8.map = function (elements, callback) {
        var value, values = [], i, key;
        if (type.isArray(elements)) {
            for (i = 0; i < elements.length; i++) {
                value = callback(elements[i], i);
                if (value !== null) {
                    values.push(value);
                }
            }
        } else {
            for (key in elements) {//jshint ignore:line
                value = callback(elements[key], key);
                if (value) {
                    values.push(value);
                }
            }
        }

        return values;
    };

    //parent 是否是node的父亲节点
    //document.documentElement.contains(node)
    J8.contains = document.documentElement.contains ?
        function (parent, node) {
            return parent !== node && parent.contains(node);
        } :
        function (parent, node) {
            while (node && (node = node.parentNode)) {
                if (node === parent) {
                    return true;
                }
                return false;
            }
        };

    /**
     * each
     * 遍历数组或者对象
     * @param elements
     * @param callback
     * @returns {*}
     */
    J8.each = function (elements, callback) {
        var i, key;
        if (type.isArray(elements)) {
            for (i = 0; i < elements.length; i++) {
                if (callback.call(elements[i], i, elements[i]) === false) {
                    return elements;
                }
            }
        } else {
            for (key in elements) {
                if (callback.call(elements[key], key, elements[key]) === false) {
                    return elements;
                }
            }
        }
        return elements;
    };

    J8.fn = {
        forEach: emptyArray.forEach,
        reduce: emptyArray.reduce,
        push: emptyArray.push,
        sort: emptyArray.sort,
        indexOf: emptyArray.indexOf,
        concat: emptyArray.concat,
        ready: function (callback) {
            //dom载入判断
            //readyRE = /complete|loaded|interactive/,
            //for IE chrome
            if (readyRE.test(document.readyState) && document.body) {
                callback(J8);
            } else {
                //for firefox
                //IE5678 not working
                document.addEventListener('DOMContentLoaded', function () {
                    callback(J8);
                }, false);
                return this;
            }
        },
        get: function (index) {
            if (!type.isNumber(index)) {
                return slice.call(this);
            }

            return index >= 0 ? this[index] : this[index + this.length];
        },
        toArray: function () {
            return slice.call(this);
        },
        size: function () {
            return this.length;
        },
        remove: function () {
            //通过parentNode.removeChildren
            return this.each(function () {
                if (this.parentNode !== null) {
                    this.parentNode.removeChild(this);
                }
            });
        },
        filter: function (selector) {
            if (type.isFunction(selector)) {
                return this.not(this.not(selector));
            }
            //选取返回的html collection中匹配selector的元素
            return J8(emptyArray.filter.call(this, function (element) {
                return jackey8.matches(element, selector);
            }));
        },
        each: function (callback) {
            emptyArray.every.call(this, function (element, index) {
                return callback.call(element, index, element) !== false;
            });
            return this;
        },
        slice: function () {
            //J8() 转为J8实例
            return J8(slice.apply(this, arguments));
        },
        eq: function (index) {
            return index === -1 ? this.slice(index) : this.slice(index, +index + 1);
        },
        first: function () {
            var element = this[0];
            return element && type.isObject(element) ? element : J8(element);
        },
        last: function () {
            var element = this[this.length - 1];
            return element && type.isObject(element) ? element : J8(element);
        },
        is: function (selector) {
            if (this.length > 0 && jackey8.matches(this[0], selector)) {
                return true;
            }
            return false;
        },
        has: function (selector) {
            //s是否具有selector
            return this.filter(function () {
                return type.isObject(selector) ?
                    J8.contains(this, selector) :
                    J8(this).find(selector).size();
            });
        },
        not: function (selector) {
            //查找不是selector的集合 ｜｜ 去掉selector的元素
            var nodes = [];
            if (type.isFunction(selector)) {
                this.each(function (index) {
                    //如果函数执行后不是返回false，则push进去
                    if (!selector.call(this, index)) {
                        nodes.push(this);
                    }
                });
            } else {
                var excludes;
                //如果是单纯的string，则检查当前返回的html collection里面是否匹配selector
                if (typeof selector === 'string') {
                    excludes = this.filter(selector);
                } else {
                    //如果是数组，而且item为函数，则直接赋值，其它则实例化
                    if (type.isArray(selector) && type.isFunction(selector.item)) {
                        excludes = slice.call(selector);
                    } else {
                        J8(selector);
                    }
                    this.forEach(function (element) {
                        if (excludes.indexOf(element)) {
                            nodes.push(element);
                        }
                    });
                }
                //array
                return J8(nodes);
            }
        },
        find: function (selector) {
            //查找selector(子元素)，返回一个组合的结果
            var result, J8this = this;
            if (!selector) {
                //如果selector为空，返回一个空的J8实例
                result = J8();
            } else if (typeof selector === 'object') {
                // 如果是对象
                //todo: object
                return J8(selector).filter(function () {
                    var node = this;
                    return emptyArray.some.call(J8this, function (parent) {
                        return J8.contains(parent, node);
                    });
                });
            } else if (this.length === 1) {
                //如果只有一个元素，利用queryDom(context,selector), 返回改元素的实例
                result = J8(jackey8.queryDom(this[0], selector));
            } else {
                //多个数组，则遍历
                result = this.map(function () {
                    return jackey8.queryDom(this, selector);
                });
            }

            return result;
        },
        parent: function (selector) {
            //取得父亲节点
            var parentNodes = getProperty(this, 'parentNode');
            //去重
            parentNodes = unique(parentNodes);
            return J8(parentNodes).filter(selector);
        },
        parents: function (selector) {
            var result = [], nodes = this;
            //深度遍历
            while (nodes.length > 0) {
                nodes = J8.map(nodes, function (node) {
                    //选取父亲节点，检查是否是document
                    node = node.parentNode;
                    if (type.isDocument(node) && result.indexOf(node) === -1) {
                        result.push(node);
                        return node;
                    }
                });//jshint ignore:line
            }

            return J8(result).filter(selector);
        }
    };

    //选取元素的属性
    function getProperty(elements, property) {
        return J8.map(elements, function (element) {
            return element[property];
        });
    }

    //去重
    function unique(arr) {
        return emptyArray.filter.call(arr, function (item, index) {
            return arr.indexOf(item) === index;
        });
    }

    //选取元素的子节点
    //如果具有children属性则使用，没有则使用childNodes
    function getChildren(element) {
        return 'children' in element ?
            slice.call(element.children) :
            J8.map(element.childNodes, function (node) {
                if (node.nodeType === 1) {
                    return node;
                }
            });
    }

    return J8;

})(type);

window.Jackey8 = Jackey8;

if (window.J8 === void 0) {
    window.J8 = Jackey8;
}
<commit_msg>contents<commit_after>/**
 * Created by lja on 2015/11/20.
 */

var type = (function () {
    'use strict';

    var class2type = {},
        toString = class2type.toString;

    ('Boolean Number String Function Array Date RegExp Object Error').split(' ').forEach(function (name) {
        class2type['[object ' + name + ']'] = name.toLowerCase();
    });

    function isWindow(obj) {
        return obj !== null && obj.window && obj === obj.window;
    }

    function isFunction(obj) {
        return class2type[toString.call(obj)] === 'function';
    }

    function isDocument(obj) {
        return obj && obj.nodeType === obj.DOCUMENT_NODE;
    }

    function isObject(obj) {
        return class2type[toString.call(obj)] === 'object';
    }

    function isArray(obj) {
        return class2type[toString.call(obj)] === 'array';
    }

    function isNumber(obj) {
        return class2type[toString.call(obj)] === 'number';
    }

    function isPlainObject(obj) {
        return isObject(obj) && !isWindow(obj) &&
            Object.getPrototypeOf(obj) === Object.prototype;
    }

    return {
        isWindow: isWindow,
        isFunction: isFunction,
        isDocument: isDocument,
        isObject: isObject,
        isPlainObject: isPlainObject,
        isArray: isArray,
        isNumber: isNumber
    };
})();

var Jackey8 = (function (type) {
    'use strict';

    var J8,
        emptyArray = [],
        slice = emptyArray.slice,
        jackey8 = {},
        table = document.createElement('table'),
        tableRow = document.createElement('tr'),
        containers = {
            'tr': document.createElement('tbody'),
            'tbody': table, 'thead': table, 'tfoot': table,
            'td': tableRow, 'th': tableRow,
            '*': document.createElement('div')
        },
    //special attributes that should be get/set via method calls
        methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
        simpleSelectorRE = /^[\w-]*$/,//字母 数字 或者下划线，不包括空格
        tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,//tag reg
        readyRE = /complete|loaded|interactive/,
        htmlFragmentRE = /^\s*<(\w+|!)[^>]*>/;//html片段

    //去除null的值
    function removeNullArray(array) {
        return emptyArray.filter.call(array, function (item) {
            return item !== null;
        });
    }

    //decorate the __proto__ and selector
    //todo: __proto__ not supported on IE
    jackey8.decorateDom = function (dom, selector) {
        dom = dom || [];
        dom.__proto__ = J8.fn;//jshint ignore:line
        dom.selector = selector;
        return dom;
    };

    //通过html片段创建dom节点
    jackey8.createNodeByHtmlFragment = function (html, name, properties) {
        var dom, nodes, container;

        //如果是简单的标签，则直接创建元素
        if (simpleSelectorRE.test(html)) {
            dom = J8(document.createElement(RegExp.$1));
        }

        if (!dom) {
            if (html.replace) {
                html = html.replace(tagExpanderRE, '<$1></$2>');
            }

            //正则选取出标签名称
            if (name === void 0) {
                name = htmlFragmentRE.test(html) && RegExp.$1;
            }

            //为了区别标签是否为table内的元素
            // 'tr': document.createElement('tbody'),
            //'tbody': table, 'thead': table, 'tfoot': table,
            //'td': tableRow, 'th': tableRow
            //其他标签都使用div作为parentNode
            if (!(name in containers)) {
                name = '*';
            }

            container = containers[name];
            container.innerHTML = '' + html;//添加到parentNode，并实现转换成dom的过程
            dom = J8.each(slice.call(container.childNodes), function () {
                container.removeChild(this);//从parentNode中移除，并返回childNodes
            });
        }

        //methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
        //如果属性在上面中，则直接赋值，否则通过attr方法去赋值
        if (type.isPlainObject(properties)) {
            nodes = J8(dom);
            J8.each(properties, function (key, value) {
                if (methodAttributes.indexOf(key) > -1) {
                    nodes[key](value);
                } else {
                    nodes.attr(key, value);
                }
            });
        }
    };

    /**
     * find selector in context
     * by id class and 复杂类型：ul li
     * @param context
     * @param selector
     */
    jackey8.queryDom = function (context, selector) {
        var found = [],
            maybeId = selector[0] === '#',
            maybeClass = selector[0] === '.',
            name = maybeId || maybeClass ? selector.slice(1) : selector,
            isSample = simpleSelectorRE.test(name);

        if (!type.isDocument(context)) {
            return found;
        }

        //如果不是简单类型（复杂类型ul li a），使用querySelectorAll
        if (!isSample) {
            found = slice.call(context.querySelectorAll(selector));
        } else {
            if (maybeId) {
                found = context.getElementById(name);
                if (found) {
                    return [found];
                }
                return [];
            }

            if (maybeClass) {
                found = context.getElementsByClassName(name);
            } else {
                found = context.getElementsByTagName(name);
            }
        }

        return slice.call(found);
    };

    //selector: empty string function object array and the instance of Jackey8
    jackey8.init = function (selector, context) {
        var dom;

        //if nothing given, return an empty collection
        if (!selector) {
            return jackey8.decorateDom();
        }

        if (typeof selector === 'string') {
            selector = selector.trim();

            //如果它是一个html片段，则创建一个节点
            //提示：在chrome21和Firefox15下面，
            // 如果不是<开头， 会抛错
            if (selector[0] === '<' && htmlFragmentRE.test(selector)) {
                //todo:
                dom = jackey8.createNodeByHtmlFragment(selector, RegExp.$1, context);
                selector = null;
            }
            //如果有parent，则先找到parent,然后使用find去找到selector
            else if (context !== void 0) {
                J8(context).find(selector);
            }
            else {
                // 正常的选取
                // 1 id 2 class 3 复杂选取
                // 作用域为document，因为如果存在context，则执行$(conetxt).find(selector)
                dom = jackey8.queryDom(document, selector);
            }
        } else if (type.isFunction(selector)) {
            J8(document).ready(selector);
        } else if (selector instanceof jackey8.decorateDom) {
            return selector;
        } else if (type.isArray(selector)) {
            dom = removeNullArray(selector);
        } else if (type.isObject(selector)) {
            //返回数组
            dom = [selector];
            selector = null;
        } else {
            dom = [];
        }

        return jackey8.decorateDom(dom, selector);
    };

    //查找selector是否存在于element元素中
    jackey8.matches = function (element, selector) {
        if (!selector || !element || element.nodeType !== 1) {
            return false;
        }

        //matchesSelector(element,selector)
        //检测该选择器selector是否匹配该元素element的属性
        var matcherSelector = element.webkitMatchesSelector ||
            element.mosMatchesSelector ||
            element.oMatchesSelector ||
            element.matchesSelector;

        if (matcherSelector) {
            return matcherSelector.call(element, selector);
        }

        var match, parent = element.parentNode, temp = !parent;

        //如果没有parentNode
        if (temp) {
            parent = document.createElement('div');
            parent.appendChild(element);
        }

        //~-1 = 0
        match = ~jackey8.queryDom(parent, selector).indexOf(element);

        if (temp) {
            parent.removeChild(element);
        }

        return !!match;

    };

    J8 = function (selector, context) {
        return jackey8.init(selector, context);
    };

    J8.map = function (elements, callback) {
        var value, values = [], i, key;
        if (type.isArray(elements)) {
            for (i = 0; i < elements.length; i++) {
                value = callback(elements[i], i);
                if (value !== null) {
                    values.push(value);
                }
            }
        } else {
            for (key in elements) {//jshint ignore:line
                value = callback(elements[key], key);
                if (value) {
                    values.push(value);
                }
            }
        }

        return values;
    };

    //parent 是否是node的父亲节点
    //document.documentElement.contains(node)
    J8.contains = document.documentElement.contains ?
        function (parent, node) {
            return parent !== node && parent.contains(node);
        } :
        function (parent, node) {
            while (node && (node = node.parentNode)) {
                if (node === parent) {
                    return true;
                }
                return false;
            }
        };

    /**
     * each
     * 遍历数组或者对象
     * @param elements
     * @param callback
     * @returns {*}
     */
    J8.each = function (elements, callback) {
        var i, key;
        if (type.isArray(elements)) {
            for (i = 0; i < elements.length; i++) {
                if (callback.call(elements[i], i, elements[i]) === false) {
                    return elements;
                }
            }
        } else {
            for (key in elements) {
                if (callback.call(elements[key], key, elements[key]) === false) {
                    return elements;
                }
            }
        }
        return elements;
    };

    J8.fn = {
        forEach: emptyArray.forEach,
        reduce: emptyArray.reduce,
        push: emptyArray.push,
        sort: emptyArray.sort,
        indexOf: emptyArray.indexOf,
        concat: emptyArray.concat,
        ready: function (callback) {
            //dom载入判断
            //readyRE = /complete|loaded|interactive/,
            //for IE chrome
            if (readyRE.test(document.readyState) && document.body) {
                callback(J8);
            } else {
                //for firefox
                //IE5678 not working
                document.addEventListener('DOMContentLoaded', function () {
                    callback(J8);
                }, false);
                return this;
            }
        },
        get: function (index) {
            if (!type.isNumber(index)) {
                return slice.call(this);
            }

            return index >= 0 ? this[index] : this[index + this.length];
        },
        toArray: function () {
            return slice.call(this);
        },
        size: function () {
            return this.length;
        },
        remove: function () {
            //通过parentNode.removeChildren
            return this.each(function () {
                if (this.parentNode !== null) {
                    this.parentNode.removeChild(this);
                }
            });
        },
        filter: function (selector) {
            if (type.isFunction(selector)) {
                return this.not(this.not(selector));
            }
            //选取返回的html collection中匹配selector的元素
            return J8(emptyArray.filter.call(this, function (element) {
                return jackey8.matches(element, selector);
            }));
        },
        each: function (callback) {
            emptyArray.every.call(this, function (element, index) {
                return callback.call(element, index, element) !== false;
            });
            return this;
        },
        slice: function () {
            //J8() 转为J8实例
            return J8(slice.apply(this, arguments));
        },
        eq: function (index) {
            return index === -1 ? this.slice(index) : this.slice(index, +index + 1);
        },
        first: function () {
            var element = this[0];
            return element && type.isObject(element) ? element : J8(element);
        },
        last: function () {
            var element = this[this.length - 1];
            return element && type.isObject(element) ? element : J8(element);
        },
        is: function (selector) {
            if (this.length > 0 && jackey8.matches(this[0], selector)) {
                return true;
            }
            return false;
        },
        has: function (selector) {
            //s是否具有selector
            return this.filter(function () {
                return type.isObject(selector) ?
                    J8.contains(this, selector) :
                    J8(this).find(selector).size();
            });
        },
        not: function (selector) {
            //查找不是selector的集合 ｜｜ 去掉selector的元素
            var nodes = [];
            if (type.isFunction(selector)) {
                this.each(function (index) {
                    //如果函数执行后不是返回false，则push进去
                    if (!selector.call(this, index)) {
                        nodes.push(this);
                    }
                });
            } else {
                var excludes;
                //如果是单纯的string，则检查当前返回的html collection里面是否匹配selector
                if (typeof selector === 'string') {
                    excludes = this.filter(selector);
                } else {
                    //如果是数组，而且item为函数，则直接赋值，其它则实例化
                    if (type.isArray(selector) && type.isFunction(selector.item)) {
                        excludes = slice.call(selector);
                    } else {
                        J8(selector);
                    }
                    this.forEach(function (element) {
                        if (excludes.indexOf(element)) {
                            nodes.push(element);
                        }
                    });
                }
                //array
                return J8(nodes);
            }
        },
        find: function (selector) {
            //查找selector(子元素)，返回一个组合的结果
            var result, J8this = this;
            if (!selector) {
                //如果selector为空，返回一个空的J8实例
                result = J8();
            } else if (typeof selector === 'object') {
                // 如果是对象
                //todo: object
                return J8(selector).filter(function () {
                    var node = this;
                    return emptyArray.some.call(J8this, function (parent) {
                        return J8.contains(parent, node);
                    });
                });
            } else if (this.length === 1) {
                //如果只有一个元素，利用queryDom(context,selector), 返回改元素的实例
                result = J8(jackey8.queryDom(this[0], selector));
            } else {
                //多个数组，则遍历
                result = this.map(function () {
                    return jackey8.queryDom(this, selector);
                });
            }

            return result;
        },
        parent: function (selector) {
            //取得父亲节点
            var parentNodes = getProperty(this, 'parentNode');
            //去重
            parentNodes = unique(parentNodes);
            return J8(parentNodes).filter(selector);
        },
        parents: function (selector) {
            var result = [], nodes = this;
            //深度遍历
            while (nodes.length > 0) {
                nodes = J8.map(nodes, function (node) {
                    //选取父亲节点，检查是否是document
                    node = node.parentNode;
                    if (type.isDocument(node) && result.indexOf(node) === -1) {
                        result.push(node);
                        return node;
                    }
                });//jshint ignore:line
            }

            return J8(result).filter(selector);
        },
        children: function (selector) {
            //getChildren 选取子节点，
            var children = J8.map(this, function (element) {
                return getChildren(element);
            });

            //返回children的实例并filter selector
            return J8(children).filter(selector);
        },
        contents: function () {
            //遍历element组合
            return J8.map(this, function (element) {
                //转换为数组返回childNodes
                return slice.call(element.childNodes);
            });
        }
    };

    //选取元素的属性
    function getProperty(elements, property) {
        return J8.map(elements, function (element) {
            return element[property];
        });
    }

    //去重
    function unique(arr) {
        return emptyArray.filter.call(arr, function (item, index) {
            return arr.indexOf(item) === index;
        });
    }

    //选取元素的子节点
    //如果具有children属性则使用，没有则使用childNodes
    function getChildren(element) {
        return 'children' in element ?
            slice.call(element.children) :
            J8.map(element.childNodes, function (node) {
                if (node.nodeType === 1) {
                    return node;
                }
            });
    }

    return J8;

})(type);

window.Jackey8 = Jackey8;

if (window.J8 === void 0) {
    window.J8 = Jackey8;
}
<|endoftext|>


<commit_before>let Promise = require('bluebird')

let model = require('../connect')

let upload = function (id, table, path, field) {
  return new Promise((resolve, reject) => {
    model.knex(table + id).del().then(() => {
      let query = 'alter table ' + table + id + ' auto_increament = 1'
      return model.knex.raw(query)
    }).then(() => {
      let query = 'load data local infile \'' + path + '\' into table ' + table + id + ' (' + field + ')'
      return model.knex.raw(query)
    }).then(() => {
      resolve()
    }).catch(error => {
      console.log(error)
      reject()
    })
  })
}

module.exports = {
  upload: upload
}<commit_msg>fix typo<commit_after>let Promise = require('bluebird')

let model = require('../connect')

let upload = function (id, table, path, field) {
  return new Promise((resolve, reject) => {
    model.knex(table + id).del().then(() => {
      let query = 'alter table ' + table + id + ' AUTO_INCREMENT = 1'
      return model.knex.raw(query)
    }).then(() => {
      let query = 'load data local infile \'' + path + '\' into table ' + table + id + ' (' + field + ')'
      return model.knex.raw(query)
    }).then(() => {
      resolve()
    }).catch(error => {
      console.log(error)
      reject()
    })
  })
}

module.exports = {
  upload: upload
}<|endoftext|>


<commit_before>var moment = require('moment');
var gravatar = require('gravatar');
var lodash = require('lodash');

'use strict';

moment.locale('zh-cn');

module.exports = {
    /**
     * 自动接取文章摘要
     * @param content
     */
    articleDesc: function(content){
        var re = /<[^>]+>/gi;
        str = content.replace(re, '');
        return str.substr(0, 100);
    },
    /**
     * 时间格式化显示
     */
    timeFromNow: function (date) {
        return moment(date).fromNow();
    },
    /**
     * +1
     * @param index
     * @returns {*}
     */
    addOne: function (index) {
        return index + 1;
    },
    add: function (value1, value2) {
        return Number(value1) + Number(value2);
    },
    reduce: function (value1, value2) {
        return Number(value1) - Number(value2);
    },
    /**
     * 格式化日期
     * @param date
     * @param fmt
     * @returns {*}
     */
    formatDate: function (date, fmt) { //author: meizz
        var o = {
            "M+": date.getMonth() + 1,                 //月份
            "d+": date.getDate(),                    //日
            "h+": date.getHours(),                   //小时
            "m+": date.getMinutes(),                 //分
            "s+": date.getSeconds(),                 //秒
            "q+": Math.floor((date.getMonth() + 3) / 3), //季度
            "S": date.getMilliseconds()             //毫秒
        };
        if (/(y+)/.test(fmt))
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt))
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    },
    /**
     * 判断相等
     * @param value1
     * @param value2
     * @param options
     * @returns {*}
     */
    equals: function (value1, value2, block) {
        if (value1 === value2) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    },
    /**
     * 渲染全球通用头像
     * @param email
     * @returns {*}
     */
    gravatar: function (email) {
        var url = gravatar.url(email, {s: '100', r: 'G', d: 'retro'});
        url = lodash.replace(url, 'www.gravatar.com', 'gravatar.duoshuo.com');
        return url;
    },
    /**
     * 遍历数字
     * @param n
     * @param block
     * @returns {string}
     */
    times: function (n, begin, end, block) {
        if (!begin)
            begin = 0;
        if (!end)
            end = n - 1;
        var accum = '';
        for (var i = begin; i <= end; ++i) {
            this.step = i;
            accum += block.fn(this);
        }
        return accum;
    },
    /**
     * 小于
     * @param value1
     * @param value2
     * @param block
     */
    lt: function (value1, value2, block) {
        if (Number(value1) < Number(value2)) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    },
    /**
     * 小于等于
     * @param value1
     * @param value2
     * @param block
     */
    le: function (value1, value2, block) {
        if (Number(value1) <= Number(value2)) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    },
    /**
     * 大于
     * @param value1
     * @param value2
     * @param block
     */
    gt: function (value1, value2, block) {
        if (Number(value1) > Number(value2)) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    },
    /**
     * 大于等于
     * @param value1
     * @param value2
     * @param block
     */
    ge: function (value1, value2, block) {
        if (Number(value1) >= Number(value2)) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    }
};<commit_msg>seo 优化<commit_after>var moment = require('moment');
var gravatar = require('gravatar');
var lodash = require('lodash');

'use strict';

moment.locale('zh-cn');

module.exports = {
    /**
     * 自动接取文章摘要
     * @param content
     */
    articleDesc: function(content){
        if(!content)
            content = '';
        var re = /<[^>]+>/gi;
        str = content.replace(re, '');
        return str.substr(0, 100);
    },
    /**
     * 时间格式化显示
     */
    timeFromNow: function (date) {
        return moment(date).fromNow();
    },
    /**
     * +1
     * @param index
     * @returns {*}
     */
    addOne: function (index) {
        return index + 1;
    },
    add: function (value1, value2) {
        return Number(value1) + Number(value2);
    },
    reduce: function (value1, value2) {
        return Number(value1) - Number(value2);
    },
    /**
     * 格式化日期
     * @param date
     * @param fmt
     * @returns {*}
     */
    formatDate: function (date, fmt) { //author: meizz
        var o = {
            "M+": date.getMonth() + 1,                 //月份
            "d+": date.getDate(),                    //日
            "h+": date.getHours(),                   //小时
            "m+": date.getMinutes(),                 //分
            "s+": date.getSeconds(),                 //秒
            "q+": Math.floor((date.getMonth() + 3) / 3), //季度
            "S": date.getMilliseconds()             //毫秒
        };
        if (/(y+)/.test(fmt))
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt))
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    },
    /**
     * 判断相等
     * @param value1
     * @param value2
     * @param options
     * @returns {*}
     */
    equals: function (value1, value2, block) {
        if (value1 === value2) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    },
    /**
     * 渲染全球通用头像
     * @param email
     * @returns {*}
     */
    gravatar: function (email) {
        var url = gravatar.url(email, {s: '100', r: 'G', d: 'retro'});
        url = lodash.replace(url, 'www.gravatar.com', 'gravatar.duoshuo.com');
        return url;
    },
    /**
     * 遍历数字
     * @param n
     * @param block
     * @returns {string}
     */
    times: function (n, begin, end, block) {
        if (!begin)
            begin = 0;
        if (!end)
            end = n - 1;
        var accum = '';
        for (var i = begin; i <= end; ++i) {
            this.step = i;
            accum += block.fn(this);
        }
        return accum;
    },
    /**
     * 小于
     * @param value1
     * @param value2
     * @param block
     */
    lt: function (value1, value2, block) {
        if (Number(value1) < Number(value2)) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    },
    /**
     * 小于等于
     * @param value1
     * @param value2
     * @param block
     */
    le: function (value1, value2, block) {
        if (Number(value1) <= Number(value2)) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    },
    /**
     * 大于
     * @param value1
     * @param value2
     * @param block
     */
    gt: function (value1, value2, block) {
        if (Number(value1) > Number(value2)) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    },
    /**
     * 大于等于
     * @param value1
     * @param value2
     * @param block
     */
    ge: function (value1, value2, block) {
        if (Number(value1) >= Number(value2)) {
            return block.fn(this);
        } else {
            return block.inverse(this);
        }
    }
};<|endoftext|>


<commit_before>var view = new ol.View({
  projection: 'EPSG:4326',
  center: [0, 0],
  zoom: 3
});

var layer = new ol.layer.Tile({
  source: new ol.source.TileWMS({
    url: 'http://demo.opengeo.org/geoserver/wms',
    params: {
      'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
    }
  })
});
var ol2d = new ol.Map({
  layers: [layer],
  target: 'map2d',
  view: view
});

var ol3d = new olcs.OLCesium(ol2d);
var scene = ol3d.getCesiumScene();
var terrainProvider = new Cesium.CesiumTerrainProvider({
    url : '//cesiumjs.org/stk-terrain/tilesets/world/tiles'
});
scene.terrainProvider = terrainProvider;

ol3d.setEnabled(true);
<commit_msg>Added TileWMS overlay to the EPSG:4326 example<commit_after>var view = new ol.View({
  projection: 'EPSG:4326',
  center: [-100, 35],
  zoom: 3
});

var layer = new ol.layer.Tile({
  source: new ol.source.TileWMS({
    url: 'http://demo.opengeo.org/geoserver/wms',
    params: {
      'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
    }
  })
});
var overlay = new ol.layer.Tile({
  opacity: 0.7,
  extent: [-124.74, 24.96, -66.96, 49.38],
  source: new ol.source.TileWMS(/** @type {olx.source.TileWMSOptions} */ ({
    url: 'http://demo.opengeo.org/geoserver/wms',
    params: {'LAYERS': 'topp:states', 'TILED': true},
    serverType: 'geoserver',
    crossOrigin: 'anonymous'
  }))
});

var ol2d = new ol.Map({
  layers: [layer, overlay],
  target: 'map2d',
  view: view
});

var ol3d = new olcs.OLCesium(ol2d);
var scene = ol3d.getCesiumScene();
var terrainProvider = new Cesium.CesiumTerrainProvider({
    url : '//cesiumjs.org/stk-terrain/tilesets/world/tiles'
});
scene.terrainProvider = terrainProvider;

ol3d.setEnabled(true);
<|endoftext|>


<commit_before>import moment from 'moment'
import {i18n, i18n_c, i18n_nop} from 'app/utils/i18n'

/// Convert a list of key,value into an object
export function to_map(l){
  let d={}
  for(let kv of l)
    d[kv[0]]=kv[1]
  return d
}
/// Convert an object to a list of [k,v]
export function to_list(d){
  let l=[]
  for (let k in d){
    l.push([k, d[k]])
  }
  return l
}

export function dedup(l){
  let ret=[]
  for (let i of l){
    if (ret.indexOf(i)<0)
      ret.push(i)
  }
  return ret
}

export function flatmap( arr, fn ){
  let ret=[]
  for(let el of arr.map( fn ))
    ret = ret.concat(el)
  return ret
}

export function is_empty(l){
  return !l || (l.length==0)
}

/// Drops some keys from a map, and returns a copy without these keys
/// Its optimized for a small ammount of keys O(N²)
export function map_drop(map, keys){
  if (keys.length==0)
    return map

  let r={}
  for (let k in map){
    let v=map[k]
    let drop=false;
    for(let dk of keys){
      if (dk==k){
        drop=true;
        break;
      }
    }
    if (!drop)
      r[k]=v
  }
  return r
}

/// Gets a deep value from a map, following a path. If any if null/undefined, returns that, not continuing the path. Path is a list
export function map_get(obj, path){
  let v = obj[path[0]]
  if (v && path.length>1)
    return map_get(v, path.slice(1))
  return v
}

/// Updates a dict path element with the given value. Path is a list of tranversal.
export function map_set(orig, path, value){
  if (path.length==0)
    return value
  const head = path[0]
  const rest = path.slice(1)
  return merge(orig, {[head]: map_set( orig[head], rest, value )})
}

/// Concatenates lists returning a new one
export function concat(/* arguments */){
  let ret = []
  for (let l of arguments){
    for (let x of l)
      ret.push(x)
  }
  return ret
}

export function sort_by_name(list){
  return list.slice().sort( (a,b) => (a.name || "").localeCompare(b.name || "") )
}

const color_set=["red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey"]
const fixed_colors={
  "stopped" : "_grey",
  "running" : "green",
  "unknown" : "grey",
  "error" : "red",
  "ok" : "green",
  "warning" : "orange",
  "up" : "green",
  "down" : "red",
  "important" : "red",
  "new" : "green",
  "unread" : "yellow",
  "disabled" : "grey",
  "active" : "green",
  "broken" : "red",
  "updatable" : "yellow",
  "": "grey"
}

export function colorize(str){
  str=str.toLowerCase()
  if (fixed_colors[str])
    return fixed_colors[str]
  return random_color(str)
}

/// Returns a random nice color for the logo icon
export function random_color(str){
  // From http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery
  // http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
  function hash(str) {
    var hash = 0, i, chr, len;
    if (str.length === 0) return hash;
    for (i = 0, len = str.length; i < len; i++) {
      chr   = str.charCodeAt(i);
      hash  = ((hash << 5) - hash) + chr;
      hash |= 0; // Convert to 32bit integer
    }
    return Math.abs(hash);
  };

  return color_set[hash(str)%color_set.length]
}

// http://stackoverflow.com/questions/1026069/how-do-i-make-the-first-letter-of-a-string-uppercase-in-javascript
export function capitalize(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

/// Merges two or more dicts into a new one. Do not modify origins. B items have priority.
export function merge(){
  let args=[{}, ...arguments]
  return Object.assign.apply(null, args)
}

export function object_is_equal(a,b){
  if (a == b) // Fast comparison, for object always false
    return true
  if (a == undefined || b == undefined) // Only one, (see prev comparison), so !=
    return false
  for(let k in a){
    if (!b.hasOwnProperty(k))
      return false
    let v=a[k]
    switch(typeof(v)){
      case 'object':
        if (!object_is_equal(v, b[k]))
          return false
      break;
      case 'function': // Ignore fns
      break;
      default:
        if (v!=b[k])
          return false
      break;
    }
  }
  // Now check also all props of b are in a
  for(let k in b){
    if (!a.hasOwnProperty(k))
      return false
  }
  return true
}

const timeunits={
  millisecond: 1,
  second: 1000,
  minute: 1000 * 60,
  hour: 1000 * 60 * 60,
  day: 1000 * 60 * 60 * 24,
  MAX: 1000 * 60 * 60 * 24 * 14
}
const one_day=(24*60*60)

i18n_nop("millisecond")
i18n_nop("second")
i18n_nop("minute")
i18n_nop("hour")
i18n_nop("day")

export function pretty_ago(t, now, minres="second"){
  now = moment.utc(now)
  let other = moment.utc(t)
  if (minres && typeof(minres)=="string")
    minres=timeunits[minres]

  let timediff = now.diff(other)

  if (timediff>timeunits.MAX){
    return pretty_date(other, minres)
  }

  let lastunit='millisecond'
  for (let d in timeunits){
    if (timediff >= timeunits[d])
      lastunit=d
  }
  if (timeunits[lastunit] < minres){
    if (minres >= (timeunits["day"]))
      return i18n("today")
    return i18n("now")
  }
  let units
  if (lastunit=="day"){
    // if days, must check on day boundaries, not 24h chunks;
    // 24h+1m ago could be 2 days ago, not yesterday
    units = Math.floor(now.unix() / one_day) - Math.floor(other.unix() / one_day)

    if (units==0)
      return i18n('today')
    if (units==1)
      return i18n('yesterday')
  }
  else{
    units=Math.floor(timediff / timeunits[lastunit])
  }
  const s=units > 1 ? 's' : ''
  let expr=i18n("{units} {timeunit} ago", {units, timeunit: `${i18n(lastunit)}${s}` })
  return expr
}

export function pretty_date(d, precission){
  if (precission >= timeunits.day )
    return moment(d).format("ddd, ll")
  return moment(d).format("llll")
}

export const months = [
    i18n_nop("January"),
    i18n_nop("February"),
    i18n_nop("March"),
    i18n_nop("April"),
    i18n_nop("May"),
    i18n_nop("June"),
    i18n_nop("July"),
    i18n_nop("August"),
    i18n_nop("September"),
    i18n_nop("October"),
    i18n_nop("November"),
    i18n_nop("December")
  ]

export const days = [
  i18n_nop("Sunday"),
  i18n_nop("Monday"),
  i18n_nop("Tuesday"),
  i18n_nop("Wednesday"),
  i18n_nop("Thursday"),
  i18n_nop("Friday"),
  i18n_nop("Saturday"),
  i18n_nop("Sunday"),
]

export function unwrap(fn, arg1, arg2){ // If two args, use them, if one, use store.getState() and props, if none, use store.getState and this.props.
  if (!fn) // not existant is as an empty list
    return []
  if (typeof(fn) == "function"){
    return fn(arg1, arg2) || [] // May return undefined, null or falsy
  }
  return fn
}

export function match_traits({has, any, all}){
  has = has || []
  if (all){
    for (let a of all){
      if (has.indexOf(a)<0)
        return false
    }
  }
  if (any && any.length>0){
    for (let a of any){
      if (has.indexOf(a)>=0)
        return true
    }
    return false
  }
  else
    return true
}
<commit_msg>Reexport templates from utils for plugins<commit_after>import moment from 'moment'
import {i18n, i18n_c, i18n_nop} from 'app/utils/i18n'
import templates from './templates'

export {templates}

/// Convert a list of key,value into an object
export function to_map(l){
  let d={}
  for(let kv of l)
    d[kv[0]]=kv[1]
  return d
}
/// Convert an object to a list of [k,v]
export function to_list(d){
  let l=[]
  for (let k in d){
    l.push([k, d[k]])
  }
  return l
}

export function dedup(l){
  let ret=[]
  for (let i of l){
    if (ret.indexOf(i)<0)
      ret.push(i)
  }
  return ret
}

export function flatmap( arr, fn ){
  let ret=[]
  for(let el of arr.map( fn ))
    ret = ret.concat(el)
  return ret
}

export function is_empty(l){
  return !l || (l.length==0)
}

/// Drops some keys from a map, and returns a copy without these keys
/// Its optimized for a small ammount of keys O(N²)
export function map_drop(map, keys){
  if (keys.length==0)
    return map

  let r={}
  for (let k in map){
    let v=map[k]
    let drop=false;
    for(let dk of keys){
      if (dk==k){
        drop=true;
        break;
      }
    }
    if (!drop)
      r[k]=v
  }
  return r
}

/// Gets a deep value from a map, following a path. If any if null/undefined, returns that, not continuing the path. Path is a list
export function map_get(obj, path){
  let v = obj[path[0]]
  if (v && path.length>1)
    return map_get(v, path.slice(1))
  return v
}

/// Updates a dict path element with the given value. Path is a list of tranversal.
export function map_set(orig, path, value){
  if (path.length==0)
    return value
  const head = path[0]
  const rest = path.slice(1)
  return merge(orig, {[head]: map_set( orig[head], rest, value )})
}

/// Concatenates lists returning a new one
export function concat(/* arguments */){
  let ret = []
  for (let l of arguments){
    for (let x of l)
      ret.push(x)
  }
  return ret
}

export function sort_by_name(list){
  return list.slice().sort( (a,b) => (a.name || "").localeCompare(b.name || "") )
}

const color_set=["red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey"]
const fixed_colors={
  "stopped" : "_grey",
  "running" : "green",
  "unknown" : "grey",
  "error" : "red",
  "ok" : "green",
  "warning" : "orange",
  "up" : "green",
  "down" : "red",
  "important" : "red",
  "new" : "green",
  "unread" : "yellow",
  "disabled" : "grey",
  "active" : "green",
  "broken" : "red",
  "updatable" : "yellow",
  "": "grey"
}

export function colorize(str){
  str=str.toLowerCase()
  if (fixed_colors[str])
    return fixed_colors[str]
  return random_color(str)
}

/// Returns a random nice color for the logo icon
export function random_color(str){
  // From http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery
  // http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
  function hash(str) {
    var hash = 0, i, chr, len;
    if (str.length === 0) return hash;
    for (i = 0, len = str.length; i < len; i++) {
      chr   = str.charCodeAt(i);
      hash  = ((hash << 5) - hash) + chr;
      hash |= 0; // Convert to 32bit integer
    }
    return Math.abs(hash);
  };

  return color_set[hash(str)%color_set.length]
}

// http://stackoverflow.com/questions/1026069/how-do-i-make-the-first-letter-of-a-string-uppercase-in-javascript
export function capitalize(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

/// Merges two or more dicts into a new one. Do not modify origins. B items have priority.
export function merge(){
  let args=[{}, ...arguments]
  return Object.assign.apply(null, args)
}

export function object_is_equal(a,b){
  if (a == b) // Fast comparison, for object always false
    return true
  if (a == undefined || b == undefined) // Only one, (see prev comparison), so !=
    return false
  for(let k in a){
    if (!b.hasOwnProperty(k))
      return false
    let v=a[k]
    switch(typeof(v)){
      case 'object':
        if (!object_is_equal(v, b[k]))
          return false
      break;
      case 'function': // Ignore fns
      break;
      default:
        if (v!=b[k])
          return false
      break;
    }
  }
  // Now check also all props of b are in a
  for(let k in b){
    if (!a.hasOwnProperty(k))
      return false
  }
  return true
}

const timeunits={
  millisecond: 1,
  second: 1000,
  minute: 1000 * 60,
  hour: 1000 * 60 * 60,
  day: 1000 * 60 * 60 * 24,
  MAX: 1000 * 60 * 60 * 24 * 14
}
const one_day=(24*60*60)

i18n_nop("millisecond")
i18n_nop("second")
i18n_nop("minute")
i18n_nop("hour")
i18n_nop("day")

export function pretty_ago(t, now, minres="second"){
  now = moment.utc(now)
  let other = moment.utc(t)
  if (minres && typeof(minres)=="string")
    minres=timeunits[minres]

  let timediff = now.diff(other)

  if (timediff>timeunits.MAX){
    return pretty_date(other, minres)
  }

  let lastunit='millisecond'
  for (let d in timeunits){
    if (timediff >= timeunits[d])
      lastunit=d
  }
  if (timeunits[lastunit] < minres){
    if (minres >= (timeunits["day"]))
      return i18n("today")
    return i18n("now")
  }
  let units
  if (lastunit=="day"){
    // if days, must check on day boundaries, not 24h chunks;
    // 24h+1m ago could be 2 days ago, not yesterday
    units = Math.floor(now.unix() / one_day) - Math.floor(other.unix() / one_day)

    if (units==0)
      return i18n('today')
    if (units==1)
      return i18n('yesterday')
  }
  else{
    units=Math.floor(timediff / timeunits[lastunit])
  }
  const s=units > 1 ? 's' : ''
  let expr=i18n("{units} {timeunit} ago", {units, timeunit: `${i18n(lastunit)}${s}` })
  return expr
}

export function pretty_date(d, precission){
  if (precission >= timeunits.day )
    return moment(d).format("ddd, ll")
  return moment(d).format("llll")
}

export const months = [
    i18n_nop("January"),
    i18n_nop("February"),
    i18n_nop("March"),
    i18n_nop("April"),
    i18n_nop("May"),
    i18n_nop("June"),
    i18n_nop("July"),
    i18n_nop("August"),
    i18n_nop("September"),
    i18n_nop("October"),
    i18n_nop("November"),
    i18n_nop("December")
  ]

export const days = [
  i18n_nop("Sunday"),
  i18n_nop("Monday"),
  i18n_nop("Tuesday"),
  i18n_nop("Wednesday"),
  i18n_nop("Thursday"),
  i18n_nop("Friday"),
  i18n_nop("Saturday"),
  i18n_nop("Sunday"),
]

export function unwrap(fn, arg1, arg2){ // If two args, use them, if one, use store.getState() and props, if none, use store.getState and this.props.
  if (!fn) // not existant is as an empty list
    return []
  if (typeof(fn) == "function"){
    return fn(arg1, arg2) || [] // May return undefined, null or falsy
  }
  return fn
}

export function match_traits({has, any, all}){
  has = has || []
  if (all){
    for (let a of all){
      if (has.indexOf(a)<0)
        return false
    }
  }
  if (any && any.length>0){
    for (let a of any){
      if (has.indexOf(a)>=0)
        return true
    }
    return false
  }
  else
    return true
}
<|endoftext|>


<commit_before>var path = require('path');
var os = require('os');
var util = require('util');
var cp = require('child_process');
var fs = require('fs');
var colors = require('colors/safe');
var fse = require('fs-extra2');
var getPluginPaths = require('../lib/plugins/module-paths').getPaths;

/*eslint no-console: "off"*/
var pluginPaths = getPluginPaths();
var MAX_RULES_LEN = 1024 * 16;
var CHECK_RUNNING_CMD = process.platform === 'win32' ?
  'tasklist /fi "PID eq %s" | findstr /i "node.exe"'
  : 'ps -f -p %s | grep "node"';

function getHomedir() {
  //默认设置为`~`，防止Linux在开机启动时Node无法获取homedir
  return (typeof os.homedir == 'function' ? os.homedir() :
    process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME']) || '~';
}

function isRunning(pid, callback) {
  pid ? cp.exec(util.format(CHECK_RUNNING_CMD, pid),
    function (err, stdout, stderr) {
      callback(!err && !!stdout.toString().trim());
    }) : callback(false);
}

function showStartWhistleTips(storage) {
  console.log(colors.red('Please execute `w2 start' + (storage ? ' -S ' + storage : '')
    + '` to start whistle first.'));
}

function handleRules(filepath, callback, port) {
  var getRules = require(filepath);
  if (typeof getRules !== 'function') {
    return callback(getRules);
  }
  getRules(callback, {
    port: port,
    checkPlugin: checkPlugin
  });
}

function getString(str) {
  return typeof str !== 'string' ? '' : str.trim();
}

function checkPlugin(name) {
  if (!name || typeof name !== 'string') {
    return false;
  }
  for (var i, len = pluginPaths.length; i < len; i++) {
    try {
      if (fs.statSync(path.join(pluginPaths[i], name)).isDirectory()) {
        return true;
      }
    } catch(e) {}
  }
}

module.exports = function(filepath, storage) {
  var dataDir = path.resolve(getHomedir(), '.startingAppData');
  var configFile = path.join(dataDir, encodeURIComponent('#' + (storage ? storage + '#' : '')));
  if (!fs.existsSync(configFile)) {
    return showStartWhistleTips(storage);
  }
  var pid, options;
  try {
    var config = fse.readJsonSync(configFile);
    options = config.options;
    pid = options && config.pid;
  } catch(e) {}
  isRunning(pid, function(running) {
    if (!running) {
      return showStartWhistleTips(storage);
    }
    filepath = path.resolve(filepath || '.whistle.js');
    var port = options.port > 0 ? options.port : 8899;
    handleRules(filepath, function(result) {
      if (!result) {
        console.log(colors.red('name and rules cannot be empty.'));
        return;
      }
      var name = getString(result.name);
      if (!name || name.length > 64) {
        console.log(colors.red('name cannot be empty and the length cannot exceed 64 characters.'));
        return;
      }
      var rules = getString(result.rules);
      if (rules.length > MAX_RULES_LEN) {
        console.log(colors.red('rules cannot be empty and the size cannot exceed 16k.'));
        return;
      }
      console.log(colors.green('[127.0.0.1:' + port + '] Setting successful.'));
    }, port);
  });
};<commit_msg>feat: add existsPlugin<commit_after>var path = require('path');
var os = require('os');
var util = require('util');
var cp = require('child_process');
var fs = require('fs');
var colors = require('colors/safe');
var fse = require('fs-extra2');
var getPluginPaths = require('../lib/plugins/module-paths').getPaths;

/*eslint no-console: "off"*/
var pluginPaths = getPluginPaths();
var MAX_RULES_LEN = 1024 * 16;
var CHECK_RUNNING_CMD = process.platform === 'win32' ?
  'tasklist /fi "PID eq %s" | findstr /i "node.exe"'
  : 'ps -f -p %s | grep "node"';

function getHomedir() {
  //默认设置为`~`，防止Linux在开机启动时Node无法获取homedir
  return (typeof os.homedir == 'function' ? os.homedir() :
    process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME']) || '~';
}

function isRunning(pid, callback) {
  pid ? cp.exec(util.format(CHECK_RUNNING_CMD, pid),
    function (err, stdout, stderr) {
      callback(!err && !!stdout.toString().trim());
    }) : callback(false);
}

function showStartWhistleTips(storage) {
  console.log(colors.red('Please execute `w2 start' + (storage ? ' -S ' + storage : '')
    + '` to start whistle first.'));
}

function handleRules(filepath, callback, port) {
  var getRules = require(filepath);
  if (typeof getRules !== 'function') {
    return callback(getRules);
  }
  getRules(callback, {
    port: port,
    existsPlugin: existsPlugin
  });
}

function getString(str) {
  return typeof str !== 'string' ? '' : str.trim();
}

function existsPlugin(name) {
  if (!name || typeof name !== 'string') {
    return false;
  }
  for (var i = 0, len = pluginPaths.length; i < len; i++) {
    try {
      if (fs.statSync(path.join(pluginPaths[i], name)).isDirectory()) {
        return true;
      }
    } catch(e) {}
  }
  return false;
}

module.exports = function(filepath, storage) {
  var dataDir = path.resolve(getHomedir(), '.startingAppData');
  var configFile = path.join(dataDir, encodeURIComponent('#' + (storage ? storage + '#' : '')));
  if (!fs.existsSync(configFile)) {
    return showStartWhistleTips(storage);
  }
  var pid, options;
  try {
    var config = fse.readJsonSync(configFile);
    options = config.options;
    pid = options && config.pid;
  } catch(e) {}
  isRunning(pid, function(running) {
    if (!running) {
      return showStartWhistleTips(storage);
    }
    filepath = path.resolve(filepath || '.whistle.js');
    var port = options.port > 0 ? options.port : 8899;
    handleRules(filepath, function(result) {
      if (!result) {
        console.log(colors.red('name and rules cannot be empty.'));
        return;
      }
      var name = getString(result.name);
      if (!name || name.length > 64) {
        console.log(colors.red('name cannot be empty and the length cannot exceed 64 characters.'));
        return;
      }
      var rules = getString(result.rules);
      if (rules.length > MAX_RULES_LEN) {
        console.log(colors.red('rules cannot be empty and the size cannot exceed 16k.'));
        return;
      }
      console.log(colors.green('[127.0.0.1:' + port + '] Setting successful.'));
    }, port);
  });
};<|endoftext|>


<commit_before>/**
 *
 * Floating label 0.1.0 - Floating label based on placeholder attribute.
 * Version 0.1.0
 * @requires jQuery v1.7.0
 *
 * http://www.opensource.org/licenses/mit-license.php
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Fabiano Araujo
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

(function(e){"use strict";e.fn.floatinglabel=function(t){function i(t,r,i){var s=e(""),o=e(t).attr("id"),u=e(t).attr("placeholder");if(e(t).attr("type")=="submit")return false;s.attr("for",o);s.html(u);s.addClass(n.labelClass);t.before(s);t.focusin(function(){s.stop().animate(n.animationIn,n.delayIn,n.easingIn)});t.focusout(function(){if(e(this).val().length>0)s.addClass(n.pinClass);else s.animate(n.animationOut,n.delayOut,n.easingOut)})}var n=e.extend({ignoreId:[],animationIn:{top:"-5px",opacity:"1"},animationOut:{top:"0",opacity:"0"},delayIn:300,delayOut:300,easingIn:false,easingOut:false,labelClass:"floating-label",pinClass:"pin"},t),r=e(this).find(":input");e(r).each(function(){if(e.inArray(e(this).attr("id"),n.ignoreId)==-1)i(e(this))});return this}})(jQuery)<commit_msg><commit_after>/**
 *
 * Floating label 0.2.0 - Floating label based on placeholder attribute.
 * Version 0.2.0
 * @requires jQuery v1.7.0
 *
 * http://www.opensource.org/licenses/mit-license.php
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Fabiano Araujo
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

!function(t){"use strict";t.fn.floatinglabel=function(n){function a(n,a,e){var l=t(""),o=t(n).attr("id"),r=t(n).attr("placeholder");if("submit"==t(n).attr("type"))return!1;l.attr("for",o),l.html(r),l.addClass(i.labelClass),n.before(l),n.on("focusin.floatinglabel",function(){n.trigger("floatinginstart"),l.stop().animate(i.animationIn,i.delayIn,i.easingIn),n.trigger("floatinginend")}),n.on("focusout.floatinglabel",function(){n.trigger("floatingoutstart"),t(this).val().length>0?l.addClass(i.pinClass):l.animate(i.animationOut,i.delayOut,i.easingOut),n.trigger("floatingoutend")})}var i=t.extend({ignoreId:[],animationIn:{top:"-5px",opacity:"1"},animationOut:{top:"0",opacity:"0"},delayIn:300,delayOut:300,easingIn:!1,easingOut:!1,labelClass:"floating-label",pinClass:"pin"},n),e=t(this).find(":input");return t(e).each(function(){-1==t.inArray(t(this).attr("id"),i.ignoreId)&&a(t(this))}),this}}(jQuery);<|endoftext|>


<commit_before>/**
 * All Paladin azerite powers go in here.
 * You need to do this manually, usually an easy way to do this is by opening a WCL report and clicking the icons of spells to open the relevant Wowhead pages, here you can get the icon name by clicking the icon, copy the name of the spell and the ID is in the URL.
 * You can access these entries like other entries in the spells files by importing `common/SPELLS` and using the assigned property on the SPELLS object. Please try to avoid abbreviating properties.
 */

export default {
  STALWART_PROTECTOR: {
    id: 274395,
    name: 'Stalwart Protector',
    icon: 'spell_holy_divineshield',
  },
  RADIANT_INCANDESCENCE: {
    id: 278147,
    name: 'Radiant Incandescence',
    icon: 'spell_holy_searinglight',
  },
  RADIANT_INCANDESCENCE_DAMAGE: {
    id: 278145,
    name: 'Radiant Incandescence',
    icon: 'spell_holy_searinglight',
  },
  RADIANT_INCANDESCENCE_TRAIT: {
    id: 277674,
    name: 'Radiant Incandescence',
    icon: 'spell_holy_searinglight',
  },

  // Holy
  GRACE_OF_THE_JUSTICAR_TRAIT: {
    id: 278593,
    name: 'Grace of the Justicar',
    icon: 'spell_holy_healingaura',
  },
  GRACE_OF_THE_JUSTICAR: {
    id: 278785,
    name: 'Grace of the Justicar',
    icon: 'spell_holy_healingaura',
  },
  GLIMMER_OF_LIGHT_HEAL: {
    id: 287280,
    name: 'Glimmer of Light',
    icon: 'ability_paladin_toweroflight',
  },
  GLIMMER_OF_LIGHT_DAMAGE: {
    id: 287285,
    name: 'Glimmer of Light',
    icon: 'ability_paladin_toweroflight',
  },
  GLIMMER_OF_LIGHT_TRAIT: {
    id: 287268,
    name: 'Glimmer of Light',
    icon: 'ability_paladin_toweroflight',
  },
  GLIMMER_OF_LIGHT: {
    id: 287286,
    name: 'Glimmer of Light',
    icon: 'ability_paladin_toweroflight',
  },
  GLIMMER_OF_LIGHT_TRAIT: {
    id: 287268,
    name: 'Glimmer of Light',
    icon: 'ability_paladin_toweroflight',
  },
  GLIMMER_OF_LIGHT_DAMAGE: {
    id: 287285,
    name: 'Glimmer of Light',
    icon: 'ability_paladin_toweroflight',
  },

  // Retribution
  EXPURGATION: {
    id: 273473,
    name: 'Expurgation',
    icon: 'ability_paladin_bladeofjustice',
  },
  RELENTLESS_INQUISITOR: {
    id: 278617,
    name: 'Relentless Inquisitor',
    icon: 'spell_holy_divinepurpose',
  },
  AVENGERS_MIGHT: {
    id: 272898,
    name: `Avenger's Might`,
    icon: 'spell_holy_avenginewrath',
  },
  INDOMITABLE_JUSTICE: {
    id: 275496,
    name: 'Indomitable Justice',
    icon: 'spell_holy_righteousfury',
  },
  LIGHTS_DECREE: {
    id: 286229,
    name: `Light's Decree`,
    icon: 'spell_holy_blessedresillience',
  },
  EMPYREAN_POWER: {
    id: 286390,
    name: 'Empyrean_power',
    icon: 'ability_paladin_sheathoflight',
  },

  // Retribution Trait Effects
  EXPURGATION_DAMAGE: {
    id: 273481,
    name: 'Expurgation',
    icon: 'ability_paladin_bladeofjustice',
  },
  RELENTLESS_INQUISITOR_BUFF: {
    id: 279204,
    name: 'Relentless Inquisitor',
    icon: 'spell_holy_divinepurpose',
  },
  AVENGERS_MIGHT_BUFF: {
    id: 272903,
    name: `Avenger's Might`,
    icon: 'spell_holy_avenginewrath',
  },
  LIGHTS_DECREE_DAMAGE: {
    id: 286232,
    name: `Light's Decree`,
    icon: 'spell_holy_blessedresillience',
  },
  EMPYREAN_POWER_BUFF: {
    id: 286393,
    name: 'Empyrean Power',
    icon: 'ability_paladin_sheathoflight',
  },

  // Protection
  INSPIRING_VANGUARD: {
    id: 278609,
    name: 'Inspiring Vanguard',
    icon: 'inv_helmet_74',
  },
  INSPIRING_VANGUARD_BUFF: {
    id: 279397,
    name: 'Inspiring Vanguard',
    icon: 'inv_helmet_74',
  },
};
<commit_msg>Fixed merging error.<commit_after>/**
 * All Paladin azerite powers go in here.
 * You need to do this manually, usually an easy way to do this is by opening a WCL report and clicking the icons of spells to open the relevant Wowhead pages, here you can get the icon name by clicking the icon, copy the name of the spell and the ID is in the URL.
 * You can access these entries like other entries in the spells files by importing `common/SPELLS` and using the assigned property on the SPELLS object. Please try to avoid abbreviating properties.
 */

export default {
  STALWART_PROTECTOR: {
    id: 274395,
    name: 'Stalwart Protector',
    icon: 'spell_holy_divineshield',
  },
  RADIANT_INCANDESCENCE: {
    id: 278147,
    name: 'Radiant Incandescence',
    icon: 'spell_holy_searinglight',
  },
  RADIANT_INCANDESCENCE_DAMAGE: {
    id: 278145,
    name: 'Radiant Incandescence',
    icon: 'spell_holy_searinglight',
  },
  RADIANT_INCANDESCENCE_TRAIT: {
    id: 277674,
    name: 'Radiant Incandescence',
    icon: 'spell_holy_searinglight',
  },

  // Holy
  GRACE_OF_THE_JUSTICAR_TRAIT: {
    id: 278593,
    name: 'Grace of the Justicar',
    icon: 'spell_holy_healingaura',
  },
  GRACE_OF_THE_JUSTICAR: {
    id: 278785,
    name: 'Grace of the Justicar',
    icon: 'spell_holy_healingaura',
  },
  GLIMMER_OF_LIGHT: {
    id: 287286,
    name: 'Glimmer of Light',
    icon: 'ability_paladin_toweroflight',
  },
  GLIMMER_OF_LIGHT_TRAIT: {
    id: 287268,
    name: 'Glimmer of Light',
    icon: 'ability_paladin_toweroflight',
  },
  GLIMMER_OF_LIGHT_DAMAGE: {
    id: 287285,
    name: 'Glimmer of Light',
    icon: 'ability_paladin_toweroflight',
  },

  // Retribution
  EXPURGATION: {
    id: 273473,
    name: 'Expurgation',
    icon: 'ability_paladin_bladeofjustice',
  },
  RELENTLESS_INQUISITOR: {
    id: 278617,
    name: 'Relentless Inquisitor',
    icon: 'spell_holy_divinepurpose',
  },
  AVENGERS_MIGHT: {
    id: 272898,
    name: `Avenger's Might`,
    icon: 'spell_holy_avenginewrath',
  },
  INDOMITABLE_JUSTICE: {
    id: 275496,
    name: 'Indomitable Justice',
    icon: 'spell_holy_righteousfury',
  },
  LIGHTS_DECREE: {
    id: 286229,
    name: `Light's Decree`,
    icon: 'spell_holy_blessedresillience',
  },
  EMPYREAN_POWER: {
    id: 286390,
    name: 'Empyrean_power',
    icon: 'ability_paladin_sheathoflight',
  },

  // Retribution Trait Effects
  EXPURGATION_DAMAGE: {
    id: 273481,
    name: 'Expurgation',
    icon: 'ability_paladin_bladeofjustice',
  },
  RELENTLESS_INQUISITOR_BUFF: {
    id: 279204,
    name: 'Relentless Inquisitor',
    icon: 'spell_holy_divinepurpose',
  },
  AVENGERS_MIGHT_BUFF: {
    id: 272903,
    name: `Avenger's Might`,
    icon: 'spell_holy_avenginewrath',
  },
  LIGHTS_DECREE_DAMAGE: {
    id: 286232,
    name: `Light's Decree`,
    icon: 'spell_holy_blessedresillience',
  },
  EMPYREAN_POWER_BUFF: {
    id: 286393,
    name: 'Empyrean Power',
    icon: 'ability_paladin_sheathoflight',
  },

  // Protection
  INSPIRING_VANGUARD: {
    id: 278609,
    name: 'Inspiring Vanguard',
    icon: 'inv_helmet_74',
  },
  INSPIRING_VANGUARD_BUFF: {
    id: 279397,
    name: 'Inspiring Vanguard',
    icon: 'inv_helmet_74',
  },
};
<|endoftext|>


<commit_before>/*
SelectFilter2 - Turns a multiple-select box into a filter interface.

Different than SelectFilter because this is coupled to the admin framework.

Requires core.js, SelectBox.js and addevent.js.
*/

function findForm(node) {
    // returns the node of the form containing the given node
    if (node.tagName.toLowerCase() != 'form') {
        return findForm(node.parentNode);
    }
    return node;
}

var SelectFilter = {
    init: function(field_id, field_name, is_stacked, admin_media_prefix) {
        if (field_id.match(/__prefix__/)){
            // Don't intialize on empty forms.
            return;
        }
        var from_box = document.getElementById(field_id);
        from_box.id += '_from'; // change its ID
        from_box.className = 'filtered';

        var ps = from_box.parentNode.getElementsByTagName('p');
        for (var i=0; i<ps.length; i++) {
            if (ps[i].className.indexOf("info") != -1) {
                // Remove
, because it just gets in the way.
                from_box.parentNode.removeChild(ps[i]);
            } else if (ps[i].className.indexOf("help") != -1) {
                // Move help text up to the top so it isn't below the select
                // boxes or wrapped off on the side to the right of the add
                // button:
                from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild);
            }
        }

        //
 or

        var selector_div = quickElement('div', from_box.parentNode);
        selector_div.className = is_stacked ? 'selector stacked' : 'selector';

        //

        var selector_available = quickElement('div', selector_div, '');
        selector_available.className = 'selector-available';
        quickElement('h2', selector_available, interpolate(gettext('Available %s'), [field_name]));
        var filter_p = quickElement('p', selector_available, '');
        filter_p.className = 'selector-filter';
        quickElement('img', filter_p, '', 'src', admin_media_prefix + 'img/admin/selector-search.gif');
        filter_p.appendChild(document.createTextNode(' '));
        var filter_input = quickElement('input', filter_p, '', 'type', 'text');
        filter_input.id = field_id + '_input';
        selector_available.appendChild(from_box);
        var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()');
        choose_all.className = 'selector-chooseall';

        //

        var selector_chooser = quickElement('ul', selector_div, '');
        selector_chooser.className = 'selector-chooser';
        var add_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Add'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to");})()');
        add_link.className = 'selector-add';
        var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from");})()');
        remove_link.className = 'selector-remove';

        //

        var selector_chosen = quickElement('div', selector_div, '');
        selector_chosen.className = 'selector-chosen';
        quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name]));
        var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click '));
        selector_filter.className = 'selector-filter';
        quickElement('img', selector_filter, '', 'src', admin_media_prefix + (is_stacked ? 'img/admin/selector_stacked-add.gif':'img/admin/selector-add.gif'), 'alt', 'Add');
        var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
        to_box.className = 'filtered';
        var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');
        clear_all.className = 'selector-clearall';

        from_box.setAttribute('name', from_box.getAttribute('name') + '_old');

        // Set up the JavaScript event handlers for the select box filter interface
        addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
        addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
        addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); });
        addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); });
        addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
        SelectBox.init(field_id + '_from');
        SelectBox.init(field_id + '_to');
        // Move selected from_box options to to_box
        SelectBox.move(field_id + '_from', field_id + '_to');
    },
    filter_key_up: function(event, field_id) {
        from = document.getElementById(field_id + '_from');
        // don't submit form if user pressed Enter
        if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
            from.selectedIndex = 0;
            SelectBox.move(field_id + '_from', field_id + '_to');
            from.selectedIndex = 0;
            return false;
        }
        var temp = from.selectedIndex;
        SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
        from.selectedIndex = temp;
        return true;
    },
    filter_key_down: function(event, field_id) {
        from = document.getElementById(field_id + '_from');
        // right arrow -- move across
        if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
            var old_index = from.selectedIndex;
            SelectBox.move(field_id + '_from', field_id + '_to');
            from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index;
            return false;
        }
        // down arrow -- wrap around
        if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) {
            from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
        }
        // up arrow -- wrap around
        if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) {
            from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1;
        }
        return true;
    }
}
<commit_msg>Fixed #12959 -- Added alt text to SelectFilter filter button. Thanks, acdha.<commit_after>/*
SelectFilter2 - Turns a multiple-select box into a filter interface.

Different than SelectFilter because this is coupled to the admin framework.

Requires core.js, SelectBox.js and addevent.js.
*/

function findForm(node) {
    // returns the node of the form containing the given node
    if (node.tagName.toLowerCase() != 'form') {
        return findForm(node.parentNode);
    }
    return node;
}

var SelectFilter = {
    init: function(field_id, field_name, is_stacked, admin_media_prefix) {
        if (field_id.match(/__prefix__/)){
            // Don't intialize on empty forms.
            return;
        }
        var from_box = document.getElementById(field_id);
        from_box.id += '_from'; // change its ID
        from_box.className = 'filtered';

        var ps = from_box.parentNode.getElementsByTagName('p');
        for (var i=0; i<ps.length; i++) {
            if (ps[i].className.indexOf("info") != -1) {
                // Remove
, because it just gets in the way.
                from_box.parentNode.removeChild(ps[i]);
            } else if (ps[i].className.indexOf("help") != -1) {
                // Move help text up to the top so it isn't below the select
                // boxes or wrapped off on the side to the right of the add
                // button:
                from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild);
            }
        }

        //
 or

        var selector_div = quickElement('div', from_box.parentNode);
        selector_div.className = is_stacked ? 'selector stacked' : 'selector';

        //

        var selector_available = quickElement('div', selector_div, '');
        selector_available.className = 'selector-available';
        quickElement('h2', selector_available, interpolate(gettext('Available %s'), [field_name]));
        var filter_p = quickElement('p', selector_available, '');
        filter_p.className = 'selector-filter';

        var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input", 'style', 'width:16px;padding:2px');

        var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_media_prefix + 'img/admin/selector-search.gif');
        search_selector_img.alt = gettext("Filter");

        filter_p.appendChild(document.createTextNode(' '));

        var filter_input = quickElement('input', filter_p, '', 'type', 'text');
        filter_input.id = field_id + '_input';
        selector_available.appendChild(from_box);
        var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()');
        choose_all.className = 'selector-chooseall';

        //

        var selector_chooser = quickElement('ul', selector_div, '');
        selector_chooser.className = 'selector-chooser';
        var add_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Add'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to");})()');
        add_link.className = 'selector-add';
        var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from");})()');
        remove_link.className = 'selector-remove';

        //

        var selector_chosen = quickElement('div', selector_div, '');
        selector_chosen.className = 'selector-chosen';
        quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name]));
        var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click '));
        selector_filter.className = 'selector-filter';
        quickElement('img', selector_filter, '', 'src', admin_media_prefix + (is_stacked ? 'img/admin/selector_stacked-add.gif':'img/admin/selector-add.gif'), 'alt', 'Add');
        var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
        to_box.className = 'filtered';
        var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');
        clear_all.className = 'selector-clearall';

        from_box.setAttribute('name', from_box.getAttribute('name') + '_old');

        // Set up the JavaScript event handlers for the select box filter interface
        addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
        addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
        addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); });
        addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); });
        addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
        SelectBox.init(field_id + '_from');
        SelectBox.init(field_id + '_to');
        // Move selected from_box options to to_box
        SelectBox.move(field_id + '_from', field_id + '_to');
    },
    filter_key_up: function(event, field_id) {
        from = document.getElementById(field_id + '_from');
        // don't submit form if user pressed Enter
        if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
            from.selectedIndex = 0;
            SelectBox.move(field_id + '_from', field_id + '_to');
            from.selectedIndex = 0;
            return false;
        }
        var temp = from.selectedIndex;
        SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
        from.selectedIndex = temp;
        return true;
    },
    filter_key_down: function(event, field_id) {
        from = document.getElementById(field_id + '_from');
        // right arrow -- move across
        if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
            var old_index = from.selectedIndex;
            SelectBox.move(field_id + '_from', field_id + '_to');
            from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index;
            return false;
        }
        // down arrow -- wrap around
        if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) {
            from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
        }
        // up arrow -- wrap around
        if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) {
            from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1;
        }
        return true;
    }
}
<|endoftext|>