From 52457b61047befaaf4502577217cb132c6d28b5d Mon Sep 17 00:00:00 2001 From: Doflatango Date: Tue, 10 Jan 2017 11:03:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=9D=99=E6=80=81=E7=9B=AE?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/handlers.go | 2 + web/ui/index.html | 12 + web/ui/vendors/vue-router.js | 2067 +++++++++ web/ui/vendors/vue.js | 8515 ++++++++++++++++++++++++++++++++++ 4 files changed, 10596 insertions(+) create mode 100644 web/ui/index.html create mode 100644 web/ui/vendors/vue-router.js create mode 100644 web/ui/vendors/vue.js diff --git a/web/handlers.go b/web/handlers.go index 2b16555..430990a 100644 --- a/web/handlers.go +++ b/web/handlers.go @@ -41,6 +41,8 @@ func InitRouters() (s *http.Server, err error) { h = BaseHandler{Handle: nodeLeaveGroup} subrouter.Handle("/node/group", h).Methods("DELETE") + subrouter.Handle("/ui", http.FileServer(http.Dir(conf.Config.Web.UIDir))) + s = &http.Server{ Handler: r, } diff --git a/web/ui/index.html b/web/ui/index.html new file mode 100644 index 0000000..e218de0 --- /dev/null +++ b/web/ui/index.html @@ -0,0 +1,12 @@ + + + + + Cronsun + + + + + + + \ No newline at end of file diff --git a/web/ui/vendors/vue-router.js b/web/ui/vendors/vue-router.js new file mode 100644 index 0000000..a4614e4 --- /dev/null +++ b/web/ui/vendors/vue-router.js @@ -0,0 +1,2067 @@ +/** + * vue-router v2.1.1 + * (c) 2016 Evan You + * @license MIT + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.VueRouter = factory()); +}(this, (function () { 'use strict'; + +var View = { + name: 'router-view', + functional: true, + props: { + name: { + type: String, + default: 'default' + } + }, + render: function render (h, ref) { + var props = ref.props; + var children = ref.children; + var parent = ref.parent; + var data = ref.data; + + data.routerView = true + + var route = parent.$route + var cache = parent._routerViewCache || (parent._routerViewCache = {}) + var depth = 0 + var inactive = false + + while (parent) { + if (parent.$vnode && parent.$vnode.data.routerView) { + depth++ + } + if (parent._inactive) { + inactive = true + } + parent = parent.$parent + } + + data.routerViewDepth = depth + var matched = route.matched[depth] + if (!matched) { + return h() + } + + var name = props.name + var component = inactive + ? cache[name] + : (cache[name] = matched.components[name]) + + if (!inactive) { + var hooks = data.hook || (data.hook = {}) + hooks.init = function (vnode) { + matched.instances[name] = vnode.child + } + hooks.prepatch = function (oldVnode, vnode) { + matched.instances[name] = vnode.child + } + hooks.destroy = function (vnode) { + if (matched.instances[name] === vnode.child) { + matched.instances[name] = undefined + } + } + } + + return h(component, data, children) + } +} + +/* */ + +function assert (condition, message) { + if (!condition) { + throw new Error(("[vue-router] " + message)) + } +} + +function warn (condition, message) { + if (!condition) { + typeof console !== 'undefined' && console.warn(("[vue-router] " + message)) + } +} + +/* */ + +var encode = encodeURIComponent +var decode = decodeURIComponent + +function resolveQuery ( + query, + extraQuery +) { + if ( extraQuery === void 0 ) extraQuery = {}; + + if (query) { + var parsedQuery + try { + parsedQuery = parseQuery(query) + } catch (e) { + "development" !== 'production' && warn(false, e.message) + parsedQuery = {} + } + for (var key in extraQuery) { + parsedQuery[key] = extraQuery[key] + } + return parsedQuery + } else { + return extraQuery + } +} + +function parseQuery (query) { + var res = {} + + query = query.trim().replace(/^(\?|#|&)/, '') + + if (!query) { + return res + } + + query.split('&').forEach(function (param) { + var parts = param.replace(/\+/g, ' ').split('=') + var key = decode(parts.shift()) + var val = parts.length > 0 + ? decode(parts.join('=')) + : null + + if (res[key] === undefined) { + res[key] = val + } else if (Array.isArray(res[key])) { + res[key].push(val) + } else { + res[key] = [res[key], val] + } + }) + + return res +} + +function stringifyQuery (obj) { + var res = obj ? Object.keys(obj).map(function (key) { + var val = obj[key] + + if (val === undefined) { + return '' + } + + if (val === null) { + return encode(key) + } + + if (Array.isArray(val)) { + var result = [] + val.slice().forEach(function (val2) { + if (val2 === undefined) { + return + } + if (val2 === null) { + result.push(encode(key)) + } else { + result.push(encode(key) + '=' + encode(val2)) + } + }) + return result.join('&') + } + + return encode(key) + '=' + encode(val) + }).filter(function (x) { return x.length > 0; }).join('&') : null + return res ? ("?" + res) : '' +} + +/* */ + +function createRoute ( + record, + location, + redirectedFrom +) { + var route = { + name: location.name || (record && record.name), + meta: (record && record.meta) || {}, + path: location.path || '/', + hash: location.hash || '', + query: location.query || {}, + params: location.params || {}, + fullPath: getFullPath(location), + matched: record ? formatMatch(record) : [] + } + if (redirectedFrom) { + route.redirectedFrom = getFullPath(redirectedFrom) + } + return Object.freeze(route) +} + +// the starting route that represents the initial state +var START = createRoute(null, { + path: '/' +}) + +function formatMatch (record) { + var res = [] + while (record) { + res.unshift(record) + record = record.parent + } + return res +} + +function getFullPath (ref) { + var path = ref.path; + var query = ref.query; if ( query === void 0 ) query = {}; + var hash = ref.hash; if ( hash === void 0 ) hash = ''; + + return (path || '/') + stringifyQuery(query) + hash +} + +var trailingSlashRE = /\/$/ +function isSameRoute (a, b) { + if (b === START) { + return a === b + } else if (!b) { + return false + } else if (a.path && b.path) { + return ( + a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') && + a.hash === b.hash && + isObjectEqual(a.query, b.query) + ) + } else if (a.name && b.name) { + return ( + a.name === b.name && + a.hash === b.hash && + isObjectEqual(a.query, b.query) && + isObjectEqual(a.params, b.params) + ) + } else { + return false + } +} + +function isObjectEqual (a, b) { + if ( a === void 0 ) a = {}; + if ( b === void 0 ) b = {}; + + var aKeys = Object.keys(a) + var bKeys = Object.keys(b) + if (aKeys.length !== bKeys.length) { + return false + } + return aKeys.every(function (key) { return String(a[key]) === String(b[key]); }) +} + +function isIncludedRoute (current, target) { + return ( + current.path.indexOf(target.path.replace(/\/$/, '')) === 0 && + (!target.hash || current.hash === target.hash) && + queryIncludes(current.query, target.query) + ) +} + +function queryIncludes (current, target) { + for (var key in target) { + if (!(key in current)) { + return false + } + } + return true +} + +/* */ + +// work around weird flow bug +var toTypes = [String, Object] + +var Link = { + name: 'router-link', + props: { + to: { + type: toTypes, + required: true + }, + tag: { + type: String, + default: 'a' + }, + exact: Boolean, + append: Boolean, + replace: Boolean, + activeClass: String, + event: { + type: [String, Array], + default: 'click' + } + }, + render: function render (h) { + var this$1 = this; + + var router = this.$router + var current = this.$route + var ref = router.resolve(this.to, current, this.append); + var normalizedTo = ref.normalizedTo; + var resolved = ref.resolved; + var href = ref.href; + var classes = {} + var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active' + var compareTarget = normalizedTo.path ? createRoute(null, normalizedTo) : resolved + classes[activeClass] = this.exact + ? isSameRoute(current, compareTarget) + : isIncludedRoute(current, compareTarget) + + var handler = function (e) { + if (guardEvent(e)) { + if (this$1.replace) { + router.replace(normalizedTo) + } else { + router.push(normalizedTo) + } + } + } + + var on = { click: guardEvent } + if (Array.isArray(this.event)) { + this.event.forEach(function (e) { on[e] = handler }) + } else { + on[this.event] = handler + } + + var data = { + class: classes + } + + if (this.tag === 'a') { + data.on = on + data.attrs = { href: href } + } else { + // find the first child and apply listener and href + var a = findAnchor(this.$slots.default) + if (a) { + // in case the is a static node + a.isStatic = false + var extend = _Vue.util.extend + var aData = a.data = extend({}, a.data) + aData.on = on + var aAttrs = a.data.attrs = extend({}, a.data.attrs) + aAttrs.href = href + } else { + // doesn't have child, apply listener to self + data.on = on + } + } + + return h(this.tag, data, this.$slots.default) + } +} + +function guardEvent (e) { + // don't redirect with control keys + /* istanbul ignore if */ + if (e.metaKey || e.ctrlKey || e.shiftKey) { return } + // don't redirect when preventDefault called + /* istanbul ignore if */ + if (e.defaultPrevented) { return } + // don't redirect on right click + /* istanbul ignore if */ + if (e.button !== 0) { return } + // don't redirect if `target="_blank"` + /* istanbul ignore if */ + var target = e.target.getAttribute('target') + if (/\b_blank\b/i.test(target)) { return } + + e.preventDefault() + return true +} + +function findAnchor (children) { + if (children) { + var child + for (var i = 0; i < children.length; i++) { + child = children[i] + if (child.tag === 'a') { + return child + } + if (child.children && (child = findAnchor(child.children))) { + return child + } + } + } +} + +var _Vue + +function install (Vue) { + if (install.installed) { return } + install.installed = true + + _Vue = Vue + + Object.defineProperty(Vue.prototype, '$router', { + get: function get () { return this.$root._router } + }) + + Object.defineProperty(Vue.prototype, '$route', { + get: function get$1 () { return this.$root._route } + }) + + Vue.mixin({ + beforeCreate: function beforeCreate () { + if (this.$options.router) { + this._router = this.$options.router + this._router.init(this) + Vue.util.defineReactive(this, '_route', this._router.history.current) + } + } + }) + + Vue.component('router-view', View) + Vue.component('router-link', Link) + + var strats = Vue.config.optionMergeStrategies + // use the same hook merging strategy for route hooks + strats.beforeRouteEnter = strats.beforeRouteLeave = strats.created +} + +/* */ + +function resolvePath ( + relative, + base, + append +) { + if (relative.charAt(0) === '/') { + return relative + } + + if (relative.charAt(0) === '?' || relative.charAt(0) === '#') { + return base + relative + } + + var stack = base.split('/') + + // remove trailing segment if: + // - not appending + // - appending to trailing slash (last segment is empty) + if (!append || !stack[stack.length - 1]) { + stack.pop() + } + + // resolve relative path + var segments = relative.replace(/^\//, '').split('/') + for (var i = 0; i < segments.length; i++) { + var segment = segments[i] + if (segment === '.') { + continue + } else if (segment === '..') { + stack.pop() + } else { + stack.push(segment) + } + } + + // ensure leading slash + if (stack[0] !== '') { + stack.unshift('') + } + + return stack.join('/') +} + +function parsePath (path) { + var hash = '' + var query = '' + + var hashIndex = path.indexOf('#') + if (hashIndex >= 0) { + hash = path.slice(hashIndex) + path = path.slice(0, hashIndex) + } + + var queryIndex = path.indexOf('?') + if (queryIndex >= 0) { + query = path.slice(queryIndex + 1) + path = path.slice(0, queryIndex) + } + + return { + path: path, + query: query, + hash: hash + } +} + +function cleanPath (path) { + return path.replace(/\/\//g, '/') +} + +/* */ + +function createRouteMap (routes) { + var pathMap = Object.create(null) + var nameMap = Object.create(null) + + routes.forEach(function (route) { + addRouteRecord(pathMap, nameMap, route) + }) + + return { + pathMap: pathMap, + nameMap: nameMap + } +} + +function addRouteRecord ( + pathMap, + nameMap, + route, + parent, + matchAs +) { + var path = route.path; + var name = route.name; + if ("development" !== 'production') { + assert(path != null, "\"path\" is required in a route configuration.") + assert( + typeof route.component !== 'string', + "route config \"component\" for path: " + (String(path || name)) + " cannot be a " + + "string id. Use an actual component instead." + ) + } + + var record = { + path: normalizePath(path, parent), + components: route.components || { default: route.component }, + instances: {}, + name: name, + parent: parent, + matchAs: matchAs, + redirect: route.redirect, + beforeEnter: route.beforeEnter, + meta: route.meta || {} + } + + if (route.children) { + // Warn if route is named and has a default child route. + // If users navigate to this route by name, the default child will + // not be rendered (GH Issue #629) + if ("development" !== 'production') { + if (route.name && route.children.some(function (child) { return /^\/?$/.test(child.path); })) { + warn(false, ("Named Route '" + (route.name) + "' has a default child route.\n When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), the default child route will not be rendered.\n Remove the name from this route and use the name of the default child route for named links instead.") + ) + } + } + route.children.forEach(function (child) { + addRouteRecord(pathMap, nameMap, child, record) + }) + } + + if (route.alias !== undefined) { + if (Array.isArray(route.alias)) { + route.alias.forEach(function (alias) { + addRouteRecord(pathMap, nameMap, { path: alias }, parent, record.path) + }) + } else { + addRouteRecord(pathMap, nameMap, { path: route.alias }, parent, record.path) + } + } + + if (!pathMap[record.path]) { + pathMap[record.path] = record + } + if (name) { + if (!nameMap[name]) { + nameMap[name] = record + } else if ("development" !== 'production') { + warn(false, ("Duplicate named routes definition: { name: \"" + name + "\", path: \"" + (record.path) + "\" }")) + } + } +} + +function normalizePath (path, parent) { + path = path.replace(/\/$/, '') + if (path[0] === '/') { return path } + if (parent == null) { return path } + return cleanPath(((parent.path) + "/" + path)) +} + +var __moduleExports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; +}; + +var isarray = __moduleExports + +/** + * Expose `pathToRegexp`. + */ +var index = pathToRegexp +var parse_1 = parse +var compile_1 = compile +var tokensToFunction_1 = tokensToFunction +var tokensToRegExp_1 = tokensToRegExp + +/** + * The main path matching regexp utility. + * + * @type {RegExp} + */ +var PATH_REGEXP = new RegExp([ + // Match escaped characters that would otherwise appear in future matches. + // This allows the user to escape special characters that won't transform. + '(\\\\.)', + // Match Express-style parameters and un-named parameters with a prefix + // and optional suffixes. Matches appear as: + // + // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined] + // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined] + // "/*" => ["/", undefined, undefined, undefined, undefined, "*"] + '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))' +].join('|'), 'g') + +/** + * Parse a string for the raw tokens. + * + * @param {string} str + * @param {Object=} options + * @return {!Array} + */ +function parse (str, options) { + var tokens = [] + var key = 0 + var index = 0 + var path = '' + var defaultDelimiter = options && options.delimiter || '/' + var res + + while ((res = PATH_REGEXP.exec(str)) != null) { + var m = res[0] + var escaped = res[1] + var offset = res.index + path += str.slice(index, offset) + index = offset + m.length + + // Ignore already escaped sequences. + if (escaped) { + path += escaped[1] + continue + } + + var next = str[index] + var prefix = res[2] + var name = res[3] + var capture = res[4] + var group = res[5] + var modifier = res[6] + var asterisk = res[7] + + // Push the current path onto the tokens. + if (path) { + tokens.push(path) + path = '' + } + + var partial = prefix != null && next != null && next !== prefix + var repeat = modifier === '+' || modifier === '*' + var optional = modifier === '?' || modifier === '*' + var delimiter = res[2] || defaultDelimiter + var pattern = capture || group + + tokens.push({ + name: name || key++, + prefix: prefix || '', + delimiter: delimiter, + optional: optional, + repeat: repeat, + partial: partial, + asterisk: !!asterisk, + pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?') + }) + } + + // Match any characters still remaining. + if (index < str.length) { + path += str.substr(index) + } + + // If the path exists, push it onto the end. + if (path) { + tokens.push(path) + } + + return tokens +} + +/** + * Compile a string to a template function for the path. + * + * @param {string} str + * @param {Object=} options + * @return {!function(Object=, Object=)} + */ +function compile (str, options) { + return tokensToFunction(parse(str, options)) +} + +/** + * Prettier encoding of URI path segments. + * + * @param {string} + * @return {string} + */ +function encodeURIComponentPretty (str) { + return encodeURI(str).replace(/[\/?#]/g, function (c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase() + }) +} + +/** + * Encode the asterisk parameter. Similar to `pretty`, but allows slashes. + * + * @param {string} + * @return {string} + */ +function encodeAsterisk (str) { + return encodeURI(str).replace(/[?#]/g, function (c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase() + }) +} + +/** + * Expose a method for transforming tokens into the path function. + */ +function tokensToFunction (tokens) { + // Compile all the tokens into regexps. + var matches = new Array(tokens.length) + + // Compile all the patterns before compilation. + for (var i = 0; i < tokens.length; i++) { + if (typeof tokens[i] === 'object') { + matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$') + } + } + + return function (obj, opts) { + var path = '' + var data = obj || {} + var options = opts || {} + var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent + + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i] + + if (typeof token === 'string') { + path += token + + continue + } + + var value = data[token.name] + var segment + + if (value == null) { + if (token.optional) { + // Prepend partial segment prefixes. + if (token.partial) { + path += token.prefix + } + + continue + } else { + throw new TypeError('Expected "' + token.name + '" to be defined') + } + } + + if (isarray(value)) { + if (!token.repeat) { + throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`') + } + + if (value.length === 0) { + if (token.optional) { + continue + } else { + throw new TypeError('Expected "' + token.name + '" to not be empty') + } + } + + for (var j = 0; j < value.length; j++) { + segment = encode(value[j]) + + if (!matches[i].test(segment)) { + throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`') + } + + path += (j === 0 ? token.prefix : token.delimiter) + segment + } + + continue + } + + segment = token.asterisk ? encodeAsterisk(value) : encode(value) + + if (!matches[i].test(segment)) { + throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"') + } + + path += token.prefix + segment + } + + return path + } +} + +/** + * Escape a regular expression string. + * + * @param {string} str + * @return {string} + */ +function escapeString (str) { + return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1') +} + +/** + * Escape the capturing group by escaping special characters and meaning. + * + * @param {string} group + * @return {string} + */ +function escapeGroup (group) { + return group.replace(/([=!:$\/()])/g, '\\$1') +} + +/** + * Attach the keys as a property of the regexp. + * + * @param {!RegExp} re + * @param {Array} keys + * @return {!RegExp} + */ +function attachKeys (re, keys) { + re.keys = keys + return re +} + +/** + * Get the flags for a regexp from the options. + * + * @param {Object} options + * @return {string} + */ +function flags (options) { + return options.sensitive ? '' : 'i' +} + +/** + * Pull out keys from a regexp. + * + * @param {!RegExp} path + * @param {!Array} keys + * @return {!RegExp} + */ +function regexpToRegexp (path, keys) { + // Use a negative lookahead to match only capturing groups. + var groups = path.source.match(/\((?!\?)/g) + + if (groups) { + for (var i = 0; i < groups.length; i++) { + keys.push({ + name: i, + prefix: null, + delimiter: null, + optional: false, + repeat: false, + partial: false, + asterisk: false, + pattern: null + }) + } + } + + return attachKeys(path, keys) +} + +/** + * Transform an array into a regexp. + * + * @param {!Array} path + * @param {Array} keys + * @param {!Object} options + * @return {!RegExp} + */ +function arrayToRegexp (path, keys, options) { + var parts = [] + + for (var i = 0; i < path.length; i++) { + parts.push(pathToRegexp(path[i], keys, options).source) + } + + var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options)) + + return attachKeys(regexp, keys) +} + +/** + * Create a path regexp from string input. + * + * @param {string} path + * @param {!Array} keys + * @param {!Object} options + * @return {!RegExp} + */ +function stringToRegexp (path, keys, options) { + return tokensToRegExp(parse(path, options), keys, options) +} + +/** + * Expose a function for taking tokens and returning a RegExp. + * + * @param {!Array} tokens + * @param {(Array|Object)=} keys + * @param {Object=} options + * @return {!RegExp} + */ +function tokensToRegExp (tokens, keys, options) { + if (!isarray(keys)) { + options = /** @type {!Object} */ (keys || options) + keys = [] + } + + options = options || {} + + var strict = options.strict + var end = options.end !== false + var route = '' + + // Iterate over the tokens and create our regexp string. + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i] + + if (typeof token === 'string') { + route += escapeString(token) + } else { + var prefix = escapeString(token.prefix) + var capture = '(?:' + token.pattern + ')' + + keys.push(token) + + if (token.repeat) { + capture += '(?:' + prefix + capture + ')*' + } + + if (token.optional) { + if (!token.partial) { + capture = '(?:' + prefix + '(' + capture + '))?' + } else { + capture = prefix + '(' + capture + ')?' + } + } else { + capture = prefix + '(' + capture + ')' + } + + route += capture + } + } + + var delimiter = escapeString(options.delimiter || '/') + var endsWithDelimiter = route.slice(-delimiter.length) === delimiter + + // In non-strict mode we allow a slash at the end of match. If the path to + // match already ends with a slash, we remove it for consistency. The slash + // is valid at the end of a path match, not in the middle. This is important + // in non-ending mode, where "/test/" shouldn't match "/test//route". + if (!strict) { + route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?' + } + + if (end) { + route += '$' + } else { + // In non-ending mode, we need the capturing groups to match as much as + // possible by using a positive lookahead to the end or next path segment. + route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)' + } + + return attachKeys(new RegExp('^' + route, flags(options)), keys) +} + +/** + * Normalize the given path string, returning a regular expression. + * + * An empty array can be passed in for the keys, which will hold the + * placeholder key descriptions. For example, using `/user/:id`, `keys` will + * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`. + * + * @param {(string|RegExp|Array)} path + * @param {(Array|Object)=} keys + * @param {Object=} options + * @return {!RegExp} + */ +function pathToRegexp (path, keys, options) { + if (!isarray(keys)) { + options = /** @type {!Object} */ (keys || options) + keys = [] + } + + options = options || {} + + if (path instanceof RegExp) { + return regexpToRegexp(path, /** @type {!Array} */ (keys)) + } + + if (isarray(path)) { + return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options) + } + + return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options) +} + +index.parse = parse_1; +index.compile = compile_1; +index.tokensToFunction = tokensToFunction_1; +index.tokensToRegExp = tokensToRegExp_1; + +/* */ + +var regexpCache = Object.create(null) + +function getRouteRegex (path) { + var hit = regexpCache[path] + var keys, regexp + + if (hit) { + keys = hit.keys + regexp = hit.regexp + } else { + keys = [] + regexp = index(path, keys) + regexpCache[path] = { keys: keys, regexp: regexp } + } + + return { keys: keys, regexp: regexp } +} + +var regexpCompileCache = Object.create(null) + +function fillParams ( + path, + params, + routeMsg +) { + try { + var filler = + regexpCompileCache[path] || + (regexpCompileCache[path] = index.compile(path)) + return filler(params || {}, { pretty: true }) + } catch (e) { + if ("development" !== 'production') { + warn(false, ("missing param for " + routeMsg + ": " + (e.message))) + } + return '' + } +} + +/* */ + +function normalizeLocation ( + raw, + current, + append +) { + var next = typeof raw === 'string' ? { path: raw } : raw + // named target + if (next.name || next._normalized) { + return next + } + + // relative params + if (!next.path && next.params && current) { + next = assign({}, next) + next._normalized = true + var params = assign(assign({}, current.params), next.params) + if (current.name) { + next.name = current.name + next.params = params + } else if (current.matched) { + var rawPath = current.matched[current.matched.length - 1].path + next.path = fillParams(rawPath, params, ("path " + (current.path))) + } else if ("development" !== 'production') { + warn(false, "relative params navigation requires a current route.") + } + return next + } + + var parsedPath = parsePath(next.path || '') + var basePath = (current && current.path) || '/' + var path = parsedPath.path + ? resolvePath(parsedPath.path, basePath, append || next.append) + : (current && current.path) || '/' + var query = resolveQuery(parsedPath.query, next.query) + var hash = next.hash || parsedPath.hash + if (hash && hash.charAt(0) !== '#') { + hash = "#" + hash + } + + return { + _normalized: true, + path: path, + query: query, + hash: hash + } +} + +function assign (a, b) { + for (var key in b) { + a[key] = b[key] + } + return a +} + +/* */ + +function createMatcher (routes) { + var ref = createRouteMap(routes); + var pathMap = ref.pathMap; + var nameMap = ref.nameMap; + + function match ( + raw, + currentRoute, + redirectedFrom + ) { + var location = normalizeLocation(raw, currentRoute) + var name = location.name; + + if (name) { + var record = nameMap[name] + var paramNames = getRouteRegex(record.path).keys + .filter(function (key) { return !key.optional; }) + .map(function (key) { return key.name; }) + + if (typeof location.params !== 'object') { + location.params = {} + } + + if (currentRoute && typeof currentRoute.params === 'object') { + for (var key in currentRoute.params) { + if (!(key in location.params) && paramNames.indexOf(key) > -1) { + location.params[key] = currentRoute.params[key] + } + } + } + + if (record) { + location.path = fillParams(record.path, location.params, ("named route \"" + name + "\"")) + return _createRoute(record, location, redirectedFrom) + } + } else if (location.path) { + location.params = {} + for (var path in pathMap) { + if (matchRoute(path, location.params, location.path)) { + return _createRoute(pathMap[path], location, redirectedFrom) + } + } + } + // no match + return _createRoute(null, location) + } + + function redirect ( + record, + location + ) { + var originalRedirect = record.redirect + var redirect = typeof originalRedirect === 'function' + ? originalRedirect(createRoute(record, location)) + : originalRedirect + + if (typeof redirect === 'string') { + redirect = { path: redirect } + } + + if (!redirect || typeof redirect !== 'object') { + "development" !== 'production' && warn( + false, ("invalid redirect option: " + (JSON.stringify(redirect))) + ) + return _createRoute(null, location) + } + + var re = redirect + var name = re.name; + var path = re.path; + var query = location.query; + var hash = location.hash; + var params = location.params; + query = re.hasOwnProperty('query') ? re.query : query + hash = re.hasOwnProperty('hash') ? re.hash : hash + params = re.hasOwnProperty('params') ? re.params : params + + if (name) { + // resolved named direct + var targetRecord = nameMap[name] + if ("development" !== 'production') { + assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found.")) + } + return match({ + _normalized: true, + name: name, + query: query, + hash: hash, + params: params + }, undefined, location) + } else if (path) { + // 1. resolve relative redirect + var rawPath = resolveRecordPath(path, record) + // 2. resolve params + var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\"")) + // 3. rematch with existing query and hash + return match({ + _normalized: true, + path: resolvedPath, + query: query, + hash: hash + }, undefined, location) + } else { + warn(false, ("invalid redirect option: " + (JSON.stringify(redirect)))) + return _createRoute(null, location) + } + } + + function alias ( + record, + location, + matchAs + ) { + var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\"")) + var aliasedMatch = match({ + _normalized: true, + path: aliasedPath + }) + if (aliasedMatch) { + var matched = aliasedMatch.matched + var aliasedRecord = matched[matched.length - 1] + location.params = aliasedMatch.params + return _createRoute(aliasedRecord, location) + } + return _createRoute(null, location) + } + + function _createRoute ( + record, + location, + redirectedFrom + ) { + if (record && record.redirect) { + return redirect(record, redirectedFrom || location) + } + if (record && record.matchAs) { + return alias(record, location, record.matchAs) + } + return createRoute(record, location, redirectedFrom) + } + + return match +} + +function matchRoute ( + path, + params, + pathname +) { + var ref = getRouteRegex(path); + var regexp = ref.regexp; + var keys = ref.keys; + var m = pathname.match(regexp) + + if (!m) { + return false + } else if (!params) { + return true + } + + for (var i = 1, len = m.length; i < len; ++i) { + var key = keys[i - 1] + var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i] + if (key) { params[key.name] = val } + } + + return true +} + +function resolveRecordPath (path, record) { + return resolvePath(path, record.parent ? record.parent.path : '/', true) +} + +/* */ + +var inBrowser = typeof window !== 'undefined' + +var supportsHistory = inBrowser && (function () { + var ua = window.navigator.userAgent + + if ( + (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && + ua.indexOf('Mobile Safari') !== -1 && + ua.indexOf('Chrome') === -1 && + ua.indexOf('Windows Phone') === -1 + ) { + return false + } + + return window.history && 'pushState' in window.history +})() + +/* */ + +function runQueue (queue, fn, cb) { + var step = function (index) { + if (index >= queue.length) { + cb() + } else { + if (queue[index]) { + fn(queue[index], function () { + step(index + 1) + }) + } else { + step(index + 1) + } + } + } + step(0) +} + +/* */ + + +var History = function History (router, base) { + this.router = router + this.base = normalizeBase(base) + // start with a route object that stands for "nowhere" + this.current = START + this.pending = null +}; + +History.prototype.listen = function listen (cb) { + this.cb = cb +}; + +History.prototype.transitionTo = function transitionTo (location, onComplete, onAbort) { + var this$1 = this; + + var route = this.router.match(location, this.current) + this.confirmTransition(route, function () { + this$1.updateRoute(route) + onComplete && onComplete(route) + this$1.ensureURL() + }, onAbort) +}; + +History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) { + var this$1 = this; + + var current = this.current + var abort = function () { onAbort && onAbort() } + if (isSameRoute(route, current)) { + this.ensureURL() + return abort() + } + + var ref = resolveQueue(this.current.matched, route.matched); + var deactivated = ref.deactivated; + var activated = ref.activated; + + var queue = [].concat( + // in-component leave guards + extractLeaveGuards(deactivated), + // global before hooks + this.router.beforeHooks, + // enter guards + activated.map(function (m) { return m.beforeEnter; }), + // async components + resolveAsyncComponents(activated) + ) + + this.pending = route + var iterator = function (hook, next) { + if (this$1.pending !== route) { + return abort() + } + hook(route, current, function (to) { + if (to === false) { + // next(false) -> abort navigation, ensure current URL + this$1.ensureURL(true) + abort() + } else if (typeof to === 'string' || typeof to === 'object') { + // next('/') or next({ path: '/' }) -> redirect + (typeof to === 'object' && to.replace) ? this$1.replace(to) : this$1.push(to) + abort() + } else { + // confirm transition and pass on the value + next(to) + } + }) + } + + runQueue(queue, iterator, function () { + var postEnterCbs = [] + var enterGuards = extractEnterGuards(activated, postEnterCbs, function () { + return this$1.current === route + }) + // wait until async components are resolved before + // extracting in-component enter guards + runQueue(enterGuards, iterator, function () { + if (this$1.pending !== route) { + return abort() + } + this$1.pending = null + onComplete(route) + if (this$1.router.app) { + this$1.router.app.$nextTick(function () { + postEnterCbs.forEach(function (cb) { return cb(); }) + }) + } + }) + }) +}; + +History.prototype.updateRoute = function updateRoute (route) { + var prev = this.current + this.current = route + this.cb && this.cb(route) + this.router.afterHooks.forEach(function (hook) { + hook && hook(route, prev) + }) +}; + +function normalizeBase (base) { + if (!base) { + if (inBrowser) { + // respect tag + var baseEl = document.querySelector('base') + base = baseEl ? baseEl.getAttribute('href') : '/' + } else { + base = '/' + } + } + // make sure there's the starting slash + if (base.charAt(0) !== '/') { + base = '/' + base + } + // remove trailing slash + return base.replace(/\/$/, '') +} + +function resolveQueue ( + current, + next +) { + var i + var max = Math.max(current.length, next.length) + for (i = 0; i < max; i++) { + if (current[i] !== next[i]) { + break + } + } + return { + activated: next.slice(i), + deactivated: current.slice(i) + } +} + +function extractGuard ( + def, + key +) { + if (typeof def !== 'function') { + // extend now so that global mixins are applied. + def = _Vue.extend(def) + } + return def.options[key] +} + +function extractLeaveGuards (matched) { + return flatten(flatMapComponents(matched, function (def, instance) { + var guard = extractGuard(def, 'beforeRouteLeave') + if (guard) { + return Array.isArray(guard) + ? guard.map(function (guard) { return wrapLeaveGuard(guard, instance); }) + : wrapLeaveGuard(guard, instance) + } + }).reverse()) +} + +function wrapLeaveGuard ( + guard, + instance +) { + return function routeLeaveGuard () { + return guard.apply(instance, arguments) + } +} + +function extractEnterGuards ( + matched, + cbs, + isValid +) { + return flatten(flatMapComponents(matched, function (def, _, match, key) { + var guard = extractGuard(def, 'beforeRouteEnter') + if (guard) { + return Array.isArray(guard) + ? guard.map(function (guard) { return wrapEnterGuard(guard, cbs, match, key, isValid); }) + : wrapEnterGuard(guard, cbs, match, key, isValid) + } + })) +} + +function wrapEnterGuard ( + guard, + cbs, + match, + key, + isValid +) { + return function routeEnterGuard (to, from, next) { + return guard(to, from, function (cb) { + next(cb) + if (typeof cb === 'function') { + cbs.push(function () { + // #750 + // if a router-view is wrapped with an out-in transition, + // the instance may not have been registered at this time. + // we will need to poll for registration until current route + // is no longer valid. + poll(cb, match.instances, key, isValid) + }) + } + }) + } +} + +function poll ( + cb, // somehow flow cannot infer this is a function + instances, + key, + isValid +) { + if (instances[key]) { + cb(instances[key]) + } else if (isValid()) { + setTimeout(function () { + poll(cb, instances, key, isValid) + }, 16) + } +} + +function resolveAsyncComponents (matched) { + return flatMapComponents(matched, function (def, _, match, key) { + // if it's a function and doesn't have Vue options attached, + // assume it's an async component resolve function. + // we are not using Vue's default async resolving mechanism because + // we want to halt the navigation until the incoming component has been + // resolved. + if (typeof def === 'function' && !def.options) { + return function (to, from, next) { + var resolve = function (resolvedDef) { + match.components[key] = resolvedDef + next() + } + + var reject = function (reason) { + warn(false, ("Failed to resolve async component " + key + ": " + reason)) + next(false) + } + + var res = def(resolve, reject) + if (res && typeof res.then === 'function') { + res.then(resolve, reject) + } + } + } + }) +} + +function flatMapComponents ( + matched, + fn +) { + return flatten(matched.map(function (m) { + return Object.keys(m.components).map(function (key) { return fn( + m.components[key], + m.instances[key], + m, key + ); }) + })) +} + +function flatten (arr) { + return Array.prototype.concat.apply([], arr) +} + +/* */ + +var positionStore = Object.create(null) + +function saveScrollPosition (key) { + if (!key) { return } + positionStore[key] = { + x: window.pageXOffset, + y: window.pageYOffset + } +} + +function getScrollPosition (key) { + if (!key) { return } + return positionStore[key] +} + +function getElementPosition (el) { + var docRect = document.documentElement.getBoundingClientRect() + var elRect = el.getBoundingClientRect() + return { + x: elRect.left - docRect.left, + y: elRect.top - docRect.top + } +} + +function isValidPosition (obj) { + return isNumber(obj.x) || isNumber(obj.y) +} + +function normalizePosition (obj) { + return { + x: isNumber(obj.x) ? obj.x : window.pageXOffset, + y: isNumber(obj.y) ? obj.y : window.pageYOffset + } +} + +function isNumber (v) { + return typeof v === 'number' +} + +/* */ + + +var genKey = function () { return String(Date.now()); } +var _key = genKey() + +var HTML5History = (function (History) { + function HTML5History (router, base) { + var this$1 = this; + + History.call(this, router, base) + + var expectScroll = router.options.scrollBehavior + window.addEventListener('popstate', function (e) { + _key = e.state && e.state.key + var current = this$1.current + this$1.transitionTo(getLocation(this$1.base), function (next) { + if (expectScroll) { + this$1.handleScroll(next, current, true) + } + }) + }) + + if (expectScroll) { + window.addEventListener('scroll', function () { + saveScrollPosition(_key) + }) + } + } + + if ( History ) HTML5History.__proto__ = History; + HTML5History.prototype = Object.create( History && History.prototype ); + HTML5History.prototype.constructor = HTML5History; + + HTML5History.prototype.go = function go (n) { + window.history.go(n) + }; + + HTML5History.prototype.push = function push (location) { + var this$1 = this; + + var current = this.current + this.transitionTo(location, function (route) { + pushState(cleanPath(this$1.base + route.fullPath)) + this$1.handleScroll(route, current, false) + }) + }; + + HTML5History.prototype.replace = function replace (location) { + var this$1 = this; + + var current = this.current + this.transitionTo(location, function (route) { + replaceState(cleanPath(this$1.base + route.fullPath)) + this$1.handleScroll(route, current, false) + }) + }; + + HTML5History.prototype.ensureURL = function ensureURL (push) { + if (getLocation(this.base) !== this.current.fullPath) { + var current = cleanPath(this.base + this.current.fullPath) + push ? pushState(current) : replaceState(current) + } + }; + + HTML5History.prototype.handleScroll = function handleScroll (to, from, isPop) { + var router = this.router + if (!router.app) { + return + } + + var behavior = router.options.scrollBehavior + if (!behavior) { + return + } + if ("development" !== 'production') { + assert(typeof behavior === 'function', "scrollBehavior must be a function") + } + + // wait until re-render finishes before scrolling + router.app.$nextTick(function () { + var position = getScrollPosition(_key) + var shouldScroll = behavior(to, from, isPop ? position : null) + if (!shouldScroll) { + return + } + var isObject = typeof shouldScroll === 'object' + if (isObject && typeof shouldScroll.selector === 'string') { + var el = document.querySelector(shouldScroll.selector) + if (el) { + position = getElementPosition(el) + } else if (isValidPosition(shouldScroll)) { + position = normalizePosition(shouldScroll) + } + } else if (isObject && isValidPosition(shouldScroll)) { + position = normalizePosition(shouldScroll) + } + + if (position) { + window.scrollTo(position.x, position.y) + } + }) + }; + + return HTML5History; +}(History)); + +function getLocation (base) { + var path = window.location.pathname + if (base && path.indexOf(base) === 0) { + path = path.slice(base.length) + } + return (path || '/') + window.location.search + window.location.hash +} + +function pushState (url, replace) { + // try...catch the pushState call to get around Safari + // DOM Exception 18 where it limits to 100 pushState calls + var history = window.history + try { + if (replace) { + history.replaceState({ key: _key }, '', url) + } else { + _key = genKey() + history.pushState({ key: _key }, '', url) + } + saveScrollPosition(_key) + } catch (e) { + window.location[replace ? 'assign' : 'replace'](url) + } +} + +function replaceState (url) { + pushState(url, true) +} + +/* */ + + +var HashHistory = (function (History) { + function HashHistory (router, base, fallback) { + History.call(this, router, base) + // check history fallback deeplinking + if (fallback && this.checkFallback()) { + return + } + ensureSlash() + } + + if ( History ) HashHistory.__proto__ = History; + HashHistory.prototype = Object.create( History && History.prototype ); + HashHistory.prototype.constructor = HashHistory; + + HashHistory.prototype.checkFallback = function checkFallback () { + var location = getLocation(this.base) + if (!/^\/#/.test(location)) { + window.location.replace( + cleanPath(this.base + '/#' + location) + ) + return true + } + }; + + HashHistory.prototype.onHashChange = function onHashChange () { + if (!ensureSlash()) { + return + } + this.transitionTo(getHash(), function (route) { + replaceHash(route.fullPath) + }) + }; + + HashHistory.prototype.push = function push (location) { + this.transitionTo(location, function (route) { + pushHash(route.fullPath) + }) + }; + + HashHistory.prototype.replace = function replace (location) { + this.transitionTo(location, function (route) { + replaceHash(route.fullPath) + }) + }; + + HashHistory.prototype.go = function go (n) { + window.history.go(n) + }; + + HashHistory.prototype.ensureURL = function ensureURL (push) { + var current = this.current.fullPath + if (getHash() !== current) { + push ? pushHash(current) : replaceHash(current) + } + }; + + return HashHistory; +}(History)); + +function ensureSlash () { + var path = getHash() + if (path.charAt(0) === '/') { + return true + } + replaceHash('/' + path) + return false +} + +function getHash () { + // We can't use window.location.hash here because it's not + // consistent across browsers - Firefox will pre-decode it! + var href = window.location.href + var index = href.indexOf('#') + return index === -1 ? '' : href.slice(index + 1) +} + +function pushHash (path) { + window.location.hash = path +} + +function replaceHash (path) { + var i = window.location.href.indexOf('#') + window.location.replace( + window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path + ) +} + +/* */ + + +var AbstractHistory = (function (History) { + function AbstractHistory (router) { + History.call(this, router) + this.stack = [] + this.index = -1 + } + + if ( History ) AbstractHistory.__proto__ = History; + AbstractHistory.prototype = Object.create( History && History.prototype ); + AbstractHistory.prototype.constructor = AbstractHistory; + + AbstractHistory.prototype.push = function push (location) { + var this$1 = this; + + this.transitionTo(location, function (route) { + this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route) + this$1.index++ + }) + }; + + AbstractHistory.prototype.replace = function replace (location) { + var this$1 = this; + + this.transitionTo(location, function (route) { + this$1.stack = this$1.stack.slice(0, this$1.index).concat(route) + }) + }; + + AbstractHistory.prototype.go = function go (n) { + var this$1 = this; + + var targetIndex = this.index + n + if (targetIndex < 0 || targetIndex >= this.stack.length) { + return + } + var route = this.stack[targetIndex] + this.confirmTransition(route, function () { + this$1.index = targetIndex + this$1.updateRoute(route) + }) + }; + + AbstractHistory.prototype.ensureURL = function ensureURL () { + // noop + }; + + return AbstractHistory; +}(History)); + +/* */ + +var VueRouter = function VueRouter (options) { + if ( options === void 0 ) options = {}; + + this.app = null + this.options = options + this.beforeHooks = [] + this.afterHooks = [] + this.match = createMatcher(options.routes || []) + + var mode = options.mode || 'hash' + this.fallback = mode === 'history' && !supportsHistory + if (this.fallback) { + mode = 'hash' + } + if (!inBrowser) { + mode = 'abstract' + } + this.mode = mode + + switch (mode) { + case 'history': + this.history = new HTML5History(this, options.base) + break + case 'hash': + this.history = new HashHistory(this, options.base, this.fallback) + break + case 'abstract': + this.history = new AbstractHistory(this) + break + default: + "development" !== 'production' && assert(false, ("invalid mode: " + mode)) + } +}; + +var prototypeAccessors = { currentRoute: {} }; + +prototypeAccessors.currentRoute.get = function () { + return this.history && this.history.current +}; + +VueRouter.prototype.init = function init (app /* Vue component instance */) { + var this$1 = this; + + "development" !== 'production' && assert( + install.installed, + "not installed. Make sure to call `Vue.use(VueRouter)` " + + "before creating root instance." + ) + + this.app = app + + var history = this.history + + if (history instanceof HTML5History) { + history.transitionTo(getLocation(history.base)) + } else if (history instanceof HashHistory) { + var setupHashListener = function () { + window.addEventListener('hashchange', function () { + history.onHashChange() + }) + } + history.transitionTo(getHash(), setupHashListener, setupHashListener) + } + + history.listen(function (route) { + this$1.app._route = route + }) +}; + +VueRouter.prototype.beforeEach = function beforeEach (fn) { + this.beforeHooks.push(fn) +}; + +VueRouter.prototype.afterEach = function afterEach (fn) { + this.afterHooks.push(fn) +}; + +VueRouter.prototype.push = function push (location) { + this.history.push(location) +}; + +VueRouter.prototype.replace = function replace (location) { + this.history.replace(location) +}; + +VueRouter.prototype.go = function go (n) { + this.history.go(n) +}; + +VueRouter.prototype.back = function back () { + this.go(-1) +}; + +VueRouter.prototype.forward = function forward () { + this.go(1) +}; + +VueRouter.prototype.getMatchedComponents = function getMatchedComponents (to) { + var route = to + ? this.resolve(to).resolved + : this.currentRoute + if (!route) { + return [] + } + return [].concat.apply([], route.matched.map(function (m) { + return Object.keys(m.components).map(function (key) { + return m.components[key] + }) + })) +}; + +VueRouter.prototype.resolve = function resolve ( + to, + current, + append +) { + var normalizedTo = normalizeLocation(to, current || this.history.current, append) + var resolved = this.match(normalizedTo, current) + var fullPath = resolved.redirectedFrom || resolved.fullPath + var base = this.history.base + var href = createHref(base, fullPath, this.mode) + return { + normalizedTo: normalizedTo, + resolved: resolved, + href: href + } +}; + +Object.defineProperties( VueRouter.prototype, prototypeAccessors ); + +function createHref (base, fullPath, mode) { + var path = mode === 'hash' ? '#' + fullPath : fullPath + return base ? cleanPath(base + '/' + path) : path +} + +VueRouter.install = install + +if (inBrowser && window.Vue) { + window.Vue.use(VueRouter) +} + +return VueRouter; + +}))); \ No newline at end of file diff --git a/web/ui/vendors/vue.js b/web/ui/vendors/vue.js new file mode 100644 index 0000000..bf46849 --- /dev/null +++ b/web/ui/vendors/vue.js @@ -0,0 +1,8515 @@ +/*! + * Vue.js v2.1.8 + * (c) 2014-2016 Evan You + * Released under the MIT License. + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.Vue = factory()); +}(this, (function () { 'use strict'; + +/* */ + +/** + * Convert a value to a string that is actually rendered. + */ +function _toString (val) { + return val == null + ? '' + : typeof val === 'object' + ? JSON.stringify(val, null, 2) + : String(val) +} + +/** + * Convert a input value to a number for persistence. + * If the conversion fails, return original string. + */ +function toNumber (val) { + var n = parseFloat(val, 10); + return (n || n === 0) ? n : val +} + +/** + * Make a map and return a function for checking if a key + * is in that map. + */ +function makeMap ( + str, + expectsLowerCase +) { + var map = Object.create(null); + var list = str.split(','); + for (var i = 0; i < list.length; i++) { + map[list[i]] = true; + } + return expectsLowerCase + ? function (val) { return map[val.toLowerCase()]; } + : function (val) { return map[val]; } +} + +/** + * Check if a tag is a built-in tag. + */ +var isBuiltInTag = makeMap('slot,component', true); + +/** + * Remove an item from an array + */ +function remove$1 (arr, item) { + if (arr.length) { + var index = arr.indexOf(item); + if (index > -1) { + return arr.splice(index, 1) + } + } +} + +/** + * Check whether the object has the property. + */ +var hasOwnProperty = Object.prototype.hasOwnProperty; +function hasOwn (obj, key) { + return hasOwnProperty.call(obj, key) +} + +/** + * Check if value is primitive + */ +function isPrimitive (value) { + return typeof value === 'string' || typeof value === 'number' +} + +/** + * Create a cached version of a pure function. + */ +function cached (fn) { + var cache = Object.create(null); + return (function cachedFn (str) { + var hit = cache[str]; + return hit || (cache[str] = fn(str)) + }) +} + +/** + * Camelize a hyphen-delmited string. + */ +var camelizeRE = /-(\w)/g; +var camelize = cached(function (str) { + return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) +}); + +/** + * Capitalize a string. + */ +var capitalize = cached(function (str) { + return str.charAt(0).toUpperCase() + str.slice(1) +}); + +/** + * Hyphenate a camelCase string. + */ +var hyphenateRE = /([^-])([A-Z])/g; +var hyphenate = cached(function (str) { + return str + .replace(hyphenateRE, '$1-$2') + .replace(hyphenateRE, '$1-$2') + .toLowerCase() +}); + +/** + * Simple bind, faster than native + */ +function bind$1 (fn, ctx) { + function boundFn (a) { + var l = arguments.length; + return l + ? l > 1 + ? fn.apply(ctx, arguments) + : fn.call(ctx, a) + : fn.call(ctx) + } + // record original fn length + boundFn._length = fn.length; + return boundFn +} + +/** + * Convert an Array-like object to a real Array. + */ +function toArray (list, start) { + start = start || 0; + var i = list.length - start; + var ret = new Array(i); + while (i--) { + ret[i] = list[i + start]; + } + return ret +} + +/** + * Mix properties into target object. + */ +function extend (to, _from) { + for (var key in _from) { + to[key] = _from[key]; + } + return to +} + +/** + * Quick object check - this is primarily used to tell + * Objects from primitive values when we know the value + * is a JSON-compliant type. + */ +function isObject (obj) { + return obj !== null && typeof obj === 'object' +} + +/** + * Strict object type check. Only returns true + * for plain JavaScript objects. + */ +var toString = Object.prototype.toString; +var OBJECT_STRING = '[object Object]'; +function isPlainObject (obj) { + return toString.call(obj) === OBJECT_STRING +} + +/** + * Merge an Array of Objects into a single Object. + */ +function toObject (arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res +} + +/** + * Perform no operation. + */ +function noop () {} + +/** + * Always return false. + */ +var no = function () { return false; }; + +/** + * Return same value + */ +var identity = function (_) { return _; }; + +/** + * Generate a static keys string from compiler modules. + */ +function genStaticKeys (modules) { + return modules.reduce(function (keys, m) { + return keys.concat(m.staticKeys || []) + }, []).join(',') +} + +/** + * Check if two values are loosely equal - that is, + * if they are plain objects, do they have the same shape? + */ +function looseEqual (a, b) { + var isObjectA = isObject(a); + var isObjectB = isObject(b); + if (isObjectA && isObjectB) { + return JSON.stringify(a) === JSON.stringify(b) + } else if (!isObjectA && !isObjectB) { + return String(a) === String(b) + } else { + return false + } +} + +function looseIndexOf (arr, val) { + for (var i = 0; i < arr.length; i++) { + if (looseEqual(arr[i], val)) { return i } + } + return -1 +} + +/* */ + +var config = { + /** + * Option merge strategies (used in core/util/options) + */ + optionMergeStrategies: Object.create(null), + + /** + * Whether to suppress warnings. + */ + silent: false, + + /** + * Whether to enable devtools + */ + devtools: "development" !== 'production', + + /** + * Error handler for watcher errors + */ + errorHandler: null, + + /** + * Ignore certain custom elements + */ + ignoredElements: [], + + /** + * Custom user key aliases for v-on + */ + keyCodes: Object.create(null), + + /** + * Check if a tag is reserved so that it cannot be registered as a + * component. This is platform-dependent and may be overwritten. + */ + isReservedTag: no, + + /** + * Check if a tag is an unknown element. + * Platform-dependent. + */ + isUnknownElement: no, + + /** + * Get the namespace of an element + */ + getTagNamespace: noop, + + /** + * Parse the real tag name for the specific platform. + */ + parsePlatformTagName: identity, + + /** + * Check if an attribute must be bound using property, e.g. value + * Platform-dependent. + */ + mustUseProp: no, + + /** + * List of asset types that a component can own. + */ + _assetTypes: [ + 'component', + 'directive', + 'filter' + ], + + /** + * List of lifecycle hooks. + */ + _lifecycleHooks: [ + 'beforeCreate', + 'created', + 'beforeMount', + 'mounted', + 'beforeUpdate', + 'updated', + 'beforeDestroy', + 'destroyed', + 'activated', + 'deactivated' + ], + + /** + * Max circular updates allowed in a scheduler flush cycle. + */ + _maxUpdateCount: 100 +}; + +/* */ + +/** + * Check if a string starts with $ or _ + */ +function isReserved (str) { + var c = (str + '').charCodeAt(0); + return c === 0x24 || c === 0x5F +} + +/** + * Define a property. + */ +function def (obj, key, val, enumerable) { + Object.defineProperty(obj, key, { + value: val, + enumerable: !!enumerable, + writable: true, + configurable: true + }); +} + +/** + * Parse simple path. + */ +var bailRE = /[^\w.$]/; +function parsePath (path) { + if (bailRE.test(path)) { + return + } else { + var segments = path.split('.'); + return function (obj) { + for (var i = 0; i < segments.length; i++) { + if (!obj) { return } + obj = obj[segments[i]]; + } + return obj + } + } +} + +/* */ +/* globals MutationObserver */ + +// can we use __proto__? +var hasProto = '__proto__' in {}; + +// Browser environment sniffing +var inBrowser = typeof window !== 'undefined'; +var UA = inBrowser && window.navigator.userAgent.toLowerCase(); +var isIE = UA && /msie|trident/.test(UA); +var isIE9 = UA && UA.indexOf('msie 9.0') > 0; +var isEdge = UA && UA.indexOf('edge/') > 0; +var isAndroid = UA && UA.indexOf('android') > 0; +var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA); + +// this needs to be lazy-evaled because vue may be required before +// vue-server-renderer can set VUE_ENV +var _isServer; +var isServerRendering = function () { + if (_isServer === undefined) { + /* istanbul ignore if */ + if (!inBrowser && typeof global !== 'undefined') { + // detect presence of vue-server-renderer and avoid + // Webpack shimming the process + _isServer = global['process'].env.VUE_ENV === 'server'; + } else { + _isServer = false; + } + } + return _isServer +}; + +// detect devtools +var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__; + +/* istanbul ignore next */ +function isNative (Ctor) { + return /native code/.test(Ctor.toString()) +} + +/** + * Defer a task to execute it asynchronously. + */ +var nextTick = (function () { + var callbacks = []; + var pending = false; + var timerFunc; + + function nextTickHandler () { + pending = false; + var copies = callbacks.slice(0); + callbacks.length = 0; + for (var i = 0; i < copies.length; i++) { + copies[i](); + } + } + + // the nextTick behavior leverages the microtask queue, which can be accessed + // via either native Promise.then or MutationObserver. + // MutationObserver has wider support, however it is seriously bugged in + // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It + // completely stops working after triggering a few times... so, if native + // Promise is available, we will use it: + /* istanbul ignore if */ + if (typeof Promise !== 'undefined' && isNative(Promise)) { + var p = Promise.resolve(); + var logError = function (err) { console.error(err); }; + timerFunc = function () { + p.then(nextTickHandler).catch(logError); + // in problematic UIWebViews, Promise.then doesn't completely break, but + // it can get stuck in a weird state where callbacks are pushed into the + // microtask queue but the queue isn't being flushed, until the browser + // needs to do some other work, e.g. handle a timer. Therefore we can + // "force" the microtask queue to be flushed by adding an empty timer. + if (isIOS) { setTimeout(noop); } + }; + } else if (typeof MutationObserver !== 'undefined' && ( + isNative(MutationObserver) || + // PhantomJS and iOS 7.x + MutationObserver.toString() === '[object MutationObserverConstructor]' + )) { + // use MutationObserver where native Promise is not available, + // e.g. PhantomJS IE11, iOS7, Android 4.4 + var counter = 1; + var observer = new MutationObserver(nextTickHandler); + var textNode = document.createTextNode(String(counter)); + observer.observe(textNode, { + characterData: true + }); + timerFunc = function () { + counter = (counter + 1) % 2; + textNode.data = String(counter); + }; + } else { + // fallback to setTimeout + /* istanbul ignore next */ + timerFunc = function () { + setTimeout(nextTickHandler, 0); + }; + } + + return function queueNextTick (cb, ctx) { + var _resolve; + callbacks.push(function () { + if (cb) { cb.call(ctx); } + if (_resolve) { _resolve(ctx); } + }); + if (!pending) { + pending = true; + timerFunc(); + } + if (!cb && typeof Promise !== 'undefined') { + return new Promise(function (resolve) { + _resolve = resolve; + }) + } + } +})(); + +var _Set; +/* istanbul ignore if */ +if (typeof Set !== 'undefined' && isNative(Set)) { + // use native Set when available. + _Set = Set; +} else { + // a non-standard Set polyfill that only works with primitive keys. + _Set = (function () { + function Set () { + this.set = Object.create(null); + } + Set.prototype.has = function has (key) { + return this.set[key] === true + }; + Set.prototype.add = function add (key) { + this.set[key] = true; + }; + Set.prototype.clear = function clear () { + this.set = Object.create(null); + }; + + return Set; + }()); +} + +var warn = noop; +var formatComponentName; + +{ + var hasConsole = typeof console !== 'undefined'; + + warn = function (msg, vm) { + if (hasConsole && (!config.silent)) { + console.error("[Vue warn]: " + msg + " " + ( + vm ? formatLocation(formatComponentName(vm)) : '' + )); + } + }; + + formatComponentName = function (vm) { + if (vm.$root === vm) { + return 'root instance' + } + var name = vm._isVue + ? vm.$options.name || vm.$options._componentTag + : vm.name; + return ( + (name ? ("component <" + name + ">") : "anonymous component") + + (vm._isVue && vm.$options.__file ? (" at " + (vm.$options.__file)) : '') + ) + }; + + var formatLocation = function (str) { + if (str === 'anonymous component') { + str += " - use the \"name\" option for better debugging messages."; + } + return ("\n(found in " + str + ")") + }; +} + +/* */ + + +var uid$1 = 0; + +/** + * A dep is an observable that can have multiple + * directives subscribing to it. + */ +var Dep = function Dep () { + this.id = uid$1++; + this.subs = []; +}; + +Dep.prototype.addSub = function addSub (sub) { + this.subs.push(sub); +}; + +Dep.prototype.removeSub = function removeSub (sub) { + remove$1(this.subs, sub); +}; + +Dep.prototype.depend = function depend () { + if (Dep.target) { + Dep.target.addDep(this); + } +}; + +Dep.prototype.notify = function notify () { + // stablize the subscriber list first + var subs = this.subs.slice(); + for (var i = 0, l = subs.length; i < l; i++) { + subs[i].update(); + } +}; + +// the current target watcher being evaluated. +// this is globally unique because there could be only one +// watcher being evaluated at any time. +Dep.target = null; +var targetStack = []; + +function pushTarget (_target) { + if (Dep.target) { targetStack.push(Dep.target); } + Dep.target = _target; +} + +function popTarget () { + Dep.target = targetStack.pop(); +} + +/* + * not type checking this file because flow doesn't play well with + * dynamically accessing methods on Array prototype + */ + +var arrayProto = Array.prototype; +var arrayMethods = Object.create(arrayProto);[ + 'push', + 'pop', + 'shift', + 'unshift', + 'splice', + 'sort', + 'reverse' +] +.forEach(function (method) { + // cache original method + var original = arrayProto[method]; + def(arrayMethods, method, function mutator () { + var arguments$1 = arguments; + + // avoid leaking arguments: + // http://jsperf.com/closure-with-arguments + var i = arguments.length; + var args = new Array(i); + while (i--) { + args[i] = arguments$1[i]; + } + var result = original.apply(this, args); + var ob = this.__ob__; + var inserted; + switch (method) { + case 'push': + inserted = args; + break + case 'unshift': + inserted = args; + break + case 'splice': + inserted = args.slice(2); + break + } + if (inserted) { ob.observeArray(inserted); } + // notify change + ob.dep.notify(); + return result + }); +}); + +/* */ + +var arrayKeys = Object.getOwnPropertyNames(arrayMethods); + +/** + * By default, when a reactive property is set, the new value is + * also converted to become reactive. However when passing down props, + * we don't want to force conversion because the value may be a nested value + * under a frozen data structure. Converting it would defeat the optimization. + */ +var observerState = { + shouldConvert: true, + isSettingProps: false +}; + +/** + * Observer class that are attached to each observed + * object. Once attached, the observer converts target + * object's property keys into getter/setters that + * collect dependencies and dispatches updates. + */ +var Observer = function Observer (value) { + this.value = value; + this.dep = new Dep(); + this.vmCount = 0; + def(value, '__ob__', this); + if (Array.isArray(value)) { + var augment = hasProto + ? protoAugment + : copyAugment; + augment(value, arrayMethods, arrayKeys); + this.observeArray(value); + } else { + this.walk(value); + } +}; + +/** + * Walk through each property and convert them into + * getter/setters. This method should only be called when + * value type is Object. + */ +Observer.prototype.walk = function walk (obj) { + var keys = Object.keys(obj); + for (var i = 0; i < keys.length; i++) { + defineReactive$$1(obj, keys[i], obj[keys[i]]); + } +}; + +/** + * Observe a list of Array items. + */ +Observer.prototype.observeArray = function observeArray (items) { + for (var i = 0, l = items.length; i < l; i++) { + observe(items[i]); + } +}; + +// helpers + +/** + * Augment an target Object or Array by intercepting + * the prototype chain using __proto__ + */ +function protoAugment (target, src) { + /* eslint-disable no-proto */ + target.__proto__ = src; + /* eslint-enable no-proto */ +} + +/** + * Augment an target Object or Array by defining + * hidden properties. + */ +/* istanbul ignore next */ +function copyAugment (target, src, keys) { + for (var i = 0, l = keys.length; i < l; i++) { + var key = keys[i]; + def(target, key, src[key]); + } +} + +/** + * Attempt to create an observer instance for a value, + * returns the new observer if successfully observed, + * or the existing observer if the value already has one. + */ +function observe (value, asRootData) { + if (!isObject(value)) { + return + } + var ob; + if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { + ob = value.__ob__; + } else if ( + observerState.shouldConvert && + !isServerRendering() && + (Array.isArray(value) || isPlainObject(value)) && + Object.isExtensible(value) && + !value._isVue + ) { + ob = new Observer(value); + } + if (asRootData && ob) { + ob.vmCount++; + } + return ob +} + +/** + * Define a reactive property on an Object. + */ +function defineReactive$$1 ( + obj, + key, + val, + customSetter +) { + var dep = new Dep(); + + var property = Object.getOwnPropertyDescriptor(obj, key); + if (property && property.configurable === false) { + return + } + + // cater for pre-defined getter/setters + var getter = property && property.get; + var setter = property && property.set; + + var childOb = observe(val); + Object.defineProperty(obj, key, { + enumerable: true, + configurable: true, + get: function reactiveGetter () { + var value = getter ? getter.call(obj) : val; + if (Dep.target) { + dep.depend(); + if (childOb) { + childOb.dep.depend(); + } + if (Array.isArray(value)) { + dependArray(value); + } + } + return value + }, + set: function reactiveSetter (newVal) { + var value = getter ? getter.call(obj) : val; + /* eslint-disable no-self-compare */ + if (newVal === value || (newVal !== newVal && value !== value)) { + return + } + /* eslint-enable no-self-compare */ + if ("development" !== 'production' && customSetter) { + customSetter(); + } + if (setter) { + setter.call(obj, newVal); + } else { + val = newVal; + } + childOb = observe(newVal); + dep.notify(); + } + }); +} + +/** + * Set a property on an object. Adds the new property and + * triggers change notification if the property doesn't + * already exist. + */ +function set$1 (obj, key, val) { + if (Array.isArray(obj)) { + obj.length = Math.max(obj.length, key); + obj.splice(key, 1, val); + return val + } + if (hasOwn(obj, key)) { + obj[key] = val; + return + } + var ob = obj.__ob__; + if (obj._isVue || (ob && ob.vmCount)) { + "development" !== 'production' && warn( + 'Avoid adding reactive properties to a Vue instance or its root $data ' + + 'at runtime - declare it upfront in the data option.' + ); + return + } + if (!ob) { + obj[key] = val; + return + } + defineReactive$$1(ob.value, key, val); + ob.dep.notify(); + return val +} + +/** + * Delete a property and trigger change if necessary. + */ +function del (obj, key) { + var ob = obj.__ob__; + if (obj._isVue || (ob && ob.vmCount)) { + "development" !== 'production' && warn( + 'Avoid deleting properties on a Vue instance or its root $data ' + + '- just set it to null.' + ); + return + } + if (!hasOwn(obj, key)) { + return + } + delete obj[key]; + if (!ob) { + return + } + ob.dep.notify(); +} + +/** + * Collect dependencies on array elements when the array is touched, since + * we cannot intercept array element access like property getters. + */ +function dependArray (value) { + for (var e = (void 0), i = 0, l = value.length; i < l; i++) { + e = value[i]; + e && e.__ob__ && e.__ob__.dep.depend(); + if (Array.isArray(e)) { + dependArray(e); + } + } +} + +/* */ + +/** + * Option overwriting strategies are functions that handle + * how to merge a parent option value and a child option + * value into the final value. + */ +var strats = config.optionMergeStrategies; + +/** + * Options with restrictions + */ +{ + strats.el = strats.propsData = function (parent, child, vm, key) { + if (!vm) { + warn( + "option \"" + key + "\" can only be used during instance " + + 'creation with the `new` keyword.' + ); + } + return defaultStrat(parent, child) + }; +} + +/** + * Helper that recursively merges two data objects together. + */ +function mergeData (to, from) { + if (!from) { return to } + var key, toVal, fromVal; + var keys = Object.keys(from); + for (var i = 0; i < keys.length; i++) { + key = keys[i]; + toVal = to[key]; + fromVal = from[key]; + if (!hasOwn(to, key)) { + set$1(to, key, fromVal); + } else if (isPlainObject(toVal) && isPlainObject(fromVal)) { + mergeData(toVal, fromVal); + } + } + return to +} + +/** + * Data + */ +strats.data = function ( + parentVal, + childVal, + vm +) { + if (!vm) { + // in a Vue.extend merge, both should be functions + if (!childVal) { + return parentVal + } + if (typeof childVal !== 'function') { + "development" !== 'production' && warn( + 'The "data" option should be a function ' + + 'that returns a per-instance value in component ' + + 'definitions.', + vm + ); + return parentVal + } + if (!parentVal) { + return childVal + } + // when parentVal & childVal are both present, + // we need to return a function that returns the + // merged result of both functions... no need to + // check if parentVal is a function here because + // it has to be a function to pass previous merges. + return function mergedDataFn () { + return mergeData( + childVal.call(this), + parentVal.call(this) + ) + } + } else if (parentVal || childVal) { + return function mergedInstanceDataFn () { + // instance merge + var instanceData = typeof childVal === 'function' + ? childVal.call(vm) + : childVal; + var defaultData = typeof parentVal === 'function' + ? parentVal.call(vm) + : undefined; + if (instanceData) { + return mergeData(instanceData, defaultData) + } else { + return defaultData + } + } + } +}; + +/** + * Hooks and param attributes are merged as arrays. + */ +function mergeHook ( + parentVal, + childVal +) { + return childVal + ? parentVal + ? parentVal.concat(childVal) + : Array.isArray(childVal) + ? childVal + : [childVal] + : parentVal +} + +config._lifecycleHooks.forEach(function (hook) { + strats[hook] = mergeHook; +}); + +/** + * Assets + * + * When a vm is present (instance creation), we need to do + * a three-way merge between constructor options, instance + * options and parent options. + */ +function mergeAssets (parentVal, childVal) { + var res = Object.create(parentVal || null); + return childVal + ? extend(res, childVal) + : res +} + +config._assetTypes.forEach(function (type) { + strats[type + 's'] = mergeAssets; +}); + +/** + * Watchers. + * + * Watchers hashes should not overwrite one + * another, so we merge them as arrays. + */ +strats.watch = function (parentVal, childVal) { + /* istanbul ignore if */ + if (!childVal) { return parentVal } + if (!parentVal) { return childVal } + var ret = {}; + extend(ret, parentVal); + for (var key in childVal) { + var parent = ret[key]; + var child = childVal[key]; + if (parent && !Array.isArray(parent)) { + parent = [parent]; + } + ret[key] = parent + ? parent.concat(child) + : [child]; + } + return ret +}; + +/** + * Other object hashes. + */ +strats.props = +strats.methods = +strats.computed = function (parentVal, childVal) { + if (!childVal) { return parentVal } + if (!parentVal) { return childVal } + var ret = Object.create(null); + extend(ret, parentVal); + extend(ret, childVal); + return ret +}; + +/** + * Default strategy. + */ +var defaultStrat = function (parentVal, childVal) { + return childVal === undefined + ? parentVal + : childVal +}; + +/** + * Validate component names + */ +function checkComponents (options) { + for (var key in options.components) { + var lower = key.toLowerCase(); + if (isBuiltInTag(lower) || config.isReservedTag(lower)) { + warn( + 'Do not use built-in or reserved HTML elements as component ' + + 'id: ' + key + ); + } + } +} + +/** + * Ensure all props option syntax are normalized into the + * Object-based format. + */ +function normalizeProps (options) { + var props = options.props; + if (!props) { return } + var res = {}; + var i, val, name; + if (Array.isArray(props)) { + i = props.length; + while (i--) { + val = props[i]; + if (typeof val === 'string') { + name = camelize(val); + res[name] = { type: null }; + } else { + warn('props must be strings when using array syntax.'); + } + } + } else if (isPlainObject(props)) { + for (var key in props) { + val = props[key]; + name = camelize(key); + res[name] = isPlainObject(val) + ? val + : { type: val }; + } + } + options.props = res; +} + +/** + * Normalize raw function directives into object format. + */ +function normalizeDirectives (options) { + var dirs = options.directives; + if (dirs) { + for (var key in dirs) { + var def = dirs[key]; + if (typeof def === 'function') { + dirs[key] = { bind: def, update: def }; + } + } + } +} + +/** + * Merge two option objects into a new one. + * Core utility used in both instantiation and inheritance. + */ +function mergeOptions ( + parent, + child, + vm +) { + { + checkComponents(child); + } + normalizeProps(child); + normalizeDirectives(child); + var extendsFrom = child.extends; + if (extendsFrom) { + parent = typeof extendsFrom === 'function' + ? mergeOptions(parent, extendsFrom.options, vm) + : mergeOptions(parent, extendsFrom, vm); + } + if (child.mixins) { + for (var i = 0, l = child.mixins.length; i < l; i++) { + var mixin = child.mixins[i]; + if (mixin.prototype instanceof Vue$3) { + mixin = mixin.options; + } + parent = mergeOptions(parent, mixin, vm); + } + } + var options = {}; + var key; + for (key in parent) { + mergeField(key); + } + for (key in child) { + if (!hasOwn(parent, key)) { + mergeField(key); + } + } + function mergeField (key) { + var strat = strats[key] || defaultStrat; + options[key] = strat(parent[key], child[key], vm, key); + } + return options +} + +/** + * Resolve an asset. + * This function is used because child instances need access + * to assets defined in its ancestor chain. + */ +function resolveAsset ( + options, + type, + id, + warnMissing +) { + /* istanbul ignore if */ + if (typeof id !== 'string') { + return + } + var assets = options[type]; + // check local registration variations first + if (hasOwn(assets, id)) { return assets[id] } + var camelizedId = camelize(id); + if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } + var PascalCaseId = capitalize(camelizedId); + if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } + // fallback to prototype chain + var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; + if ("development" !== 'production' && warnMissing && !res) { + warn( + 'Failed to resolve ' + type.slice(0, -1) + ': ' + id, + options + ); + } + return res +} + +/* */ + +function validateProp ( + key, + propOptions, + propsData, + vm +) { + var prop = propOptions[key]; + var absent = !hasOwn(propsData, key); + var value = propsData[key]; + // handle boolean props + if (isType(Boolean, prop.type)) { + if (absent && !hasOwn(prop, 'default')) { + value = false; + } else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) { + value = true; + } + } + // check default value + if (value === undefined) { + value = getPropDefaultValue(vm, prop, key); + // since the default value is a fresh copy, + // make sure to observe it. + var prevShouldConvert = observerState.shouldConvert; + observerState.shouldConvert = true; + observe(value); + observerState.shouldConvert = prevShouldConvert; + } + { + assertProp(prop, key, value, vm, absent); + } + return value +} + +/** + * Get the default value of a prop. + */ +function getPropDefaultValue (vm, prop, key) { + // no default, return undefined + if (!hasOwn(prop, 'default')) { + return undefined + } + var def = prop.default; + // warn against non-factory defaults for Object & Array + if (isObject(def)) { + "development" !== 'production' && warn( + 'Invalid default value for prop "' + key + '": ' + + 'Props with type Object/Array must use a factory function ' + + 'to return the default value.', + vm + ); + } + // the raw prop value was also undefined from previous render, + // return previous default value to avoid unnecessary watcher trigger + if (vm && vm.$options.propsData && + vm.$options.propsData[key] === undefined && + vm[key] !== undefined) { + return vm[key] + } + // call factory function for non-Function types + return typeof def === 'function' && prop.type !== Function + ? def.call(vm) + : def +} + +/** + * Assert whether a prop is valid. + */ +function assertProp ( + prop, + name, + value, + vm, + absent +) { + if (prop.required && absent) { + warn( + 'Missing required prop: "' + name + '"', + vm + ); + return + } + if (value == null && !prop.required) { + return + } + var type = prop.type; + var valid = !type || type === true; + var expectedTypes = []; + if (type) { + if (!Array.isArray(type)) { + type = [type]; + } + for (var i = 0; i < type.length && !valid; i++) { + var assertedType = assertType(value, type[i]); + expectedTypes.push(assertedType.expectedType || ''); + valid = assertedType.valid; + } + } + if (!valid) { + warn( + 'Invalid prop: type check failed for prop "' + name + '".' + + ' Expected ' + expectedTypes.map(capitalize).join(', ') + + ', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.', + vm + ); + return + } + var validator = prop.validator; + if (validator) { + if (!validator(value)) { + warn( + 'Invalid prop: custom validator check failed for prop "' + name + '".', + vm + ); + } + } +} + +/** + * Assert the type of a value + */ +function assertType (value, type) { + var valid; + var expectedType = getType(type); + if (expectedType === 'String') { + valid = typeof value === (expectedType = 'string'); + } else if (expectedType === 'Number') { + valid = typeof value === (expectedType = 'number'); + } else if (expectedType === 'Boolean') { + valid = typeof value === (expectedType = 'boolean'); + } else if (expectedType === 'Function') { + valid = typeof value === (expectedType = 'function'); + } else if (expectedType === 'Object') { + valid = isPlainObject(value); + } else if (expectedType === 'Array') { + valid = Array.isArray(value); + } else { + valid = value instanceof type; + } + return { + valid: valid, + expectedType: expectedType + } +} + +/** + * Use function string name to check built-in types, + * because a simple equality check will fail when running + * across different vms / iframes. + */ +function getType (fn) { + var match = fn && fn.toString().match(/^\s*function (\w+)/); + return match && match[1] +} + +function isType (type, fn) { + if (!Array.isArray(fn)) { + return getType(fn) === getType(type) + } + for (var i = 0, len = fn.length; i < len; i++) { + if (getType(fn[i]) === getType(type)) { + return true + } + } + /* istanbul ignore next */ + return false +} + + + +var util = Object.freeze({ + defineReactive: defineReactive$$1, + _toString: _toString, + toNumber: toNumber, + makeMap: makeMap, + isBuiltInTag: isBuiltInTag, + remove: remove$1, + hasOwn: hasOwn, + isPrimitive: isPrimitive, + cached: cached, + camelize: camelize, + capitalize: capitalize, + hyphenate: hyphenate, + bind: bind$1, + toArray: toArray, + extend: extend, + isObject: isObject, + isPlainObject: isPlainObject, + toObject: toObject, + noop: noop, + no: no, + identity: identity, + genStaticKeys: genStaticKeys, + looseEqual: looseEqual, + looseIndexOf: looseIndexOf, + isReserved: isReserved, + def: def, + parsePath: parsePath, + hasProto: hasProto, + inBrowser: inBrowser, + UA: UA, + isIE: isIE, + isIE9: isIE9, + isEdge: isEdge, + isAndroid: isAndroid, + isIOS: isIOS, + isServerRendering: isServerRendering, + devtools: devtools, + nextTick: nextTick, + get _Set () { return _Set; }, + mergeOptions: mergeOptions, + resolveAsset: resolveAsset, + get warn () { return warn; }, + get formatComponentName () { return formatComponentName; }, + validateProp: validateProp +}); + +/* not type checking this file because flow doesn't play well with Proxy */ + +var initProxy; + +{ + var allowedGlobals = makeMap( + 'Infinity,undefined,NaN,isFinite,isNaN,' + + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + + 'require' // for Webpack/Browserify + ); + + var warnNonPresent = function (target, key) { + warn( + "Property or method \"" + key + "\" is not defined on the instance but " + + "referenced during render. Make sure to declare reactive data " + + "properties in the data option.", + target + ); + }; + + var hasProxy = + typeof Proxy !== 'undefined' && + Proxy.toString().match(/native code/); + + if (hasProxy) { + var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta'); + config.keyCodes = new Proxy(config.keyCodes, { + set: function set (target, key, value) { + if (isBuiltInModifier(key)) { + warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key)); + return false + } else { + target[key] = value; + return true + } + } + }); + } + + var hasHandler = { + has: function has (target, key) { + var has = key in target; + var isAllowed = allowedGlobals(key) || key.charAt(0) === '_'; + if (!has && !isAllowed) { + warnNonPresent(target, key); + } + return has || !isAllowed + } + }; + + var getHandler = { + get: function get (target, key) { + if (typeof key === 'string' && !(key in target)) { + warnNonPresent(target, key); + } + return target[key] + } + }; + + initProxy = function initProxy (vm) { + if (hasProxy) { + // determine which proxy handler to use + var options = vm.$options; + var handlers = options.render && options.render._withStripped + ? getHandler + : hasHandler; + vm._renderProxy = new Proxy(vm, handlers); + } else { + vm._renderProxy = vm; + } + }; +} + +/* */ + + +var queue = []; +var has$1 = {}; +var circular = {}; +var waiting = false; +var flushing = false; +var index = 0; + +/** + * Reset the scheduler's state. + */ +function resetSchedulerState () { + queue.length = 0; + has$1 = {}; + { + circular = {}; + } + waiting = flushing = false; +} + +/** + * Flush both queues and run the watchers. + */ +function flushSchedulerQueue () { + flushing = true; + + // Sort queue before flush. + // This ensures that: + // 1. Components are updated from parent to child. (because parent is always + // created before the child) + // 2. A component's user watchers are run before its render watcher (because + // user watchers are created before the render watcher) + // 3. If a component is destroyed during a parent component's watcher run, + // its watchers can be skipped. + queue.sort(function (a, b) { return a.id - b.id; }); + + // do not cache length because more watchers might be pushed + // as we run existing watchers + for (index = 0; index < queue.length; index++) { + var watcher = queue[index]; + var id = watcher.id; + has$1[id] = null; + watcher.run(); + // in dev build, check and stop circular updates. + if ("development" !== 'production' && has$1[id] != null) { + circular[id] = (circular[id] || 0) + 1; + if (circular[id] > config._maxUpdateCount) { + warn( + 'You may have an infinite update loop ' + ( + watcher.user + ? ("in watcher with expression \"" + (watcher.expression) + "\"") + : "in a component render function." + ), + watcher.vm + ); + break + } + } + } + + // devtool hook + /* istanbul ignore if */ + if (devtools && config.devtools) { + devtools.emit('flush'); + } + + resetSchedulerState(); +} + +/** + * Push a watcher into the watcher queue. + * Jobs with duplicate IDs will be skipped unless it's + * pushed when the queue is being flushed. + */ +function queueWatcher (watcher) { + var id = watcher.id; + if (has$1[id] == null) { + has$1[id] = true; + if (!flushing) { + queue.push(watcher); + } else { + // if already flushing, splice the watcher based on its id + // if already past its id, it will be run next immediately. + var i = queue.length - 1; + while (i >= 0 && queue[i].id > watcher.id) { + i--; + } + queue.splice(Math.max(i, index) + 1, 0, watcher); + } + // queue the flush + if (!waiting) { + waiting = true; + nextTick(flushSchedulerQueue); + } + } +} + +/* */ + +var uid$2 = 0; + +/** + * A watcher parses an expression, collects dependencies, + * and fires callback when the expression value changes. + * This is used for both the $watch() api and directives. + */ +var Watcher = function Watcher ( + vm, + expOrFn, + cb, + options +) { + this.vm = vm; + vm._watchers.push(this); + // options + if (options) { + this.deep = !!options.deep; + this.user = !!options.user; + this.lazy = !!options.lazy; + this.sync = !!options.sync; + } else { + this.deep = this.user = this.lazy = this.sync = false; + } + this.cb = cb; + this.id = ++uid$2; // uid for batching + this.active = true; + this.dirty = this.lazy; // for lazy watchers + this.deps = []; + this.newDeps = []; + this.depIds = new _Set(); + this.newDepIds = new _Set(); + this.expression = expOrFn.toString(); + // parse expression for getter + if (typeof expOrFn === 'function') { + this.getter = expOrFn; + } else { + this.getter = parsePath(expOrFn); + if (!this.getter) { + this.getter = function () {}; + "development" !== 'production' && warn( + "Failed watching path: \"" + expOrFn + "\" " + + 'Watcher only accepts simple dot-delimited paths. ' + + 'For full control, use a function instead.', + vm + ); + } + } + this.value = this.lazy + ? undefined + : this.get(); +}; + +/** + * Evaluate the getter, and re-collect dependencies. + */ +Watcher.prototype.get = function get () { + pushTarget(this); + var value = this.getter.call(this.vm, this.vm); + // "touch" every property so they are all tracked as + // dependencies for deep watching + if (this.deep) { + traverse(value); + } + popTarget(); + this.cleanupDeps(); + return value +}; + +/** + * Add a dependency to this directive. + */ +Watcher.prototype.addDep = function addDep (dep) { + var id = dep.id; + if (!this.newDepIds.has(id)) { + this.newDepIds.add(id); + this.newDeps.push(dep); + if (!this.depIds.has(id)) { + dep.addSub(this); + } + } +}; + +/** + * Clean up for dependency collection. + */ +Watcher.prototype.cleanupDeps = function cleanupDeps () { + var this$1 = this; + + var i = this.deps.length; + while (i--) { + var dep = this$1.deps[i]; + if (!this$1.newDepIds.has(dep.id)) { + dep.removeSub(this$1); + } + } + var tmp = this.depIds; + this.depIds = this.newDepIds; + this.newDepIds = tmp; + this.newDepIds.clear(); + tmp = this.deps; + this.deps = this.newDeps; + this.newDeps = tmp; + this.newDeps.length = 0; +}; + +/** + * Subscriber interface. + * Will be called when a dependency changes. + */ +Watcher.prototype.update = function update () { + /* istanbul ignore else */ + if (this.lazy) { + this.dirty = true; + } else if (this.sync) { + this.run(); + } else { + queueWatcher(this); + } +}; + +/** + * Scheduler job interface. + * Will be called by the scheduler. + */ +Watcher.prototype.run = function run () { + if (this.active) { + var value = this.get(); + if ( + value !== this.value || + // Deep watchers and watchers on Object/Arrays should fire even + // when the value is the same, because the value may + // have mutated. + isObject(value) || + this.deep + ) { + // set new value + var oldValue = this.value; + this.value = value; + if (this.user) { + try { + this.cb.call(this.vm, value, oldValue); + } catch (e) { + /* istanbul ignore else */ + if (config.errorHandler) { + config.errorHandler.call(null, e, this.vm); + } else { + "development" !== 'production' && warn( + ("Error in watcher \"" + (this.expression) + "\""), + this.vm + ); + throw e + } + } + } else { + this.cb.call(this.vm, value, oldValue); + } + } + } +}; + +/** + * Evaluate the value of the watcher. + * This only gets called for lazy watchers. + */ +Watcher.prototype.evaluate = function evaluate () { + this.value = this.get(); + this.dirty = false; +}; + +/** + * Depend on all deps collected by this watcher. + */ +Watcher.prototype.depend = function depend () { + var this$1 = this; + + var i = this.deps.length; + while (i--) { + this$1.deps[i].depend(); + } +}; + +/** + * Remove self from all dependencies' subscriber list. + */ +Watcher.prototype.teardown = function teardown () { + var this$1 = this; + + if (this.active) { + // remove self from vm's watcher list + // this is a somewhat expensive operation so we skip it + // if the vm is being destroyed. + if (!this.vm._isBeingDestroyed) { + remove$1(this.vm._watchers, this); + } + var i = this.deps.length; + while (i--) { + this$1.deps[i].removeSub(this$1); + } + this.active = false; + } +}; + +/** + * Recursively traverse an object to evoke all converted + * getters, so that every nested property inside the object + * is collected as a "deep" dependency. + */ +var seenObjects = new _Set(); +function traverse (val) { + seenObjects.clear(); + _traverse(val, seenObjects); +} + +function _traverse (val, seen) { + var i, keys; + var isA = Array.isArray(val); + if ((!isA && !isObject(val)) || !Object.isExtensible(val)) { + return + } + if (val.__ob__) { + var depId = val.__ob__.dep.id; + if (seen.has(depId)) { + return + } + seen.add(depId); + } + if (isA) { + i = val.length; + while (i--) { _traverse(val[i], seen); } + } else { + keys = Object.keys(val); + i = keys.length; + while (i--) { _traverse(val[keys[i]], seen); } + } +} + +/* */ + +function initState (vm) { + vm._watchers = []; + var opts = vm.$options; + if (opts.props) { initProps(vm, opts.props); } + if (opts.methods) { initMethods(vm, opts.methods); } + if (opts.data) { + initData(vm); + } else { + observe(vm._data = {}, true /* asRootData */); + } + if (opts.computed) { initComputed(vm, opts.computed); } + if (opts.watch) { initWatch(vm, opts.watch); } +} + +var isReservedProp = { key: 1, ref: 1, slot: 1 }; + +function initProps (vm, props) { + var propsData = vm.$options.propsData || {}; + var keys = vm.$options._propKeys = Object.keys(props); + var isRoot = !vm.$parent; + // root instance props should be converted + observerState.shouldConvert = isRoot; + var loop = function ( i ) { + var key = keys[i]; + /* istanbul ignore else */ + { + if (isReservedProp[key]) { + warn( + ("\"" + key + "\" is a reserved attribute and cannot be used as component prop."), + vm + ); + } + defineReactive$$1(vm, key, validateProp(key, props, propsData, vm), function () { + if (vm.$parent && !observerState.isSettingProps) { + warn( + "Avoid mutating a prop directly since the value will be " + + "overwritten whenever the parent component re-renders. " + + "Instead, use a data or computed property based on the prop's " + + "value. Prop being mutated: \"" + key + "\"", + vm + ); + } + }); + } + }; + + for (var i = 0; i < keys.length; i++) loop( i ); + observerState.shouldConvert = true; +} + +function initData (vm) { + var data = vm.$options.data; + data = vm._data = typeof data === 'function' + ? data.call(vm) + : data || {}; + if (!isPlainObject(data)) { + data = {}; + "development" !== 'production' && warn( + 'data functions should return an object:\n' + + 'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', + vm + ); + } + // proxy data on instance + var keys = Object.keys(data); + var props = vm.$options.props; + var i = keys.length; + while (i--) { + if (props && hasOwn(props, keys[i])) { + "development" !== 'production' && warn( + "The data property \"" + (keys[i]) + "\" is already declared as a prop. " + + "Use prop default value instead.", + vm + ); + } else { + proxy(vm, keys[i]); + } + } + // observe data + observe(data, true /* asRootData */); +} + +var computedSharedDefinition = { + enumerable: true, + configurable: true, + get: noop, + set: noop +}; + +function initComputed (vm, computed) { + for (var key in computed) { + /* istanbul ignore if */ + if ("development" !== 'production' && key in vm) { + warn( + "existing instance property \"" + key + "\" will be " + + "overwritten by a computed property with the same name.", + vm + ); + } + var userDef = computed[key]; + if (typeof userDef === 'function') { + computedSharedDefinition.get = makeComputedGetter(userDef, vm); + computedSharedDefinition.set = noop; + } else { + computedSharedDefinition.get = userDef.get + ? userDef.cache !== false + ? makeComputedGetter(userDef.get, vm) + : bind$1(userDef.get, vm) + : noop; + computedSharedDefinition.set = userDef.set + ? bind$1(userDef.set, vm) + : noop; + } + Object.defineProperty(vm, key, computedSharedDefinition); + } +} + +function makeComputedGetter (getter, owner) { + var watcher = new Watcher(owner, getter, noop, { + lazy: true + }); + return function computedGetter () { + if (watcher.dirty) { + watcher.evaluate(); + } + if (Dep.target) { + watcher.depend(); + } + return watcher.value + } +} + +function initMethods (vm, methods) { + for (var key in methods) { + vm[key] = methods[key] == null ? noop : bind$1(methods[key], vm); + if ("development" !== 'production' && methods[key] == null) { + warn( + "method \"" + key + "\" has an undefined value in the component definition. " + + "Did you reference the function correctly?", + vm + ); + } + } +} + +function initWatch (vm, watch) { + for (var key in watch) { + var handler = watch[key]; + if (Array.isArray(handler)) { + for (var i = 0; i < handler.length; i++) { + createWatcher(vm, key, handler[i]); + } + } else { + createWatcher(vm, key, handler); + } + } +} + +function createWatcher (vm, key, handler) { + var options; + if (isPlainObject(handler)) { + options = handler; + handler = handler.handler; + } + if (typeof handler === 'string') { + handler = vm[handler]; + } + vm.$watch(key, handler, options); +} + +function stateMixin (Vue) { + // flow somehow has problems with directly declared definition object + // when using Object.defineProperty, so we have to procedurally build up + // the object here. + var dataDef = {}; + dataDef.get = function () { + return this._data + }; + { + dataDef.set = function (newData) { + warn( + 'Avoid replacing instance root $data. ' + + 'Use nested data properties instead.', + this + ); + }; + } + Object.defineProperty(Vue.prototype, '$data', dataDef); + + Vue.prototype.$set = set$1; + Vue.prototype.$delete = del; + + Vue.prototype.$watch = function ( + expOrFn, + cb, + options + ) { + var vm = this; + options = options || {}; + options.user = true; + var watcher = new Watcher(vm, expOrFn, cb, options); + if (options.immediate) { + cb.call(vm, watcher.value); + } + return function unwatchFn () { + watcher.teardown(); + } + }; +} + +function proxy (vm, key) { + if (!isReserved(key)) { + Object.defineProperty(vm, key, { + configurable: true, + enumerable: true, + get: function proxyGetter () { + return vm._data[key] + }, + set: function proxySetter (val) { + vm._data[key] = val; + } + }); + } +} + +/* */ + +var VNode = function VNode ( + tag, + data, + children, + text, + elm, + context, + componentOptions +) { + this.tag = tag; + this.data = data; + this.children = children; + this.text = text; + this.elm = elm; + this.ns = undefined; + this.context = context; + this.functionalContext = undefined; + this.key = data && data.key; + this.componentOptions = componentOptions; + this.child = undefined; + this.parent = undefined; + this.raw = false; + this.isStatic = false; + this.isRootInsert = true; + this.isComment = false; + this.isCloned = false; + this.isOnce = false; +}; + +var createEmptyVNode = function () { + var node = new VNode(); + node.text = ''; + node.isComment = true; + return node +}; + +function createTextVNode (val) { + return new VNode(undefined, undefined, undefined, String(val)) +} + +// optimized shallow clone +// used for static nodes and slot nodes because they may be reused across +// multiple renders, cloning them avoids errors when DOM manipulations rely +// on their elm reference. +function cloneVNode (vnode) { + var cloned = new VNode( + vnode.tag, + vnode.data, + vnode.children, + vnode.text, + vnode.elm, + vnode.context, + vnode.componentOptions + ); + cloned.ns = vnode.ns; + cloned.isStatic = vnode.isStatic; + cloned.key = vnode.key; + cloned.isCloned = true; + return cloned +} + +function cloneVNodes (vnodes) { + var res = new Array(vnodes.length); + for (var i = 0; i < vnodes.length; i++) { + res[i] = cloneVNode(vnodes[i]); + } + return res +} + +/* */ + +function mergeVNodeHook (def, hookKey, hook, key) { + key = key + hookKey; + var injectedHash = def.__injected || (def.__injected = {}); + if (!injectedHash[key]) { + injectedHash[key] = true; + var oldHook = def[hookKey]; + if (oldHook) { + def[hookKey] = function () { + oldHook.apply(this, arguments); + hook.apply(this, arguments); + }; + } else { + def[hookKey] = hook; + } + } +} + +/* */ + +function updateListeners ( + on, + oldOn, + add, + remove$$1, + vm +) { + var name, cur, old, fn, event, capture, once; + for (name in on) { + cur = on[name]; + old = oldOn[name]; + if (!cur) { + "development" !== 'production' && warn( + "Invalid handler for event \"" + name + "\": got " + String(cur), + vm + ); + } else if (!old) { + once = name.charAt(0) === '~'; // Prefixed last, checked first + event = once ? name.slice(1) : name; + capture = event.charAt(0) === '!'; + event = capture ? event.slice(1) : event; + if (Array.isArray(cur)) { + add(event, (cur.invoker = arrInvoker(cur)), once, capture); + } else { + if (!cur.invoker) { + fn = cur; + cur = on[name] = {}; + cur.fn = fn; + cur.invoker = fnInvoker(cur); + } + add(event, cur.invoker, once, capture); + } + } else if (cur !== old) { + if (Array.isArray(old)) { + old.length = cur.length; + for (var i = 0; i < old.length; i++) { old[i] = cur[i]; } + on[name] = old; + } else { + old.fn = cur; + on[name] = old; + } + } + } + for (name in oldOn) { + if (!on[name]) { + once = name.charAt(0) === '~'; // Prefixed last, checked first + event = once ? name.slice(1) : name; + capture = event.charAt(0) === '!'; + event = capture ? event.slice(1) : event; + remove$$1(event, oldOn[name].invoker, capture); + } + } +} + +function arrInvoker (arr) { + return function (ev) { + var arguments$1 = arguments; + + var single = arguments.length === 1; + for (var i = 0; i < arr.length; i++) { + single ? arr[i](ev) : arr[i].apply(null, arguments$1); + } + } +} + +function fnInvoker (o) { + return function (ev) { + var single = arguments.length === 1; + single ? o.fn(ev) : o.fn.apply(null, arguments); + } +} + +/* */ + +// The template compiler attempts to minimize the need for normalization by +// statically analyzing the template at compile time. +// +// For plain HTML markup, normalization can be completely skipped because the +// generated render function is guaranteed to return Array. There are +// two cases where extra normalization is needed: + +// 1. When the children contains components - because a functional component +// may return an Array instead of a single root. In this case, just a simple +// nomralization is needed - if any child is an Array, we flatten the whole +// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep +// because functional components already normalize their own children. +function simpleNormalizeChildren (children) { + for (var i = 0; i < children.length; i++) { + if (Array.isArray(children[i])) { + return Array.prototype.concat.apply([], children) + } + } + return children +} + +// 2. When the children contains constrcuts that always generated nested Arrays, +// e.g.