/******/ (function(modules) { // webpackBootstrap /******/ var parentHotUpdateCallback = this["webpackHotUpdate"]; /******/ this["webpackHotUpdate"] = /******/ function webpackHotUpdateCallback(chunkId, moreModules) { // eslint-disable-line no-unused-vars /******/ hotAddUpdateChunk(chunkId, moreModules); /******/ if(parentHotUpdateCallback) parentHotUpdateCallback(chunkId, moreModules); /******/ } /******/ /******/ function hotDownloadUpdateChunk(chunkId) { // eslint-disable-line no-unused-vars /******/ var head = document.getElementsByTagName("head")[0]; /******/ var script = document.createElement("script"); /******/ script.type = "text/javascript"; /******/ script.charset = "utf-8"; /******/ script.src = __webpack_require__.p + "" + chunkId + "." + hotCurrentHash + ".hot-update.js"; /******/ head.appendChild(script); /******/ } /******/ /******/ function hotDownloadManifest(callback) { // eslint-disable-line no-unused-vars /******/ if(typeof XMLHttpRequest === "undefined") /******/ return callback(new Error("No browser support")); /******/ try { /******/ var request = new XMLHttpRequest(); /******/ var requestPath = __webpack_require__.p + "" + hotCurrentHash + ".hot-update.json"; /******/ request.open("GET", requestPath, true); /******/ request.timeout = 10000; /******/ request.send(null); /******/ } catch(err) { /******/ return callback(err); /******/ } /******/ request.onreadystatechange = function() { /******/ if(request.readyState !== 4) return; /******/ if(request.status === 0) { /******/ // timeout /******/ callback(new Error("Manifest request to " + requestPath + " timed out.")); /******/ } else if(request.status === 404) { /******/ // no update available /******/ callback(); /******/ } else if(request.status !== 200 && request.status !== 304) { /******/ // other failure /******/ callback(new Error("Manifest request to " + requestPath + " failed.")); /******/ } else { /******/ // success /******/ try { /******/ var update = JSON.parse(request.responseText); /******/ } catch(e) { /******/ callback(e); /******/ return; /******/ } /******/ callback(null, update); /******/ } /******/ }; /******/ } /******/ /******/ /******/ // Copied from https://github.com/facebook/react/blob/bef45b0/src/shared/utils/canDefineProperty.js /******/ var canDefineProperty = false; /******/ try { /******/ Object.defineProperty({}, "x", { /******/ get: function() {} /******/ }); /******/ canDefineProperty = true; /******/ } catch(x) { /******/ // IE will fail on defineProperty /******/ } /******/ /******/ var hotApplyOnUpdate = true; /******/ var hotCurrentHash = "df5ff963eab1d8f408b8"; // eslint-disable-line no-unused-vars /******/ var hotCurrentModuleData = {}; /******/ var hotCurrentParents = []; // eslint-disable-line no-unused-vars /******/ /******/ function hotCreateRequire(moduleId) { // eslint-disable-line no-unused-vars /******/ var me = installedModules[moduleId]; /******/ if(!me) return __webpack_require__; /******/ var fn = function(request) { /******/ if(me.hot.active) { /******/ if(installedModules[request]) { /******/ if(installedModules[request].parents.indexOf(moduleId) < 0) /******/ installedModules[request].parents.push(moduleId); /******/ if(me.children.indexOf(request) < 0) /******/ me.children.push(request); /******/ } else hotCurrentParents = [moduleId]; /******/ } else { /******/ console.warn("[HMR] unexpected require(" + request + ") from disposed module " + moduleId); /******/ hotCurrentParents = []; /******/ } /******/ return __webpack_require__(request); /******/ }; /******/ for(var name in __webpack_require__) { /******/ if(Object.prototype.hasOwnProperty.call(__webpack_require__, name)) { /******/ if(canDefineProperty) { /******/ Object.defineProperty(fn, name, (function(name) { /******/ return { /******/ configurable: true, /******/ enumerable: true, /******/ get: function() { /******/ return __webpack_require__[name]; /******/ }, /******/ set: function(value) { /******/ __webpack_require__[name] = value; /******/ } /******/ }; /******/ }(name))); /******/ } else { /******/ fn[name] = __webpack_require__[name]; /******/ } /******/ } /******/ } /******/ /******/ function ensure(chunkId, callback) { /******/ if(hotStatus === "ready") /******/ hotSetStatus("prepare"); /******/ hotChunksLoading++; /******/ __webpack_require__.e(chunkId, function() { /******/ try { /******/ callback.call(null, fn); /******/ } finally { /******/ finishChunkLoading(); /******/ } /******/ /******/ function finishChunkLoading() { /******/ hotChunksLoading--; /******/ if(hotStatus === "prepare") { /******/ if(!hotWaitingFilesMap[chunkId]) { /******/ hotEnsureUpdateChunk(chunkId); /******/ } /******/ if(hotChunksLoading === 0 && hotWaitingFiles === 0) { /******/ hotUpdateDownloaded(); /******/ } /******/ } /******/ } /******/ }); /******/ } /******/ if(canDefineProperty) { /******/ Object.defineProperty(fn, "e", { /******/ enumerable: true, /******/ value: ensure /******/ }); /******/ } else { /******/ fn.e = ensure; /******/ } /******/ return fn; /******/ } /******/ /******/ function hotCreateModule(moduleId) { // eslint-disable-line no-unused-vars /******/ var hot = { /******/ // private stuff /******/ _acceptedDependencies: {}, /******/ _declinedDependencies: {}, /******/ _selfAccepted: false, /******/ _selfDeclined: false, /******/ _disposeHandlers: [], /******/ /******/ // Module API /******/ active: true, /******/ accept: function(dep, callback) { /******/ if(typeof dep === "undefined") /******/ hot._selfAccepted = true; /******/ else if(typeof dep === "function") /******/ hot._selfAccepted = dep; /******/ else if(typeof dep === "object") /******/ for(var i = 0; i < dep.length; i++) /******/ hot._acceptedDependencies[dep[i]] = callback; /******/ else /******/ hot._acceptedDependencies[dep] = callback; /******/ }, /******/ decline: function(dep) { /******/ if(typeof dep === "undefined") /******/ hot._selfDeclined = true; /******/ else if(typeof dep === "number") /******/ hot._declinedDependencies[dep] = true; /******/ else /******/ for(var i = 0; i < dep.length; i++) /******/ hot._declinedDependencies[dep[i]] = true; /******/ }, /******/ dispose: function(callback) { /******/ hot._disposeHandlers.push(callback); /******/ }, /******/ addDisposeHandler: function(callback) { /******/ hot._disposeHandlers.push(callback); /******/ }, /******/ removeDisposeHandler: function(callback) { /******/ var idx = hot._disposeHandlers.indexOf(callback); /******/ if(idx >= 0) hot._disposeHandlers.splice(idx, 1); /******/ }, /******/ /******/ // Management API /******/ check: hotCheck, /******/ apply: hotApply, /******/ status: function(l) { /******/ if(!l) return hotStatus; /******/ hotStatusHandlers.push(l); /******/ }, /******/ addStatusHandler: function(l) { /******/ hotStatusHandlers.push(l); /******/ }, /******/ removeStatusHandler: function(l) { /******/ var idx = hotStatusHandlers.indexOf(l); /******/ if(idx >= 0) hotStatusHandlers.splice(idx, 1); /******/ }, /******/ /******/ //inherit from previous dispose call /******/ data: hotCurrentModuleData[moduleId] /******/ }; /******/ return hot; /******/ } /******/ /******/ var hotStatusHandlers = []; /******/ var hotStatus = "idle"; /******/ /******/ function hotSetStatus(newStatus) { /******/ hotStatus = newStatus; /******/ for(var i = 0; i < hotStatusHandlers.length; i++) /******/ hotStatusHandlers[i].call(null, newStatus); /******/ } /******/ /******/ // while downloading /******/ var hotWaitingFiles = 0; /******/ var hotChunksLoading = 0; /******/ var hotWaitingFilesMap = {}; /******/ var hotRequestedFilesMap = {}; /******/ var hotAvailibleFilesMap = {}; /******/ var hotCallback; /******/ /******/ // The update info /******/ var hotUpdate, hotUpdateNewHash; /******/ /******/ function toModuleId(id) { /******/ var isNumber = (+id) + "" === id; /******/ return isNumber ? +id : id; /******/ } /******/ /******/ function hotCheck(apply, callback) { /******/ if(hotStatus !== "idle") throw new Error("check() is only allowed in idle status"); /******/ if(typeof apply === "function") { /******/ hotApplyOnUpdate = false; /******/ callback = apply; /******/ } else { /******/ hotApplyOnUpdate = apply; /******/ callback = callback || function(err) { /******/ if(err) throw err; /******/ }; /******/ } /******/ hotSetStatus("check"); /******/ hotDownloadManifest(function(err, update) { /******/ if(err) return callback(err); /******/ if(!update) { /******/ hotSetStatus("idle"); /******/ callback(null, null); /******/ return; /******/ } /******/ /******/ hotRequestedFilesMap = {}; /******/ hotAvailibleFilesMap = {}; /******/ hotWaitingFilesMap = {}; /******/ for(var i = 0; i < update.c.length; i++) /******/ hotAvailibleFilesMap[update.c[i]] = true; /******/ hotUpdateNewHash = update.h; /******/ /******/ hotSetStatus("prepare"); /******/ hotCallback = callback; /******/ hotUpdate = {}; /******/ var chunkId = 0; /******/ { // eslint-disable-line no-lone-blocks /******/ /*globals chunkId */ /******/ hotEnsureUpdateChunk(chunkId); /******/ } /******/ if(hotStatus === "prepare" && hotChunksLoading === 0 && hotWaitingFiles === 0) { /******/ hotUpdateDownloaded(); /******/ } /******/ }); /******/ } /******/ /******/ function hotAddUpdateChunk(chunkId, moreModules) { // eslint-disable-line no-unused-vars /******/ if(!hotAvailibleFilesMap[chunkId] || !hotRequestedFilesMap[chunkId]) /******/ return; /******/ hotRequestedFilesMap[chunkId] = false; /******/ for(var moduleId in moreModules) { /******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { /******/ hotUpdate[moduleId] = moreModules[moduleId]; /******/ } /******/ } /******/ if(--hotWaitingFiles === 0 && hotChunksLoading === 0) { /******/ hotUpdateDownloaded(); /******/ } /******/ } /******/ /******/ function hotEnsureUpdateChunk(chunkId) { /******/ if(!hotAvailibleFilesMap[chunkId]) { /******/ hotWaitingFilesMap[chunkId] = true; /******/ } else { /******/ hotRequestedFilesMap[chunkId] = true; /******/ hotWaitingFiles++; /******/ hotDownloadUpdateChunk(chunkId); /******/ } /******/ } /******/ /******/ function hotUpdateDownloaded() { /******/ hotSetStatus("ready"); /******/ var callback = hotCallback; /******/ hotCallback = null; /******/ if(!callback) return; /******/ if(hotApplyOnUpdate) { /******/ hotApply(hotApplyOnUpdate, callback); /******/ } else { /******/ var outdatedModules = []; /******/ for(var id in hotUpdate) { /******/ if(Object.prototype.hasOwnProperty.call(hotUpdate, id)) { /******/ outdatedModules.push(toModuleId(id)); /******/ } /******/ } /******/ callback(null, outdatedModules); /******/ } /******/ } /******/ /******/ function hotApply(options, callback) { /******/ if(hotStatus !== "ready") throw new Error("apply() is only allowed in ready status"); /******/ if(typeof options === "function") { /******/ callback = options; /******/ options = {}; /******/ } else if(options && typeof options === "object") { /******/ callback = callback || function(err) { /******/ if(err) throw err; /******/ }; /******/ } else { /******/ options = {}; /******/ callback = callback || function(err) { /******/ if(err) throw err; /******/ }; /******/ } /******/ /******/ function getAffectedStuff(module) { /******/ var outdatedModules = [module]; /******/ var outdatedDependencies = {}; /******/ /******/ var queue = outdatedModules.slice(); /******/ while(queue.length > 0) { /******/ var moduleId = queue.pop(); /******/ var module = installedModules[moduleId]; /******/ if(!module || module.hot._selfAccepted) /******/ continue; /******/ if(module.hot._selfDeclined) { /******/ return new Error("Aborted because of self decline: " + moduleId); /******/ } /******/ if(moduleId === 0) { /******/ return; /******/ } /******/ for(var i = 0; i < module.parents.length; i++) { /******/ var parentId = module.parents[i]; /******/ var parent = installedModules[parentId]; /******/ if(parent.hot._declinedDependencies[moduleId]) { /******/ return new Error("Aborted because of declined dependency: " + moduleId + " in " + parentId); /******/ } /******/ if(outdatedModules.indexOf(parentId) >= 0) continue; /******/ if(parent.hot._acceptedDependencies[moduleId]) { /******/ if(!outdatedDependencies[parentId]) /******/ outdatedDependencies[parentId] = []; /******/ addAllToSet(outdatedDependencies[parentId], [moduleId]); /******/ continue; /******/ } /******/ delete outdatedDependencies[parentId]; /******/ outdatedModules.push(parentId); /******/ queue.push(parentId); /******/ } /******/ } /******/ /******/ return [outdatedModules, outdatedDependencies]; /******/ } /******/ /******/ function addAllToSet(a, b) { /******/ for(var i = 0; i < b.length; i++) { /******/ var item = b[i]; /******/ if(a.indexOf(item) < 0) /******/ a.push(item); /******/ } /******/ } /******/ /******/ // at begin all updates modules are outdated /******/ // the "outdated" status can propagate to parents if they don't accept the children /******/ var outdatedDependencies = {}; /******/ var outdatedModules = []; /******/ var appliedUpdate = {}; /******/ for(var id in hotUpdate) { /******/ if(Object.prototype.hasOwnProperty.call(hotUpdate, id)) { /******/ var moduleId = toModuleId(id); /******/ var result = getAffectedStuff(moduleId); /******/ if(!result) { /******/ if(options.ignoreUnaccepted) /******/ continue; /******/ hotSetStatus("abort"); /******/ return callback(new Error("Aborted because " + moduleId + " is not accepted")); /******/ } /******/ if(result instanceof Error) { /******/ hotSetStatus("abort"); /******/ return callback(result); /******/ } /******/ appliedUpdate[moduleId] = hotUpdate[moduleId]; /******/ addAllToSet(outdatedModules, result[0]); /******/ for(var moduleId in result[1]) { /******/ if(Object.prototype.hasOwnProperty.call(result[1], moduleId)) { /******/ if(!outdatedDependencies[moduleId]) /******/ outdatedDependencies[moduleId] = []; /******/ addAllToSet(outdatedDependencies[moduleId], result[1][moduleId]); /******/ } /******/ } /******/ } /******/ } /******/ /******/ // Store self accepted outdated modules to require them later by the module system /******/ var outdatedSelfAcceptedModules = []; /******/ for(var i = 0; i < outdatedModules.length; i++) { /******/ var moduleId = outdatedModules[i]; /******/ if(installedModules[moduleId] && installedModules[moduleId].hot._selfAccepted) /******/ outdatedSelfAcceptedModules.push({ /******/ module: moduleId, /******/ errorHandler: installedModules[moduleId].hot._selfAccepted /******/ }); /******/ } /******/ /******/ // Now in "dispose" phase /******/ hotSetStatus("dispose"); /******/ var queue = outdatedModules.slice(); /******/ while(queue.length > 0) { /******/ var moduleId = queue.pop(); /******/ var module = installedModules[moduleId]; /******/ if(!module) continue; /******/ /******/ var data = {}; /******/ /******/ // Call dispose handlers /******/ var disposeHandlers = module.hot._disposeHandlers; /******/ for(var j = 0; j < disposeHandlers.length; j++) { /******/ var cb = disposeHandlers[j]; /******/ cb(data); /******/ } /******/ hotCurrentModuleData[moduleId] = data; /******/ /******/ // disable module (this disables requires from this module) /******/ module.hot.active = false; /******/ /******/ // remove module from cache /******/ delete installedModules[moduleId]; /******/ /******/ // remove "parents" references from all children /******/ for(var j = 0; j < module.children.length; j++) { /******/ var child = installedModules[module.children[j]]; /******/ if(!child) continue; /******/ var idx = child.parents.indexOf(moduleId); /******/ if(idx >= 0) { /******/ child.parents.splice(idx, 1); /******/ } /******/ } /******/ } /******/ /******/ // remove outdated dependency from module children /******/ for(var moduleId in outdatedDependencies) { /******/ if(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) { /******/ var module = installedModules[moduleId]; /******/ var moduleOutdatedDependencies = outdatedDependencies[moduleId]; /******/ for(var j = 0; j < moduleOutdatedDependencies.length; j++) { /******/ var dependency = moduleOutdatedDependencies[j]; /******/ var idx = module.children.indexOf(dependency); /******/ if(idx >= 0) module.children.splice(idx, 1); /******/ } /******/ } /******/ } /******/ /******/ // Not in "apply" phase /******/ hotSetStatus("apply"); /******/ /******/ hotCurrentHash = hotUpdateNewHash; /******/ /******/ // insert new code /******/ for(var moduleId in appliedUpdate) { /******/ if(Object.prototype.hasOwnProperty.call(appliedUpdate, moduleId)) { /******/ modules[moduleId] = appliedUpdate[moduleId]; /******/ } /******/ } /******/ /******/ // call accept handlers /******/ var error = null; /******/ for(var moduleId in outdatedDependencies) { /******/ if(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) { /******/ var module = installedModules[moduleId]; /******/ var moduleOutdatedDependencies = outdatedDependencies[moduleId]; /******/ var callbacks = []; /******/ for(var i = 0; i < moduleOutdatedDependencies.length; i++) { /******/ var dependency = moduleOutdatedDependencies[i]; /******/ var cb = module.hot._acceptedDependencies[dependency]; /******/ if(callbacks.indexOf(cb) >= 0) continue; /******/ callbacks.push(cb); /******/ } /******/ for(var i = 0; i < callbacks.length; i++) { /******/ var cb = callbacks[i]; /******/ try { /******/ cb(outdatedDependencies); /******/ } catch(err) { /******/ if(!error) /******/ error = err; /******/ } /******/ } /******/ } /******/ } /******/ /******/ // Load self accepted modules /******/ for(var i = 0; i < outdatedSelfAcceptedModules.length; i++) { /******/ var item = outdatedSelfAcceptedModules[i]; /******/ var moduleId = item.module; /******/ hotCurrentParents = [moduleId]; /******/ try { /******/ __webpack_require__(moduleId); /******/ } catch(err) { /******/ if(typeof item.errorHandler === "function") { /******/ try { /******/ item.errorHandler(err); /******/ } catch(err) { /******/ if(!error) /******/ error = err; /******/ } /******/ } else if(!error) /******/ error = err; /******/ } /******/ } /******/ /******/ // handle errors in accept handlers and self accepted module load /******/ if(error) { /******/ hotSetStatus("fail"); /******/ return callback(error); /******/ } /******/ /******/ hotSetStatus("idle"); /******/ callback(null, outdatedModules); /******/ } /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false, /******/ hot: hotCreateModule(moduleId), /******/ parents: hotCurrentParents, /******/ children: [] /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId)); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // __webpack_hash__ /******/ __webpack_require__.h = function() { return hotCurrentHash; }; /******/ // Load entry module and return exports /******/ return hotCreateRequire(0)(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var riot = __webpack_require__(1); // Provide some settings riot.settings.brackets = '{{ }}'; // Get application tag and mount it! Yeah baby! __webpack_require__(3); riot.mount('app'); // Router __webpack_require__(33); // SASS __webpack_require__(52); __webpack_require__(54); __webpack_require__(56); /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;/* Riot v2.6.8, @license MIT */ ;(function(window, undefined) { 'use strict'; var riot = { version: 'v2.6.8', settings: {} }, // be aware, internal usage // ATTENTION: prefix the global dynamic variables with `__` // counter to give a unique id to all the Tag instances __uid = 0, // tags instances cache __virtualDom = [], // tags implementation cache __tagImpl = {}, /** * Const */ GLOBAL_MIXIN = '__global_mixin', // riot specific prefixes RIOT_PREFIX = 'riot-', RIOT_TAG = RIOT_PREFIX + 'tag', RIOT_TAG_IS = 'data-is', // for typeof == '' comparisons T_STRING = 'string', T_OBJECT = 'object', T_UNDEF = 'undefined', T_FUNCTION = 'function', XLINK_NS = 'http://www.w3.org/1999/xlink', XLINK_REGEX = /^xlink:(\w+)/, // special native tags that cannot be treated like the others SPECIAL_TAGS_REGEX = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?|opt(?:ion|group))$/, RESERVED_WORDS_BLACKLIST = /^(?:_(?:item|id|parent)|update|root|(?:un)?mount|mixin|is(?:Mounted|Loop)|tags|parent|opts|trigger|o(?:n|ff|ne))$/, // SVG tags list https://www.w3.org/TR/SVG/attindex.html#PresentationAttributes SVG_TAGS_LIST = ['altGlyph', 'animate', 'animateColor', 'circle', 'clipPath', 'defs', 'ellipse', 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feFlood', 'feGaussianBlur', 'feImage', 'feMerge', 'feMorphology', 'feOffset', 'feSpecularLighting', 'feTile', 'feTurbulence', 'filter', 'font', 'foreignObject', 'g', 'glyph', 'glyphRef', 'image', 'line', 'linearGradient', 'marker', 'mask', 'missing-glyph', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'svg', 'switch', 'symbol', 'text', 'textPath', 'tref', 'tspan', 'use'], // version# for IE 8-11, 0 for others IE_VERSION = (window && window.document || {}).documentMode | 0, // detect firefox to fix #1374 FIREFOX = window && !!window.InstallTrigger /* istanbul ignore next */ riot.observable = function(el) { /** * Extend the original object or create a new empty one * @type { Object } */ el = el || {} /** * Private variables */ var callbacks = {}, slice = Array.prototype.slice /** * Private Methods */ /** * Helper function needed to get and loop all the events in a string * @param { String } e - event string * @param {Function} fn - callback */ function onEachEvent(e, fn) { var es = e.split(' '), l = es.length, i = 0 for (; i < l; i++) { var name = es[i] if (name) fn(name, i) } } /** * Public Api */ // extend the el object adding the observable methods Object.defineProperties(el, { /** * Listen to the given space separated list of `events` and * execute the `callback` each time an event is triggered. * @param { String } events - events ids * @param { Function } fn - callback function * @returns { Object } el */ on: { value: function(events, fn) { if (typeof fn != 'function') return el onEachEvent(events, function(name, pos) { (callbacks[name] = callbacks[name] || []).push(fn) fn.typed = pos > 0 }) return el }, enumerable: false, writable: false, configurable: false }, /** * Removes the given space separated list of `events` listeners * @param { String } events - events ids * @param { Function } fn - callback function * @returns { Object } el */ off: { value: function(events, fn) { if (events == '*' && !fn) callbacks = {} else { onEachEvent(events, function(name, pos) { if (fn) { var arr = callbacks[name] for (var i = 0, cb; cb = arr && arr[i]; ++i) { if (cb == fn) arr.splice(i--, 1) } } else delete callbacks[name] }) } return el }, enumerable: false, writable: false, configurable: false }, /** * Listen to the given space separated list of `events` and * execute the `callback` at most once * @param { String } events - events ids * @param { Function } fn - callback function * @returns { Object } el */ one: { value: function(events, fn) { function on() { el.off(events, on) fn.apply(el, arguments) } return el.on(events, on) }, enumerable: false, writable: false, configurable: false }, /** * Execute all callback functions that listen to * the given space separated list of `events` * @param { String } events - events ids * @returns { Object } el */ trigger: { value: function(events) { // getting the arguments var arglen = arguments.length - 1, args = new Array(arglen), fns for (var i = 0; i < arglen; i++) { args[i] = arguments[i + 1] // skip first argument } onEachEvent(events, function(name, pos) { fns = slice.call(callbacks[name] || [], 0) for (var i = 0, fn; fn = fns[i]; ++i) { if (fn.busy) continue fn.busy = 1 fn.apply(el, fn.typed ? [name].concat(args) : args) if (fns[i] !== fn) { i-- } fn.busy = 0 } if (callbacks['*'] && name != '*') el.trigger.apply(el, ['*', name].concat(args)) }) return el }, enumerable: false, writable: false, configurable: false } }) return el } /* istanbul ignore next */ ;(function(riot) { /** * Simple client-side router * @module riot-route */ var RE_ORIGIN = /^.+?\/\/+[^\/]+/, EVENT_LISTENER = 'EventListener', REMOVE_EVENT_LISTENER = 'remove' + EVENT_LISTENER, ADD_EVENT_LISTENER = 'add' + EVENT_LISTENER, HAS_ATTRIBUTE = 'hasAttribute', REPLACE = 'replace', POPSTATE = 'popstate', HASHCHANGE = 'hashchange', TRIGGER = 'trigger', MAX_EMIT_STACK_LEVEL = 3, win = typeof window != 'undefined' && window, doc = typeof document != 'undefined' && document, hist = win && history, loc = win && (hist.location || win.location), // see html5-history-api prot = Router.prototype, // to minify more clickEvent = doc && doc.ontouchstart ? 'touchstart' : 'click', started = false, central = riot.observable(), routeFound = false, debouncedEmit, base, current, parser, secondParser, emitStack = [], emitStackLevel = 0 /** * Default parser. You can replace it via router.parser method. * @param {string} path - current path (normalized) * @returns {array} array */ function DEFAULT_PARSER(path) { return path.split(/[/?#]/) } /** * Default parser (second). You can replace it via router.parser method. * @param {string} path - current path (normalized) * @param {string} filter - filter string (normalized) * @returns {array} array */ function DEFAULT_SECOND_PARSER(path, filter) { var re = new RegExp('^' + filter[REPLACE](/\*/g, '([^/?#]+?)')[REPLACE](/\.\./, '.*') + '$'), args = path.match(re) if (args) return args.slice(1) } /** * Simple/cheap debounce implementation * @param {function} fn - callback * @param {number} delay - delay in seconds * @returns {function} debounced function */ function debounce(fn, delay) { var t return function () { clearTimeout(t) t = setTimeout(fn, delay) } } /** * Set the window listeners to trigger the routes * @param {boolean} autoExec - see route.start */ function start(autoExec) { debouncedEmit = debounce(emit, 1) win[ADD_EVENT_LISTENER](POPSTATE, debouncedEmit) win[ADD_EVENT_LISTENER](HASHCHANGE, debouncedEmit) doc[ADD_EVENT_LISTENER](clickEvent, click) if (autoExec) emit(true) } /** * Router class */ function Router() { this.$ = [] riot.observable(this) // make it observable central.on('stop', this.s.bind(this)) central.on('emit', this.e.bind(this)) } function normalize(path) { return path[REPLACE](/^\/|\/$/, '') } function isString(str) { return typeof str == 'string' } /** * Get the part after domain name * @param {string} href - fullpath * @returns {string} path from root */ function getPathFromRoot(href) { return (href || loc.href)[REPLACE](RE_ORIGIN, '') } /** * Get the part after base * @param {string} href - fullpath * @returns {string} path from base */ function getPathFromBase(href) { return base[0] == '#' ? (href || loc.href || '').split(base)[1] || '' : (loc ? getPathFromRoot(href) : href || '')[REPLACE](base, '') } function emit(force) { // the stack is needed for redirections var isRoot = emitStackLevel == 0, first if (MAX_EMIT_STACK_LEVEL <= emitStackLevel) return emitStackLevel++ emitStack.push(function() { var path = getPathFromBase() if (force || path != current) { central[TRIGGER]('emit', path) current = path } }) if (isRoot) { while (first = emitStack.shift()) first() // stack increses within this call emitStackLevel = 0 } } function click(e) { if ( e.which != 1 // not left click || e.metaKey || e.ctrlKey || e.shiftKey // or meta keys || e.defaultPrevented // or default prevented ) return var el = e.target while (el && el.nodeName != 'A') el = el.parentNode if ( !el || el.nodeName != 'A' // not A tag || el[HAS_ATTRIBUTE]('download') // has download attr || !el[HAS_ATTRIBUTE]('href') // has no href attr || el.target && el.target != '_self' // another window or frame || el.href.indexOf(loc.href.match(RE_ORIGIN)[0]) == -1 // cross origin ) return if (el.href != loc.href && ( el.href.split('#')[0] == loc.href.split('#')[0] // internal jump || base[0] != '#' && getPathFromRoot(el.href).indexOf(base) !== 0 // outside of base || base[0] == '#' && el.href.split(base)[0] != loc.href.split(base)[0] // outside of #base || !go(getPathFromBase(el.href), el.title || doc.title) // route not found )) return e.preventDefault() } /** * Go to the path * @param {string} path - destination path * @param {string} title - page title * @param {boolean} shouldReplace - use replaceState or pushState * @returns {boolean} - route not found flag */ function go(path, title, shouldReplace) { // Server-side usage: directly execute handlers for the path if (!hist) return central[TRIGGER]('emit', getPathFromBase(path)) path = base + normalize(path) title = title || doc.title // browsers ignores the second parameter `title` shouldReplace ? hist.replaceState(null, title, path) : hist.pushState(null, title, path) // so we need to set it manually doc.title = title routeFound = false emit() return routeFound } /** * Go to path or set action * a single string: go there * two strings: go there with setting a title * two strings and boolean: replace history with setting a title * a single function: set an action on the default route * a string/RegExp and a function: set an action on the route * @param {(string|function)} first - path / action / filter * @param {(string|RegExp|function)} second - title / action * @param {boolean} third - replace flag */ prot.m = function(first, second, third) { if (isString(first) && (!second || isString(second))) go(first, second, third || false) else if (second) this.r(first, second) else this.r('@', first) } /** * Stop routing */ prot.s = function() { this.off('*') this.$ = [] } /** * Emit * @param {string} path - path */ prot.e = function(path) { this.$.concat('@').some(function(filter) { var args = (filter == '@' ? parser : secondParser)(normalize(path), normalize(filter)) if (typeof args != 'undefined') { this[TRIGGER].apply(null, [filter].concat(args)) return routeFound = true // exit from loop } }, this) } /** * Register route * @param {string} filter - filter for matching to url * @param {function} action - action to register */ prot.r = function(filter, action) { if (filter != '@') { filter = '/' + normalize(filter) this.$.push(filter) } this.on(filter, action) } var mainRouter = new Router() var route = mainRouter.m.bind(mainRouter) /** * Create a sub router * @returns {function} the method of a new Router object */ route.create = function() { var newSubRouter = new Router() // assign sub-router's main method var router = newSubRouter.m.bind(newSubRouter) // stop only this sub-router router.stop = newSubRouter.s.bind(newSubRouter) return router } /** * Set the base of url * @param {(str|RegExp)} arg - a new base or '#' or '#!' */ route.base = function(arg) { base = arg || '#' current = getPathFromBase() // recalculate current path } /** Exec routing right now **/ route.exec = function() { emit(true) } /** * Replace the default router to yours * @param {function} fn - your parser function * @param {function} fn2 - your secondParser function */ route.parser = function(fn, fn2) { if (!fn && !fn2) { // reset parser for testing... parser = DEFAULT_PARSER secondParser = DEFAULT_SECOND_PARSER } if (fn) parser = fn if (fn2) secondParser = fn2 } /** * Helper function to get url query as an object * @returns {object} parsed query */ route.query = function() { var q = {} var href = loc.href || current href[REPLACE](/[?&](.+?)=([^&]*)/g, function(_, k, v) { q[k] = v }) return q } /** Stop routing **/ route.stop = function () { if (started) { if (win) { win[REMOVE_EVENT_LISTENER](POPSTATE, debouncedEmit) win[REMOVE_EVENT_LISTENER](HASHCHANGE, debouncedEmit) doc[REMOVE_EVENT_LISTENER](clickEvent, click) } central[TRIGGER]('stop') started = false } } /** * Start routing * @param {boolean} autoExec - automatically exec after starting if true */ route.start = function (autoExec) { if (!started) { if (win) { if (document.readyState == 'complete') start(autoExec) // the timeout is needed to solve // a weird safari bug https://github.com/riot/route/issues/33 else win[ADD_EVENT_LISTENER]('load', function() { setTimeout(function() { start(autoExec) }, 1) }) } started = true } } /** Prepare the router **/ route.base() route.parser() riot.route = route })(riot) /* istanbul ignore next */ /** * The riot template engine * @version v2.4.2 */ /** * riot.util.brackets * * - `brackets ` - Returns a string or regex based on its parameter * - `brackets.set` - Change the current riot brackets * * @module */ var brackets = (function (UNDEF) { var REGLOB = 'g', R_MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g, R_STRINGS = /"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'/g, S_QBLOCKS = R_STRINGS.source + '|' + /(?:\breturn\s+|(?:[$\w\)\]]|\+\+|--)\s*(\/)(?![*\/]))/.source + '|' + /\/(?=[^*\/])[^[\/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[\/\\]*)*?(\/)[gim]*/.source, UNSUPPORTED = RegExp('[\\' + 'x00-\\x1F<>a-zA-Z0-9\'",;\\\\]'), NEED_ESCAPE = /(?=[[\]()*+?.^$|])/g, FINDBRACES = { '(': RegExp('([()])|' + S_QBLOCKS, REGLOB), '[': RegExp('([[\\]])|' + S_QBLOCKS, REGLOB), '{': RegExp('([{}])|' + S_QBLOCKS, REGLOB) }, DEFAULT = '{ }' var _pairs = [ '{', '}', '{', '}', /{[^}]*}/, /\\([{}])/g, /\\({)|{/g, RegExp('\\\\(})|([[({])|(})|' + S_QBLOCKS, REGLOB), DEFAULT, /^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/, /(^|[^\\]){=[\S\s]*?}/ ] var cachedBrackets = UNDEF, _regex, _cache = [], _settings function _loopback (re) { return re } function _rewrite (re, bp) { if (!bp) bp = _cache return new RegExp( re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : '' ) } function _create (pair) { if (pair === DEFAULT) return _pairs var arr = pair.split(' ') if (arr.length !== 2 || UNSUPPORTED.test(pair)) { throw new Error('Unsupported brackets "' + pair + '"') } arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' ')) arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr) arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr) arr[6] = _rewrite(_pairs[6], arr) arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB) arr[8] = pair return arr } function _brackets (reOrIdx) { return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx] } _brackets.split = function split (str, tmpl, _bp) { // istanbul ignore next: _bp is for the compiler if (!_bp) _bp = _cache var parts = [], match, isexpr, start, pos, re = _bp[6] isexpr = start = re.lastIndex = 0 while ((match = re.exec(str))) { pos = match.index if (isexpr) { if (match[2]) { re.lastIndex = skipBraces(str, match[2], re.lastIndex) continue } if (!match[3]) { continue } } if (!match[1]) { unescapeStr(str.slice(start, pos)) start = re.lastIndex re = _bp[6 + (isexpr ^= 1)] re.lastIndex = start } } if (str && start < str.length) { unescapeStr(str.slice(start)) } return parts function unescapeStr (s) { if (tmpl || isexpr) { parts.push(s && s.replace(_bp[5], '$1')) } else { parts.push(s) } } function skipBraces (s, ch, ix) { var match, recch = FINDBRACES[ch] recch.lastIndex = ix ix = 1 while ((match = recch.exec(s))) { if (match[1] && !(match[1] === ch ? ++ix : --ix)) break } return ix ? s.length : recch.lastIndex } } _brackets.hasExpr = function hasExpr (str) { return _cache[4].test(str) } _brackets.loopKeys = function loopKeys (expr) { var m = expr.match(_cache[9]) return m ? { key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] } : { val: expr.trim() } } _brackets.array = function array (pair) { return pair ? _create(pair) : _cache } function _reset (pair) { if ((pair || (pair = DEFAULT)) !== _cache[8]) { _cache = _create(pair) _regex = pair === DEFAULT ? _loopback : _rewrite _cache[9] = _regex(_pairs[9]) } cachedBrackets = pair } function _setSettings (o) { var b o = o || {} b = o.brackets Object.defineProperty(o, 'brackets', { set: _reset, get: function () { return cachedBrackets }, enumerable: true }) _settings = o _reset(b) } Object.defineProperty(_brackets, 'settings', { set: _setSettings, get: function () { return _settings } }) /* istanbul ignore next: in the browser riot is always in the scope */ _brackets.settings = typeof riot !== 'undefined' && riot.settings || {} _brackets.set = _reset _brackets.R_STRINGS = R_STRINGS _brackets.R_MLCOMMS = R_MLCOMMS _brackets.S_QBLOCKS = S_QBLOCKS return _brackets })() /** * @module tmpl * * tmpl - Root function, returns the template value, render with data * tmpl.hasExpr - Test the existence of a expression inside a string * tmpl.loopKeys - Get the keys for an 'each' loop (used by `_each`) */ var tmpl = (function () { var _cache = {} function _tmpl (str, data) { if (!str) return str return (_cache[str] || (_cache[str] = _create(str))).call(data, _logErr) } _tmpl.haveRaw = brackets.hasRaw _tmpl.hasExpr = brackets.hasExpr _tmpl.loopKeys = brackets.loopKeys // istanbul ignore next _tmpl.clearCache = function () { _cache = {} } _tmpl.errorHandler = null function _logErr (err, ctx) { if (_tmpl.errorHandler) { err.riotData = { tagName: ctx && ctx.root && ctx.root.tagName, _riot_id: ctx && ctx._riot_id //eslint-disable-line camelcase } _tmpl.errorHandler(err) } } function _create (str) { var expr = _getTmpl(str) if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr return new Function('E', expr + ';') // eslint-disable-line no-new-func } var CH_IDEXPR = String.fromCharCode(0x2057), RE_CSNAME = /^(?:(-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*)|\u2057(\d+)~):/, RE_QBLOCK = RegExp(brackets.S_QBLOCKS, 'g'), RE_DQUOTE = /\u2057/g, RE_QBMARK = /\u2057(\d+)~/g function _getTmpl (str) { var qstr = [], expr, parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1) if (parts.length > 2 || parts[0]) { var i, j, list = [] for (i = j = 0; i < parts.length; ++i) { expr = parts[i] if (expr && (expr = i & 1 ? _parseExpr(expr, 1, qstr) : '"' + expr .replace(/\\/g, '\\\\') .replace(/\r\n?|\n/g, '\\n') .replace(/"/g, '\\"') + '"' )) list[j++] = expr } expr = j < 2 ? list[0] : '[' + list.join(',') + '].join("")' } else { expr = _parseExpr(parts[1], 0, qstr) } if (qstr[0]) { expr = expr.replace(RE_QBMARK, function (_, pos) { return qstr[pos] .replace(/\r/g, '\\r') .replace(/\n/g, '\\n') }) } return expr } var RE_BREND = { '(': /[()]/g, '[': /[[\]]/g, '{': /[{}]/g } function _parseExpr (expr, asText, qstr) { expr = expr .replace(RE_QBLOCK, function (s, div) { return s.length > 2 && !div ? CH_IDEXPR + (qstr.push(s) - 1) + '~' : s }) .replace(/\s+/g, ' ').trim() .replace(/\ ?([[\({},?\.:])\ ?/g, '$1') if (expr) { var list = [], cnt = 0, match while (expr && (match = expr.match(RE_CSNAME)) && !match.index ) { var key, jsb, re = /,|([[{(])|$/g expr = RegExp.rightContext key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1] while (jsb = (match = re.exec(expr))[1]) skipBraces(jsb, re) jsb = expr.slice(0, match.index) expr = RegExp.rightContext list[cnt++] = _wrapExpr(jsb, 1, key) } expr = !cnt ? _wrapExpr(expr, asText) : cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0] } return expr function skipBraces (ch, re) { var mm, lv = 1, ir = RE_BREND[ch] ir.lastIndex = re.lastIndex while (mm = ir.exec(expr)) { if (mm[0] === ch) ++lv else if (!--lv) break } re.lastIndex = lv ? expr.length : ir.lastIndex } } // istanbul ignore next: not both var // eslint-disable-next-line max-len JS_CONTEXT = '"in this?this:' + (typeof window !== 'object' ? 'global' : 'window') + ').', JS_VARNAME = /[,{][\$\w]+(?=:)|(^ *|[^$\w\.{])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g, JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/ function _wrapExpr (expr, asText, key) { var tb expr = expr.replace(JS_VARNAME, function (match, p, mvar, pos, s) { if (mvar) { pos = tb ? 0 : pos + match.length if (mvar !== 'this' && mvar !== 'global' && mvar !== 'window') { match = p + '("' + mvar + JS_CONTEXT + mvar if (pos) tb = (s = s[pos]) === '.' || s === '(' || s === '[' } else if (pos) { tb = !JS_NOPROPS.test(s.slice(pos)) } } return match }) if (tb) { expr = 'try{return ' + expr + '}catch(e){E(e,this)}' } if (key) { expr = (tb ? 'function(){' + expr + '}.call(this)' : '(' + expr + ')' ) + '?"' + key + '":""' } else if (asText) { expr = 'function(v){' + (tb ? expr.replace('return ', 'v=') : 'v=(' + expr + ')' ) + ';return v||v===0?v:""}.call(this)' } return expr } _tmpl.version = brackets.version = 'v2.4.2' return _tmpl })() /* lib/browser/tag/mkdom.js Includes hacks needed for the Internet Explorer version 9 and below See: http://kangax.github.io/compat-table/es5/#ie8 http://codeplanet.io/dropping-ie8/ */ var mkdom = (function _mkdom() { var reHasYield = /|>([\S\s]*?)<\/yield\s*>|>)/ig, reYieldSrc = /]*)['"]\s*>([\S\s]*?)<\/yield\s*>/ig, reYieldDest = /|>([\S\s]*?)<\/yield\s*>)/ig var rootEls = { tr: 'tbody', th: 'tr', td: 'tr', col: 'colgroup' }, tblTags = IE_VERSION && IE_VERSION < 10 ? SPECIAL_TAGS_REGEX : /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?)$/ /** * Creates a DOM element to wrap the given content. Normally an `DIV`, but can be * also a `TABLE`, `SELECT`, `TBODY`, `TR`, or `COLGROUP` element. * * @param { String } templ - The template coming from the custom tag definition * @param { String } [html] - HTML content that comes from the DOM element where you * will mount the tag, mostly the original tag in the page * @param { Boolean } checkSvg - flag needed to know if we need to force the svg rendering in case of loop nodes * @returns {HTMLElement} DOM element with _templ_ merged through `YIELD` with the _html_. */ function _mkdom(templ, html, checkSvg) { var match = templ && templ.match(/^\s*<([-\w]+)/), tagName = match && match[1].toLowerCase(), el = mkEl('div', checkSvg && isSVGTag(tagName)) // replace all the yield tags with the tag inner html templ = replaceYield(templ, html) /* istanbul ignore next */ if (tblTags.test(tagName)) el = specialTags(el, templ, tagName) else setInnerHTML(el, templ) el.stub = true return el } /* Creates the root element for table or select child elements: tr/th/td/thead/tfoot/tbody/caption/col/colgroup/option/optgroup */ function specialTags(el, templ, tagName) { var select = tagName[0] === 'o', parent = select ? 'select>' : 'table>' // trim() is important here, this ensures we don't have artifacts, // so we can check if we have only one element inside the parent el.innerHTML = '<' + parent + templ.trim() + ' j) { t = tags[--i] tags.splice(i, 1) t.unmount() } } /** * Move the nested custom tags in non custom loop tags * @param { Object } child - non custom loop tag * @param { Number } i - current position of the loop tag */ function moveNestedTags(child, i) { Object.keys(child.tags).forEach(function(tagName) { var tag = child.tags[tagName] if (isArray(tag)) each(tag, function (t) { moveChildTag(t, tagName, i) }) else moveChildTag(tag, tagName, i) }) } /** * Adds the elements for a virtual tag * @param { Tag } tag - the tag whose root's children will be inserted or appended * @param { Node } src - the node that will do the inserting or appending * @param { Tag } target - only if inserting, insert before this tag's first child */ function addVirtual(tag, src, target) { var el = tag._root, sib tag._virts = [] while (el) { sib = el.nextSibling if (target) src.insertBefore(el, target._root) else src.appendChild(el) tag._virts.push(el) // hold for unmounting el = sib } } /** * Move virtual tag and all child nodes * @param { Tag } tag - first child reference used to start move * @param { Node } src - the node that will do the inserting * @param { Tag } target - insert before this tag's first child * @param { Number } len - how many child nodes to move */ function moveVirtual(tag, src, target, len) { var el = tag._root, sib, i = 0 for (; i < len; i++) { sib = el.nextSibling src.insertBefore(el, target._root) el = sib } } /** * Insert a new tag avoiding the insert for the conditional tags * @param {Boolean} isVirtual [description] * @param { Tag } prevTag - tag instance used as reference to prepend our new tag * @param { Tag } newTag - new tag to be inserted * @param { HTMLElement } root - loop parent node * @param { Array } tags - array containing the current tags list * @param { Function } virtualFn - callback needed to move or insert virtual DOM * @param { Object } dom - DOM node we need to loop */ function insertTag(isVirtual, prevTag, newTag, root, tags, virtualFn, dom) { if (isInStub(prevTag.root)) return if (isVirtual) virtualFn(prevTag, root, newTag, dom.childNodes.length) else root.insertBefore(prevTag.root, newTag.root) // #1374 some browsers reset selected here } /** * Manage tags having the 'each' * @param { Object } dom - DOM node we need to loop * @param { Tag } parent - parent tag instance where the dom node is contained * @param { String } expr - string contained in the 'each' attribute */ function _each(dom, parent, expr) { // remove the each property from the original tag remAttr(dom, 'each') var mustReorder = typeof getAttr(dom, 'no-reorder') !== T_STRING || remAttr(dom, 'no-reorder'), tagName = getTagName(dom), impl = __tagImpl[tagName] || { tmpl: getOuterHTML(dom) }, useRoot = SPECIAL_TAGS_REGEX.test(tagName), root = dom.parentNode, ref = document.createTextNode(''), child = getTag(dom), isOption = tagName.toLowerCase() === 'option', // the option tags must be treated differently tags = [], oldItems = [], hasKeys, isVirtual = dom.tagName == 'VIRTUAL' // parse the each expression expr = tmpl.loopKeys(expr) // insert a marked where the loop tags will be injected root.insertBefore(ref, dom) // clean template code parent.one('before-mount', function () { // remove the original DOM node dom.parentNode.removeChild(dom) if (root.stub) root = parent.root }).on('update', function () { // get the new items collection var items = tmpl(expr.val, parent), // create a fragment to hold the new DOM nodes to inject in the parent tag frag = document.createDocumentFragment() // object loop. any changes cause full redraw if (!isArray(items)) { hasKeys = items || false items = hasKeys ? Object.keys(items).map(function (key) { return mkitem(expr, key, items[key]) }) : [] } // loop all the new items var i = 0, itemsLength = items.length for (; i < itemsLength; i++) { // reorder only if the items are objects var item = items[i], _mustReorder = mustReorder && typeof item == T_OBJECT && !hasKeys, oldPos = oldItems.indexOf(item), pos = ~oldPos && _mustReorder ? oldPos : i, // does a tag exist in this position? tag = tags[pos] item = !hasKeys && expr.key ? mkitem(expr, item, i) : item // new tag if ( !_mustReorder && !tag // with no-reorder we just update the old tags || _mustReorder && !~oldPos || !tag // by default we always try to reorder the DOM elements ) { tag = new Tag(impl, { parent: parent, isLoop: true, hasImpl: !!__tagImpl[tagName], root: useRoot ? root : dom.cloneNode(), item: item }, dom.innerHTML) tag.mount() if (isVirtual) tag._root = tag.root.firstChild // save reference for further moves or inserts // this tag must be appended if (i == tags.length || !tags[i]) { // fix 1581 if (isVirtual) addVirtual(tag, frag) else frag.appendChild(tag.root) } // this tag must be insert else { insertTag(isVirtual, tag, tags[i], root, tags, addVirtual, dom) oldItems.splice(i, 0, item) } tags.splice(i, 0, tag) pos = i // handled here so no move } else tag.update(item, true) // reorder the tag if it's not located in its previous position if ( pos !== i && _mustReorder && tags[i] // fix 1581 unable to reproduce it in a test! ) { // #closes 2040 PLEASE DON'T REMOVE IT! // there are no tests for this feature if (contains(items, oldItems[i])) insertTag(isVirtual, tag, tags[i], root, tags, moveVirtual, dom) // update the position attribute if it exists if (expr.pos) tag[expr.pos] = i // move the old tag instance tags.splice(i, 0, tags.splice(pos, 1)[0]) // move the old item oldItems.splice(i, 0, oldItems.splice(pos, 1)[0]) // if the loop tags are not custom // we need to move all their custom tags into the right position if (!child && tag.tags) moveNestedTags(tag, i) } // cache the original item to use it in the events bound to this node // and its children tag._item = item // cache the real parent tag internally defineProperty(tag, '_parent', parent) } // remove the redundant tags unmountRedundant(items, tags) // insert the new nodes root.insertBefore(frag, ref) if (isOption) { // #1374 FireFox bug in