From bb165ca19931d165cf672ce42dbb23f934867d1e Mon Sep 17 00:00:00 2001 From: davidyang Date: Wed, 11 Nov 2015 19:02:40 +0800 Subject: [PATCH] ranks --- css/main.css | 47 +- data.html | 46 + hiho-resolver.js | 3 +- index.html | 38 +- js/main.js | 259 +- libs/js/jquery.scrollTo.min.js | 7 + libs/js/vue.1.js | 10374 +++++++++++++++++++++++++++++++ libs/js/vue.product.js | 10198 ++++++++++++++++++++++++++++++ 8 files changed, 20864 insertions(+), 108 deletions(-) create mode 100644 data.html create mode 100755 libs/js/jquery.scrollTo.min.js create mode 100644 libs/js/vue.1.js create mode 100644 libs/js/vue.product.js diff --git a/css/main.css b/css/main.css index b2377b7..d77c40c 100755 --- a/css/main.css +++ b/css/main.css @@ -24,27 +24,50 @@ .solved, .penalty { float: right; } +.rank, .solved, .penalty { + font-size: 20px; + text-align: center; + vertical-align: middle; + line-height: 50px; +} .rank-list-item { border-bottom: 1px solid #31708F; padding: 10px; + position: relative; } -.status-solved { +.ac { background-color: #5cb85c; } -.status-wrong { +.failed, .WA { background-color: #a94442; } -.status-no-try { +.frozen { background-color: #8a6d3b; } -.status-unknow { - background-color: #999; +.untouched { + background-color: #31708f; + color: #31708F; } -.seleted-rank { + +.selected { background-color: #337AB7; } +.uncover { + animation: flashing 300ms infinite; + -webkit-animation: flashing 30ms infinite; /*Safari and Chrome*/ +} + +@keyframes flashing { + from { background-color: #8a6d3b } + to { background-color: #BD995B } +} + +@-webkit-keyframes flashing {/*Safari and Chrome*/ + from { background-color: #8a6d3b } + to { background-color: #BD995B } +} /* index @@ -55,8 +78,8 @@ height: 50px; text-align: center; vertical-align: middle; - font-size: 20px; line-height: 50px; + margin-right: 15px; } .name { font-size: 18px; @@ -68,10 +91,14 @@ padding: 0; font-size: 12px; } -.problems li { - padding: 3px 10px; - border: 1px solid #ccc; +.problems .item { + padding: 2px; margin-right: 10px; + width: 80px; + text-align: center; +} +.problems .item .p-content { + padding: 1px 0; } .solved { width: 100px; diff --git a/data.html b/data.html new file mode 100644 index 0000000..150549f --- /dev/null +++ b/data.html @@ -0,0 +1,46 @@ + + + + + + The 2015 ACM-ICPC Asia Beijing Regional Contest + + + + + + + + +
{{ $data | json }}
+ + + + + + + + + + + + \ No newline at end of file diff --git a/hiho-resolver.js b/hiho-resolver.js index 404a5f2..5ab8de6 100644 --- a/hiho-resolver.js +++ b/hiho-resolver.js @@ -81,7 +81,8 @@ Resolver.prototype.calcOperations = function() { } return b.score - a.score; }); - this.rank_frozen = $.extend(true, {}, this.rank2); + this.rank2.length = 20; + this.rank_frozen = $.extend(true, [], this.rank2); for(var i = this.rank2.length - 1; i >= 0; i--) { var flag = true; while(flag) { diff --git a/index.html b/index.html index 8716e08..548247e 100755 --- a/index.html +++ b/index.html @@ -26,45 +26,37 @@ -
-
-
{{ team.rank }}
+
+
+
{{ $index+1 }}
-
{{ team.name }}
-
    -
  • {{p.index}}
  • +
    {{ users[team.user_id].college }}--{{ users[team.user_id].name }}
    +
      +
    • +
      {{team.problem[n+1] | problemStatus}}
      +
-
{{team.penalty}}
-
{{team.solved}}
- +
{{ team.penalty | toMinutes }}
+
{{ team.score }}
-
{{ $data | json }}
+
-

-

- +

- - - + + + - \ No newline at end of file diff --git a/js/main.js b/js/main.js index 4213630..eaeb6c0 100755 --- a/js/main.js +++ b/js/main.js @@ -2,48 +2,182 @@ * main.js */ - -// localStorage (function(exports){ 'use strict'; var RANKS_KEY = 'icpc-ranks'; - var OPER_STACK_KEY = 'operation-stack'; + var OPER_FLAG_KEY = 'operation-flag'; + var NEXT_SPEED = 3000; //ms + var BACK_SPEED = 2000; //ms exports.Storage = { fetch: function(type) { if(type == 'ranks') - return JSON.parse(localStorage.getItem(RANKS_KEY)) || RanksData.init(); - else if(type == 'operation') - return JSON.parse(localStorage.getItem(OPER_STACK_KEY) || '[]'); + return JSON.parse(localStorage.getItem(RANKS_KEY)) || exports.resolver.rank_frozen; + else if(type == 'opera_flag') + return localStorage.getItem(OPER_FLAG_KEY) || 0; }, update: function(type, data) { if(type == 'ranks') localStorage.setItem(RANKS_KEY, JSON.stringify(data)); - else if(type == 'operation') - localStorage.setItem(OPER_STACK_KEY, JSON.stringify(data)); + else if(type == 'opera_flag') + localStorage.setItem(OPER_FLAG_KEY, data); } }; -})(window); + exports.Operation = { + next: function() { + vm.$data.op_status = false; + var op = vm.$data.operations[vm.$data.op_flag]; + var op_next = vm.$data.operations[vm.$data.op_flag+1]; + var ranks = vm.$data.ranks; + var rank_old = ranks[op.old_rank]; + + var el_old = $('#rank-' + op.old_rank); + var el_new = $('#rank-' + op.new_rank); + + el_old + .find('.p-'+op.problem_index).addClass('uncover') + .find('.p-content').addClass('uncover'); + vm.selected(el_old, 'add'); + if(op.new_rank == op.old_rank){ + var el_old_next = $('#rank-' + op_next.old_rank); + setTimeout(function(){ + if(op.new_verdict == 'AC'){ + rank_old.score += 1; + rank_old.penalty += op.new_penalty; + } + rank_old.problem[op.problem_index].old_verdict = op.new_verdict; + rank_old.problem[op.problem_index].new_verdict = "NA"; + Vue.nextTick(function(){ + el_old + .find('.p-'+op.problem_index).addClass('uncover') + .find('.p-content').removeClass('uncover'); + }); + + setTimeout(function(){ + vm.selected(el_old, 'remove'); + vm.selected(el_old_next, 'add'); + el_old.find('.p-'+op.problem_index).removeClass('uncover'); + // .find('.p-content').removeClass('uncover'); + + vm.$data.op_flag += 1; + vm.$data.op_status = true; + }, 1000); + }, 1000); + }else{ + var old_pos_top = el_old.position().top; + var new_pos_top = el_new.position().top; + var distance = new_pos_top - old_pos_top; + var win_heigth = $(window).height(); + if(Math.abs(distance) > win_heigth){ + distance = -(win_heigth); + } + var j = op.old_rank - 1; + var el_obj = []; + for(j; j >= op.new_rank; j--){ + var el = $('#rank-'+ j); + el_obj.push(el); + } + setTimeout(function(){ + // return function(){ + + // 修改原始数据 + if(op.new_verdict == 'AC'){ + rank_old.score += 1; + rank_old.penalty += op.new_penalty; + } + rank_old.problem[op.problem_index].old_verdict = op.new_verdict; + rank_old.problem[op.problem_index].new_verdict = "NA"; + // + Vue.nextTick(function(){ + //添加揭晓题目闪动效果 + el_old + .find('.p-'+op.problem_index).addClass('uncover') + .find('.p-content').removeClass('uncover'); + //修改排名 + el_old.find('.rank').text(op.new_rank+1); + el_obj.forEach(function(val,i){ + var dom_rank = el_obj[i].find('.rank'); + dom_rank.text(Number(dom_rank.text())+1); + }); + }); + + setTimeout(function(){ + el_old + .css('position', 'relative') + .animate({ top: distance+'px' }, 2000, function(){ + el_new.removeAttr('style'); + el_old.removeAttr('style'); + var ranks_tmp = $.extend(true, [], ranks); + var data_old = ranks_tmp[op.old_rank]; + var i = op.old_rank - 1; + for(i; i >= op.new_rank; i--){ + ranks_tmp[i+1] = ranks_tmp[i]; + } + ranks_tmp[op.new_rank] = data_old; + vm.$set('ranks', ranks_tmp); + Vue.nextTick(function () { + el_obj.forEach(function(val,i){ el_obj[i].removeAttr('style'); }); + el_old.find('.p-'+op.problem_index).removeClass('uncover'); + var el_old_next = $('#rank-' + op_next.old_rank); + vm.selected(el_old, 'remove'); + vm.selected(el_old_next, 'add'); + vm.$data.op_flag += 1; + vm.$data.op_status = true; + }); + }); + + el_obj.forEach(function(val,i){ el_obj[i].animate({'top': 75+'px',},2000); }); + // for(j; j >= op.new_rank; j--){ + // var el = $('#rank-'+ j); + // el_obj.push(el); + // el.animate({'top': 75+'px',},2000); + // } + }, 1000);// two loop + // }; + }, 1500); + } + }, + + back: function() { + + } + }; +})(window); // Vuejs -(function(exports){ +function vuejs() { + Vue.filter('toMinutes', function (value) { + return parseInt(value/60); + }); + + Vue.filter('problemStatus', function (problem) { + return resolver.status(problem); + }); - 'use strict'; + Vue.filter('submissions', function (value) { + var st = resolver.status(value); + if(st == 'ac') + return value.submissions + 1; + // todo + }); - exports.app = new Vue({ - + Vue.config.debug = true; + + window.vm = new Vue({ el: '.app', data: { + op_flag: Number(Storage.fetch('opera_flag')), + op_status: true, // running: false, stop: true + p_count: resolver.problem_count, ranks: Storage.fetch('ranks'), - operation: Storage.fetch('operation'), - no_animate_running: true, - p_names: {1:'A', 2:'B'} + operations: resolver.operations, + users: resolver.users }, ready: function () { @@ -51,77 +185,54 @@ Storage.update('ranks', ranks); }, {'deep': true}); - this.$watch('operation', function(operation){ - Storage.update('operation', operation); + this.$watch('op_flag', function(op_flag){ + Storage.update('opera_flag', op_flag); }, {'deep': true}); + + var op = this.operations[this.op_flag]; + this.selected($('#rank-'+op.old_rank), 'add'); }, methods: { - publish: function(rank_item, problem) { - if(no_animate_running){ - - } - }, - - changeRank: function(rank_item, problem){ - this.operationPush(rank_item); - var old_rank = rank_item.rank; - var new_rank = 3; - - var el_old_rank = $('#rank-'+old_rank); - var el_new_rank = $('#rank-'+new_rank); - var new_top = el_new_rank.position().top; - var old_top = el_old_rank.position().top; - var distance = new_top - old_top - 87; - - var ranks = this.ranks; - var temp = $.extend(true, {}, rank_item); - //animate - el_old_rank.css('position', 'relative'); - el_new_rank.css('margin-top', '87px'); - el_old_rank.animate({ - "top": distance+'px', - }, 3000, function(){ - el_new_rank.css('margin-top', '0'); - el_old_rank.css('position', 'static'); - rank_item.rank = new_rank; - // ranks.splice(2, 0, temp); - // ranks.$remove(rank_item); - }); - - - }, - reset: function(){ if(confirm('确定要重置排名吗?')){ localStorage.clear(); window.location.reload(); } }, - - operationPush: function(rank_item){ - this.operation.push($.extend(true, {}, rank_item)); - }, - operationPop: function() { - var op = this.operation; - var ranks = this.ranks; - for(var x in ranks){ - if(ranks[x].name == _.last(op).name){ - this.$set('ranks['+x+']', _.last(op)); - break; - } - } - op.$remove(_.last(op)); + uncover: function(){ + }, - computingRank: function(){ - + selected: function(el, type){ + if(el === undefined) + return; + if(type == 'add') + el.addClass('selected'); + else if(type == 'remove') + el.removeClass('selected'); + // var win_heigth = $(window).height(); + // var pos = el.position().top; + // var offset = pos - win_heigth + 261; + // window.scrollTo(0, offset); } } }); - -})(window); - - - +} + +$.getJSON("contest.json", function(data){ + var resolver = new Resolver(data.solutions, data.users, data.problem_count); + window.resolver = resolver; + resolver.calcOperations(); + vuejs(); + document.onkeydown = function(event){ + var e = event || window.event || arguments.callee.caller.arguments[0]; + if(e && e.keyCode == 37 && vm.$data.op_status){ // key left + Operation.back(); + } + if(e && e.keyCode == 39 && vm.$data.op_status){ // key right + Operation.next(); + } + }; +}); diff --git a/libs/js/jquery.scrollTo.min.js b/libs/js/jquery.scrollTo.min.js new file mode 100755 index 0000000..983eb88 --- /dev/null +++ b/libs/js/jquery.scrollTo.min.js @@ -0,0 +1,7 @@ +/** + * Copyright (c) 2007-2015 Ariel Flesler - aflesler ○ gmail • com | http://flesler.blogspot.com + * Licensed under MIT + * @author Ariel Flesler + * @version 2.1.3 + */ +;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1 MyComponent + * some_else => SomeElse + * some/comp => SomeComp + * + * @param {String} str + * @return {String} + */ + + var classifyRE = /(?:^|[-_\/])(\w)/g + exports.classify = function (str) { + return str.replace(classifyRE, toUpper) + } + + /** + * Simple bind, faster than native + * + * @param {Function} fn + * @param {Object} ctx + * @return {Function} + */ + + exports.bind = function (fn, ctx) { + return function (a) { + var l = arguments.length + return l + ? l > 1 + ? fn.apply(ctx, arguments) + : fn.call(ctx, a) + : fn.call(ctx) + } + } + + /** + * Convert an Array-like object to a real Array. + * + * @param {Array-like} list + * @param {Number} [start] - start index + * @return {Array} + */ + + exports.toArray = function (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. + * + * @param {Object} to + * @param {Object} from + */ + + exports.extend = function (to, from) { + var keys = Object.keys(from) + var i = keys.length + while (i--) { + to[keys[i]] = from[keys[i]] + } + 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. + * + * @param {*} obj + * @return {Boolean} + */ + + exports.isObject = function (obj) { + return obj !== null && typeof obj === 'object' + } + + /** + * Strict object type check. Only returns true + * for plain JavaScript objects. + * + * @param {*} obj + * @return {Boolean} + */ + + var toString = Object.prototype.toString + var OBJECT_STRING = '[object Object]' + exports.isPlainObject = function (obj) { + return toString.call(obj) === OBJECT_STRING + } + + /** + * Array type check. + * + * @param {*} obj + * @return {Boolean} + */ + + exports.isArray = Array.isArray + + /** + * Define a non-enumerable property + * + * @param {Object} obj + * @param {String} key + * @param {*} val + * @param {Boolean} [enumerable] + */ + + exports.define = function (obj, key, val, enumerable) { + Object.defineProperty(obj, key, { + value: val, + enumerable: !!enumerable, + writable: true, + configurable: true + }) + } + + /** + * Debounce a function so it only gets called after the + * input stops arriving after the given wait period. + * + * @param {Function} func + * @param {Number} wait + * @return {Function} - the debounced function + */ + + exports.debounce = function (func, wait) { + var timeout, args, context, timestamp, result + var later = function () { + var last = Date.now() - timestamp + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last) + } else { + timeout = null + result = func.apply(context, args) + if (!timeout) context = args = null + } + } + return function () { + context = this + args = arguments + timestamp = Date.now() + if (!timeout) { + timeout = setTimeout(later, wait) + } + return result + } + } + + /** + * Manual indexOf because it's slightly faster than + * native. + * + * @param {Array} arr + * @param {*} obj + */ + + exports.indexOf = function (arr, obj) { + var i = arr.length + while (i--) { + if (arr[i] === obj) return i + } + return -1 + } + + /** + * Make a cancellable version of an async callback. + * + * @param {Function} fn + * @return {Function} + */ + + exports.cancellable = function (fn) { + var cb = function () { + if (!cb.cancelled) { + return fn.apply(this, arguments) + } + } + cb.cancel = function () { + cb.cancelled = true + } + return cb + } + + /** + * Check if two values are loosely equal - that is, + * if they are plain objects, do they have the same shape? + * + * @param {*} a + * @param {*} b + * @return {Boolean} + */ + + exports.looseEqual = function (a, b) { + /* eslint-disable eqeqeq */ + return a == b || ( + exports.isObject(a) && exports.isObject(b) + ? JSON.stringify(a) === JSON.stringify(b) + : false + ) + /* eslint-enable eqeqeq */ + } + + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + // can we use __proto__? + exports.hasProto = '__proto__' in {} + + // Browser environment sniffing + var inBrowser = exports.inBrowser = + typeof window !== 'undefined' && + Object.prototype.toString.call(window) !== '[object Object]' + + exports.isIE9 = + inBrowser && + navigator.userAgent.toLowerCase().indexOf('msie 9.0') > 0 + + exports.isAndroid = + inBrowser && + navigator.userAgent.toLowerCase().indexOf('android') > 0 + + // Transition property/event sniffing + if (inBrowser && !exports.isIE9) { + var isWebkitTrans = + window.ontransitionend === undefined && + window.onwebkittransitionend !== undefined + var isWebkitAnim = + window.onanimationend === undefined && + window.onwebkitanimationend !== undefined + exports.transitionProp = isWebkitTrans + ? 'WebkitTransition' + : 'transition' + exports.transitionEndEvent = isWebkitTrans + ? 'webkitTransitionEnd' + : 'transitionend' + exports.animationProp = isWebkitAnim + ? 'WebkitAnimation' + : 'animation' + exports.animationEndEvent = isWebkitAnim + ? 'webkitAnimationEnd' + : 'animationend' + } + + /** + * Defer a task to execute it asynchronously. Ideally this + * should be executed as a microtask, so we leverage + * MutationObserver if it's available, and fallback to + * setTimeout(0). + * + * @param {Function} cb + * @param {Object} ctx + */ + + exports.nextTick = (function () { + var callbacks = [] + var pending = false + var timerFunc + function nextTickHandler () { + pending = false + var copies = callbacks.slice(0) + callbacks = [] + for (var i = 0; i < copies.length; i++) { + copies[i]() + } + } + /* istanbul ignore if */ + if (typeof MutationObserver !== 'undefined') { + var counter = 1 + var observer = new MutationObserver(nextTickHandler) + var textNode = document.createTextNode(counter) + observer.observe(textNode, { + characterData: true + }) + timerFunc = function () { + counter = (counter + 1) % 2 + textNode.data = counter + } + } else { + timerFunc = setTimeout + } + return function (cb, ctx) { + var func = ctx + ? function () { cb.call(ctx) } + : cb + callbacks.push(func) + if (pending) return + pending = true + timerFunc(nextTickHandler, 0) + } + })() + + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var config = __webpack_require__(5) + var transition = __webpack_require__(9) + + /** + * Query an element selector if it's not an element already. + * + * @param {String|Element} el + * @return {Element} + */ + + exports.query = function (el) { + if (typeof el === 'string') { + var selector = el + el = document.querySelector(el) + if (!el) { + ("development") !== 'production' && _.warn( + 'Cannot find element: ' + selector + ) + } + } + return el + } + + /** + * Check if a node is in the document. + * Note: document.documentElement.contains should work here + * but always returns false for comment nodes in phantomjs, + * making unit tests difficult. This is fixed by doing the + * contains() check on the node's parentNode instead of + * the node itself. + * + * @param {Node} node + * @return {Boolean} + */ + + exports.inDoc = function (node) { + var doc = document.documentElement + var parent = node && node.parentNode + return doc === node || + doc === parent || + !!(parent && parent.nodeType === 1 && (doc.contains(parent))) + } + + /** + * Get and remove an attribute from a node. + * + * @param {Node} node + * @param {String} attr + */ + + exports.attr = function (node, attr) { + var val = node.getAttribute(attr) + if (val !== null) { + node.removeAttribute(attr) + } + return val + } + + /** + * Get an attribute with colon or v-bind: prefix. + * + * @param {Node} node + * @param {String} name + * @return {String|null} + */ + + exports.getBindAttr = function (node, name) { + var val = exports.attr(node, ':' + name) + if (val === null) { + val = exports.attr(node, 'v-bind:' + name) + } + return val + } + + /** + * Insert el before target + * + * @param {Element} el + * @param {Element} target + */ + + exports.before = function (el, target) { + target.parentNode.insertBefore(el, target) + } + + /** + * Insert el after target + * + * @param {Element} el + * @param {Element} target + */ + + exports.after = function (el, target) { + if (target.nextSibling) { + exports.before(el, target.nextSibling) + } else { + target.parentNode.appendChild(el) + } + } + + /** + * Remove el from DOM + * + * @param {Element} el + */ + + exports.remove = function (el) { + el.parentNode.removeChild(el) + } + + /** + * Prepend el to target + * + * @param {Element} el + * @param {Element} target + */ + + exports.prepend = function (el, target) { + if (target.firstChild) { + exports.before(el, target.firstChild) + } else { + target.appendChild(el) + } + } + + /** + * Replace target with el + * + * @param {Element} target + * @param {Element} el + */ + + exports.replace = function (target, el) { + var parent = target.parentNode + if (parent) { + parent.replaceChild(el, target) + } + } + + /** + * Add event listener shorthand. + * + * @param {Element} el + * @param {String} event + * @param {Function} cb + */ + + exports.on = function (el, event, cb) { + el.addEventListener(event, cb) + } + + /** + * Remove event listener shorthand. + * + * @param {Element} el + * @param {String} event + * @param {Function} cb + */ + + exports.off = function (el, event, cb) { + el.removeEventListener(event, cb) + } + + /** + * Add class with compatibility for IE & SVG + * + * @param {Element} el + * @param {Strong} cls + */ + + exports.addClass = function (el, cls) { + if (el.classList) { + el.classList.add(cls) + } else { + var cur = ' ' + (el.getAttribute('class') || '') + ' ' + if (cur.indexOf(' ' + cls + ' ') < 0) { + el.setAttribute('class', (cur + cls).trim()) + } + } + } + + /** + * Remove class with compatibility for IE & SVG + * + * @param {Element} el + * @param {Strong} cls + */ + + exports.removeClass = function (el, cls) { + if (el.classList) { + el.classList.remove(cls) + } else { + var cur = ' ' + (el.getAttribute('class') || '') + ' ' + var tar = ' ' + cls + ' ' + while (cur.indexOf(tar) >= 0) { + cur = cur.replace(tar, ' ') + } + el.setAttribute('class', cur.trim()) + } + if (!el.className) { + el.removeAttribute('class') + } + } + + /** + * Extract raw content inside an element into a temporary + * container div + * + * @param {Element} el + * @param {Boolean} asFragment + * @return {Element} + */ + + exports.extractContent = function (el, asFragment) { + var child + var rawContent + /* istanbul ignore if */ + if ( + exports.isTemplate(el) && + el.content instanceof DocumentFragment + ) { + el = el.content + } + if (el.hasChildNodes()) { + exports.trimNode(el) + rawContent = asFragment + ? document.createDocumentFragment() + : document.createElement('div') + /* eslint-disable no-cond-assign */ + while (child = el.firstChild) { + /* eslint-enable no-cond-assign */ + rawContent.appendChild(child) + } + } + return rawContent + } + + /** + * Trim possible empty head/tail textNodes inside a parent. + * + * @param {Node} node + */ + + exports.trimNode = function (node) { + trim(node, node.firstChild) + trim(node, node.lastChild) + } + + function trim (parent, node) { + if (node && node.nodeType === 3 && !node.data.trim()) { + parent.removeChild(node) + } + } + + /** + * Check if an element is a template tag. + * Note if the template appears inside an SVG its tagName + * will be in lowercase. + * + * @param {Element} el + */ + + exports.isTemplate = function (el) { + return el.tagName && + el.tagName.toLowerCase() === 'template' + } + + /** + * Create an "anchor" for performing dom insertion/removals. + * This is used in a number of scenarios: + * - fragment instance + * - v-html + * - v-if + * - v-for + * - component + * + * @param {String} content + * @param {Boolean} persist - IE trashes empty textNodes on + * cloneNode(true), so in certain + * cases the anchor needs to be + * non-empty to be persisted in + * templates. + * @return {Comment|Text} + */ + + exports.createAnchor = function (content, persist) { + return config.debug + ? document.createComment(content) + : document.createTextNode(persist ? ' ' : '') + } + + /** + * Find a component ref attribute that starts with $. + * + * @param {Element} node + * @return {String|undefined} + */ + + var refRE = /^v-ref:/ + exports.findRef = function (node) { + if (node.hasAttributes()) { + var attrs = node.attributes + for (var i = 0, l = attrs.length; i < l; i++) { + var name = attrs[i].name + if (refRE.test(name)) { + node.removeAttribute(name) + return _.camelize(name.replace(refRE, '')) + } + } + } + } + + /** + * Map a function to a range of nodes . + * + * @param {Node} node + * @param {Node} end + * @param {Function} op + */ + + exports.mapNodeRange = function (node, end, op) { + var next + while (node !== end) { + next = node.nextSibling + op(node) + node = next + } + op(end) + } + + /** + * Remove a range of nodes with transition, store + * the nodes in a fragment with correct ordering, + * and call callback when done. + * + * @param {Node} start + * @param {Node} end + * @param {Vue} vm + * @param {DocumentFragment} frag + * @param {Function} cb + */ + + exports.removeNodeRange = function (start, end, vm, frag, cb) { + var done = false + var removed = 0 + var nodes = [] + exports.mapNodeRange(start, end, function (node) { + if (node === end) done = true + nodes.push(node) + transition.remove(node, vm, onRemoved) + }) + function onRemoved () { + removed++ + if (done && removed >= nodes.length) { + for (var i = 0; i < nodes.length; i++) { + frag.appendChild(nodes[i]) + } + cb && cb() + } + } + } + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = { + + /** + * Whether to print debug messages. + * Also enables stack trace for warnings. + * + * @type {Boolean} + */ + + debug: false, + + /** + * Whether to suppress warnings. + * + * @type {Boolean} + */ + + silent: false, + + /** + * Whether to use async rendering. + */ + + async: true, + + /** + * Whether to warn against errors caught when evaluating + * expressions. + */ + + warnExpressionErrors: true, + + /** + * Internal flag to indicate the delimiters have been + * changed. + * + * @type {Boolean} + */ + + _delimitersChanged: true, + + /** + * List of asset types that a component can own. + * + * @type {Array} + */ + + _assetTypes: [ + 'component', + 'directive', + 'elementDirective', + 'filter', + 'transition', + 'partial' + ], + + /** + * prop binding modes + */ + + _propBindingModes: { + ONE_WAY: 0, + TWO_WAY: 1, + ONE_TIME: 2 + }, + + /** + * Max circular updates allowed in a batcher flush cycle. + */ + + _maxUpdateCount: 100 + + } + + /** + * Interpolation delimiters. Changing these would trigger + * the text parser to re-compile the regular expressions. + * + * @type {Array} + */ + + var delimiters = ['{{', '}}'] + var unsafeDelimiters = ['{{{', '}}}'] + var textParser = __webpack_require__(6) + + Object.defineProperty(module.exports, 'delimiters', { + get: function () { + return delimiters + }, + set: function (val) { + delimiters = val + textParser.compileRegex() + } + }) + + Object.defineProperty(module.exports, 'unsafeDelimiters', { + get: function () { + return unsafeDelimiters + }, + set: function (val) { + unsafeDelimiters = val + textParser.compileRegex() + } + }) + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + var Cache = __webpack_require__(7) + var config = __webpack_require__(5) + var dirParser = __webpack_require__(8) + var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g + var cache, tagRE, htmlRE + + /** + * Escape a string so it can be used in a RegExp + * constructor. + * + * @param {String} str + */ + + function escapeRegex (str) { + return str.replace(regexEscapeRE, '\\$&') + } + + exports.compileRegex = function () { + var open = escapeRegex(config.delimiters[0]) + var close = escapeRegex(config.delimiters[1]) + var unsafeOpen = escapeRegex(config.unsafeDelimiters[0]) + var unsafeClose = escapeRegex(config.unsafeDelimiters[1]) + tagRE = new RegExp( + unsafeOpen + '(.+?)' + unsafeClose + '|' + + open + '(.+?)' + close, + 'g' + ) + htmlRE = new RegExp( + '^' + unsafeOpen + '.*' + unsafeClose + '$' + ) + // reset cache + cache = new Cache(1000) + } + + /** + * Parse a template text string into an array of tokens. + * + * @param {String} text + * @return {Array | null} + * - {String} type + * - {String} value + * - {Boolean} [html] + * - {Boolean} [oneTime] + */ + + exports.parse = function (text) { + if (!cache) { + exports.compileRegex() + } + var hit = cache.get(text) + if (hit) { + return hit + } + text = text.replace(/\n/g, '') + if (!tagRE.test(text)) { + return null + } + var tokens = [] + var lastIndex = tagRE.lastIndex = 0 + var match, index, html, value, first, oneTime + /* eslint-disable no-cond-assign */ + while (match = tagRE.exec(text)) { + /* eslint-enable no-cond-assign */ + index = match.index + // push text token + if (index > lastIndex) { + tokens.push({ + value: text.slice(lastIndex, index) + }) + } + // tag token + html = htmlRE.test(match[0]) + value = html ? match[1] : match[2] + first = value.charCodeAt(0) + oneTime = first === 42 // * + value = oneTime + ? value.slice(1) + : value + tokens.push({ + tag: true, + value: value.trim(), + html: html, + oneTime: oneTime + }) + lastIndex = index + match[0].length + } + if (lastIndex < text.length) { + tokens.push({ + value: text.slice(lastIndex) + }) + } + cache.put(text, tokens) + return tokens + } + + /** + * Format a list of tokens into an expression. + * e.g. tokens parsed from 'a {{b}} c' can be serialized + * into one single expression as '"a " + b + " c"'. + * + * @param {Array} tokens + * @return {String} + */ + + exports.tokensToExp = function (tokens) { + if (tokens.length > 1) { + return tokens.map(function (token) { + return formatToken(token) + }).join('+') + } else { + return formatToken(tokens[0], true) + } + } + + /** + * Format a single token. + * + * @param {Object} token + * @param {Boolean} single + * @return {String} + */ + + function formatToken (token, single) { + return token.tag + ? inlineFilters(token.value, single) + : '"' + token.value + '"' + } + + /** + * For an attribute with multiple interpolation tags, + * e.g. attr="some-{{thing | filter}}", in order to combine + * the whole thing into a single watchable expression, we + * have to inline those filters. This function does exactly + * that. This is a bit hacky but it avoids heavy changes + * to directive parser and watcher mechanism. + * + * @param {String} exp + * @param {Boolean} single + * @return {String} + */ + + var filterRE = /[^|]\|[^|]/ + function inlineFilters (exp, single) { + if (!filterRE.test(exp)) { + return single + ? exp + : '(' + exp + ')' + } else { + var dir = dirParser.parse(exp) + if (!dir.filters) { + return '(' + exp + ')' + } else { + return 'this._applyFilters(' + + dir.expression + // value + ',null,' + // oldValue (null for read) + JSON.stringify(dir.filters) + // filter descriptors + ',false)' // write? + } + } + } + + +/***/ }, +/* 7 */ +/***/ function(module, exports) { + + /** + * A doubly linked list-based Least Recently Used (LRU) + * cache. Will keep most recently used items while + * discarding least recently used items when its limit is + * reached. This is a bare-bone version of + * Rasmus Andersson's js-lru: + * + * https://github.com/rsms/js-lru + * + * @param {Number} limit + * @constructor + */ + + function Cache (limit) { + this.size = 0 + this.limit = limit + this.head = this.tail = undefined + this._keymap = Object.create(null) + } + + var p = Cache.prototype + + /** + * Put into the cache associated with . + * Returns the entry which was removed to make room for + * the new entry. Otherwise undefined is returned. + * (i.e. if there was enough room already). + * + * @param {String} key + * @param {*} value + * @return {Entry|undefined} + */ + + p.put = function (key, value) { + var entry = { + key: key, + value: value + } + this._keymap[key] = entry + if (this.tail) { + this.tail.newer = entry + entry.older = this.tail + } else { + this.head = entry + } + this.tail = entry + if (this.size === this.limit) { + return this.shift() + } else { + this.size++ + } + } + + /** + * Purge the least recently used (oldest) entry from the + * cache. Returns the removed entry or undefined if the + * cache was empty. + */ + + p.shift = function () { + var entry = this.head + if (entry) { + this.head = this.head.newer + this.head.older = undefined + entry.newer = entry.older = undefined + this._keymap[entry.key] = undefined + } + return entry + } + + /** + * Get and register recent use of . Returns the value + * associated with or undefined if not in cache. + * + * @param {String} key + * @param {Boolean} returnEntry + * @return {Entry|*} + */ + + p.get = function (key, returnEntry) { + var entry = this._keymap[key] + if (entry === undefined) return + if (entry === this.tail) { + return returnEntry + ? entry + : entry.value + } + // HEAD--------------TAIL + // <.older .newer> + // <--- add direction -- + // A B C E + if (entry.newer) { + if (entry === this.head) { + this.head = entry.newer + } + entry.newer.older = entry.older // C <-- E. + } + if (entry.older) { + entry.older.newer = entry.newer // C. --> E + } + entry.newer = undefined // D --x + entry.older = this.tail // D. --> E + if (this.tail) { + this.tail.newer = entry // E. <-- D + } + this.tail = entry + return returnEntry + ? entry + : entry.value + } + + module.exports = Cache + + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var Cache = __webpack_require__(7) + var cache = new Cache(1000) + var filterTokenRE = /[^\s'"]+|'[^']*'|"[^"]*"/g + var reservedArgRE = /^in$|^-?\d+/ + + /** + * Parser state + */ + + var str, dir + var c, i, l, lastFilterIndex + var inSingle, inDouble, curly, square, paren + + /** + * Push a filter to the current directive object + */ + + function pushFilter () { + var exp = str.slice(lastFilterIndex, i).trim() + var filter + if (exp) { + filter = {} + var tokens = exp.match(filterTokenRE) + filter.name = tokens[0] + if (tokens.length > 1) { + filter.args = tokens.slice(1).map(processFilterArg) + } + } + if (filter) { + (dir.filters = dir.filters || []).push(filter) + } + lastFilterIndex = i + 1 + } + + /** + * Check if an argument is dynamic and strip quotes. + * + * @param {String} arg + * @return {Object} + */ + + function processFilterArg (arg) { + if (reservedArgRE.test(arg)) { + return { + value: _.toNumber(arg), + dynamic: false + } + } else { + var stripped = _.stripQuotes(arg) + var dynamic = stripped === arg + return { + value: dynamic ? arg : stripped, + dynamic: dynamic + } + } + } + + /** + * Parse a directive value and extract the expression + * and its filters into a descriptor. + * + * Example: + * + * "a + 1 | uppercase" will yield: + * { + * expression: 'a + 1', + * filters: [ + * { name: 'uppercase', args: null } + * ] + * } + * + * @param {String} str + * @return {Object} + */ + + exports.parse = function (s) { + + var hit = cache.get(s) + if (hit) { + return hit + } + + // reset parser state + str = s + inSingle = inDouble = false + curly = square = paren = 0 + lastFilterIndex = 0 + dir = {} + + for (i = 0, l = str.length; i < l; i++) { + c = str.charCodeAt(i) + if (inSingle) { + // check single quote + if (c === 0x27) inSingle = !inSingle + } else if (inDouble) { + // check double quote + if (c === 0x22) inDouble = !inDouble + } else if ( + c === 0x7C && // pipe + str.charCodeAt(i + 1) !== 0x7C && + str.charCodeAt(i - 1) !== 0x7C + ) { + if (dir.expression == null) { + // first filter, end of expression + lastFilterIndex = i + 1 + dir.expression = str.slice(0, i).trim() + } else { + // already has filter + pushFilter() + } + } else { + switch (c) { + case 0x22: inDouble = true; break // " + case 0x27: inSingle = true; break // ' + case 0x28: paren++; break // ( + case 0x29: paren--; break // ) + case 0x5B: square++; break // [ + case 0x5D: square--; break // ] + case 0x7B: curly++; break // { + case 0x7D: curly--; break // } + } + } + } + + if (dir.expression == null) { + dir.expression = str.slice(0, i).trim() + } else if (lastFilterIndex !== 0) { + pushFilter() + } + + cache.put(s, dir) + return dir + } + + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + /** + * Append with transition. + * + * @param {Element} el + * @param {Element} target + * @param {Vue} vm + * @param {Function} [cb] + */ + + exports.append = function (el, target, vm, cb) { + apply(el, 1, function () { + target.appendChild(el) + }, vm, cb) + } + + /** + * InsertBefore with transition. + * + * @param {Element} el + * @param {Element} target + * @param {Vue} vm + * @param {Function} [cb] + */ + + exports.before = function (el, target, vm, cb) { + apply(el, 1, function () { + _.before(el, target) + }, vm, cb) + } + + /** + * Remove with transition. + * + * @param {Element} el + * @param {Vue} vm + * @param {Function} [cb] + */ + + exports.remove = function (el, vm, cb) { + apply(el, -1, function () { + _.remove(el) + }, vm, cb) + } + + /** + * Apply transitions with an operation callback. + * + * @param {Element} el + * @param {Number} direction + * 1: enter + * -1: leave + * @param {Function} op - the actual DOM operation + * @param {Vue} vm + * @param {Function} [cb] + */ + + var apply = exports.apply = function (el, direction, op, vm, cb) { + var transition = el.__v_trans + if ( + !transition || + // skip if there are no js hooks and CSS transition is + // not supported + (!transition.hooks && !_.transitionEndEvent) || + // skip transitions for initial compile + !vm._isCompiled || + // if the vm is being manipulated by a parent directive + // during the parent's compilation phase, skip the + // animation. + (vm.$parent && !vm.$parent._isCompiled) + ) { + op() + if (cb) cb() + return + } + var action = direction > 0 ? 'enter' : 'leave' + transition[action](op, cb) + } + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var config = __webpack_require__(5) + var extend = _.extend + + /** + * Option overwriting strategies are functions that handle + * how to merge a parent option value and a child option + * value into the final value. + * + * All strategy functions follow the same signature: + * + * @param {*} parentVal + * @param {*} childVal + * @param {Vue} [vm] + */ + + var strats = config.optionMergeStrategies = Object.create(null) + + /** + * Helper that recursively merges two data objects together. + */ + + function mergeData (to, from) { + var key, toVal, fromVal + for (key in from) { + toVal = to[key] + fromVal = from[key] + if (!to.hasOwnProperty(key)) { + _.set(to, key, fromVal) + } else if (_.isObject(toVal) && _.isObject(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.' + ) + 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 + } + } + } + } + + /** + * El + */ + + strats.el = function (parentVal, childVal, vm) { + if (!vm && childVal && typeof childVal !== 'function') { + ("development") !== 'production' && _.warn( + 'The "el" option should be a function ' + + 'that returns a per-instance value in component ' + + 'definitions.' + ) + return + } + var ret = childVal || parentVal + // invoke the element factory if this is instance merge + return vm && typeof ret === 'function' + ? ret.call(vm) + : ret + } + + /** + * Hooks and param attributes are merged as arrays. + */ + + strats.init = + strats.created = + strats.ready = + strats.attached = + strats.detached = + strats.beforeCompile = + strats.compiled = + strats.beforeDestroy = + strats.destroyed = function (parentVal, childVal) { + return childVal + ? parentVal + ? parentVal.concat(childVal) + : _.isArray(childVal) + ? childVal + : [childVal] + : parentVal + } + + /** + * 0.11 deprecation warning + */ + + strats.paramAttributes = function () { + /* istanbul ignore next */ + ("development") !== 'production' && _.warn( + '"paramAttributes" option has been deprecated in 0.12. ' + + 'Use "props" instead.' + ) + } + + /** + * 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) + return childVal + ? extend(res, guardArrayAssets(childVal)) + : res + } + + config._assetTypes.forEach(function (type) { + strats[type + 's'] = mergeAssets + }) + + /** + * Events & Watchers. + * + * Events & watchers hashes should not overwrite one + * another, so we merge them as arrays. + */ + + strats.watch = + strats.events = function (parentVal, childVal) { + 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 && !_.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 + } + + /** + * Make sure component options get converted to actual + * constructors. + * + * @param {Object} options + */ + + function guardComponents (options) { + if (options.components) { + var components = options.components = + guardArrayAssets(options.components) + var def + var ids = Object.keys(components) + for (var i = 0, l = ids.length; i < l; i++) { + var key = ids[i] + if (_.commonTagRE.test(key)) { + ("development") !== 'production' && _.warn( + 'Do not use built-in HTML elements as component ' + + 'id: ' + key + ) + continue + } + def = components[key] + if (_.isPlainObject(def)) { + components[key] = _.Vue.extend(def) + } + } + } + } + + /** + * Ensure all props option syntax are normalized into the + * Object-based format. + * + * @param {Object} options + */ + + function guardProps (options) { + var props = options.props + var i + if (_.isArray(props)) { + options.props = {} + i = props.length + while (i--) { + options.props[props[i]] = null + } + } else if (_.isPlainObject(props)) { + var keys = Object.keys(props) + i = keys.length + while (i--) { + var val = props[keys[i]] + if (typeof val === 'function') { + props[keys[i]] = { type: val } + } + } + } + } + + /** + * Guard an Array-format assets option and converted it + * into the key-value Object format. + * + * @param {Object|Array} assets + * @return {Object} + */ + + function guardArrayAssets (assets) { + if (_.isArray(assets)) { + var res = {} + var i = assets.length + var asset + while (i--) { + asset = assets[i] + var id = typeof asset === 'function' + ? ((asset.options && asset.options.name) || asset.id) + : (asset.name || asset.id) + if (!id) { + ("development") !== 'production' && _.warn( + 'Array-syntax assets must provide a "name" or "id" field.' + ) + } else { + res[id] = asset + } + } + return res + } + return assets + } + + /** + * Merge two option objects into a new one. + * Core utility used in both instantiation and inheritance. + * + * @param {Object} parent + * @param {Object} child + * @param {Vue} [vm] - if vm is present, indicates this is + * an instantiation merge. + */ + + exports.mergeOptions = function merge (parent, child, vm) { + guardComponents(child) + guardProps(child) + var options = {} + var key + if (child.mixins) { + for (var i = 0, l = child.mixins.length; i < l; i++) { + parent = merge(parent, child.mixins[i], vm) + } + } + for (key in parent) { + mergeField(key) + } + for (key in child) { + if (!(parent.hasOwnProperty(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. + * + * @param {Object} options + * @param {String} type + * @param {String} id + * @return {Object|Function} + */ + + exports.resolveAsset = function resolve (options, type, id) { + var assets = options[type] + var camelizedId + return assets[id] || + // camelCase ID + assets[camelizedId = _.camelize(id)] || + // Pascal Case ID + assets[camelizedId.charAt(0).toUpperCase() + camelizedId.slice(1)] + } + + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + /** + * Check if an element is a component, if yes return its + * component id. + * + * @param {Element} el + * @param {Object} options + * @return {Object|undefined} + */ + + exports.commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/ + exports.checkComponent = function (el, options) { + var tag = el.tagName.toLowerCase() + var hasAttrs = el.hasAttributes() + if (!exports.commonTagRE.test(tag) && tag !== 'component') { + if (_.resolveAsset(options, 'components', tag)) { + return { id: tag } + } else { + var is = hasAttrs && getIsBinding(el) + if (is) { + return is + } else if (true) { + if ( + tag.indexOf('-') > -1 || + ( + /HTMLUnknownElement/.test(el.toString()) && + // Chrome returns unknown for several HTML5 elements. + // https://code.google.com/p/chromium/issues/detail?id=540526 + !/^(data|time|rtc|rb)$/.test(tag) + ) + ) { + _.warn( + 'Unknown custom element: <' + tag + '> - did you ' + + 'register the component correctly?' + ) + } + } + } + } else if (hasAttrs) { + return getIsBinding(el) + } + } + + /** + * Get "is" binding from an element. + * + * @param {Element} el + * @return {Object|undefined} + */ + + function getIsBinding (el) { + // dynamic syntax + var exp = _.attr(el, 'is') + if (exp != null) { + return { id: exp } + } else { + exp = _.getBindAttr(el, 'is') + if (exp != null) { + return { id: exp, dynamic: true } + } + } + } + + /** + * Set a prop's initial value on a vm and its data object. + * + * @param {Vue} vm + * @param {Object} prop + * @param {*} value + */ + + exports.initProp = function (vm, prop, value) { + if (exports.assertProp(prop, value)) { + var key = prop.path + vm[key] = vm._data[key] = value + } + } + + /** + * Assert whether a prop is valid. + * + * @param {Object} prop + * @param {*} value + */ + + exports.assertProp = function (prop, value) { + // if a prop is not provided and is not required, + // skip the check. + if (prop.raw === null && !prop.required) { + return true + } + var options = prop.options + var type = options.type + var valid = true + var expectedType + if (type) { + if (type === String) { + expectedType = 'string' + valid = typeof value === expectedType + } else if (type === Number) { + expectedType = 'number' + valid = typeof value === 'number' + } else if (type === Boolean) { + expectedType = 'boolean' + valid = typeof value === 'boolean' + } else if (type === Function) { + expectedType = 'function' + valid = typeof value === 'function' + } else if (type === Object) { + expectedType = 'object' + valid = _.isPlainObject(value) + } else if (type === Array) { + expectedType = 'array' + valid = _.isArray(value) + } else { + valid = value instanceof type + } + } + if (!valid) { + ("development") !== 'production' && _.warn( + 'Invalid prop: type check failed for ' + + prop.path + '="' + prop.raw + '".' + + ' Expected ' + formatType(expectedType) + + ', got ' + formatValue(value) + '.' + ) + return false + } + var validator = options.validator + if (validator) { + if (!validator.call(null, value)) { + ("development") !== 'production' && _.warn( + 'Invalid prop: custom validator check failed for ' + + prop.path + '="' + prop.raw + '"' + ) + return false + } + } + return true + } + + function formatType (val) { + return val + ? val.charAt(0).toUpperCase() + val.slice(1) + : 'custom type' + } + + function formatValue (val) { + return Object.prototype.toString.call(val).slice(8, -1) + } + + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Enable debug utilities. + */ + + if (true) { + + var config = __webpack_require__(5) + var hasConsole = typeof console !== 'undefined' + + /** + * Log a message. + * + * @param {String} msg + */ + + exports.log = function (msg) { + if (hasConsole && config.debug) { + console.log('[Vue info]: ' + msg) + } + } + + /** + * We've got a problem here. + * + * @param {String} msg + */ + + exports.warn = function (msg, e) { + if (hasConsole && (!config.silent || config.debug)) { + console.warn('[Vue warn]: ' + msg) + /* istanbul ignore if */ + if (config.debug) { + console.warn((e || new Error('Warning Stack Trace')).stack) + } + } + } + + /** + * Assert asset exists + */ + + exports.assertAsset = function (val, type, id) { + if (!val) { + exports.warn('Failed to resolve ' + type + ': ' + id) + } + } + } + + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var config = __webpack_require__(5) + + /** + * Expose useful internals + */ + + exports.util = _ + exports.config = config + exports.set = _.set + exports.delete = _.delete + exports.nextTick = _.nextTick + + /** + * The following are exposed for advanced usage / plugins + */ + + exports.compiler = __webpack_require__(14) + exports.FragmentFactory = __webpack_require__(21) + exports.internalDirectives = __webpack_require__(36) + exports.parsers = { + path: __webpack_require__(43), + text: __webpack_require__(6), + template: __webpack_require__(19), + directive: __webpack_require__(8), + expression: __webpack_require__(42) + } + + /** + * Each instance constructor, including Vue, has a unique + * cid. This enables us to create wrapped "child + * constructors" for prototypal inheritance and cache them. + */ + + exports.cid = 0 + var cid = 1 + + /** + * Class inheritance + * + * @param {Object} extendOptions + */ + + exports.extend = function (extendOptions) { + extendOptions = extendOptions || {} + var Super = this + var isFirstExtend = Super.cid === 0 + if (isFirstExtend && extendOptions._Ctor) { + return extendOptions._Ctor + } + var name = extendOptions.name || Super.options.name + var Sub = createClass(name || 'VueComponent') + Sub.prototype = Object.create(Super.prototype) + Sub.prototype.constructor = Sub + Sub.cid = cid++ + Sub.options = _.mergeOptions( + Super.options, + extendOptions + ) + Sub['super'] = Super + // allow further extension + Sub.extend = Super.extend + // create asset registers, so extended classes + // can have their private assets too. + config._assetTypes.forEach(function (type) { + Sub[type] = Super[type] + }) + // enable recursive self-lookup + if (name) { + Sub.options.components[name] = Sub + } + // cache constructor + if (isFirstExtend) { + extendOptions._Ctor = Sub + } + return Sub + } + + /** + * A function that returns a sub-class constructor with the + * given name. This gives us much nicer output when + * logging instances in the console. + * + * @param {String} name + * @return {Function} + */ + + function createClass (name) { + return new Function( + 'return function ' + _.classify(name) + + ' (options) { this._init(options) }' + )() + } + + /** + * Plugin system + * + * @param {Object} plugin + */ + + exports.use = function (plugin) { + /* istanbul ignore if */ + if (plugin.installed) { + return + } + // additional parameters + var args = _.toArray(arguments, 1) + args.unshift(this) + if (typeof plugin.install === 'function') { + plugin.install.apply(plugin, args) + } else { + plugin.apply(null, args) + } + plugin.installed = true + return this + } + + /** + * Apply a global mixin by merging it into the default + * options. + */ + + exports.mixin = function (mixin) { + var Vue = _.Vue + Vue.options = _.mergeOptions(Vue.options, mixin) + } + + /** + * Create asset registration methods with the following + * signature: + * + * @param {String} id + * @param {*} definition + */ + + config._assetTypes.forEach(function (type) { + exports[type] = function (id, definition) { + if (!definition) { + return this.options[type + 's'][id] + } else { + if ( + type === 'component' && + _.isPlainObject(definition) + ) { + definition.name = id + definition = _.Vue.extend(definition) + } + this.options[type + 's'][id] = definition + return definition + } + } + }) + + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + _.extend(exports, __webpack_require__(15)) + _.extend(exports, __webpack_require__(49)) + + +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var publicDirectives = __webpack_require__(16) + var internalDirectives = __webpack_require__(36) + var compileProps = __webpack_require__(48) + var textParser = __webpack_require__(6) + var dirParser = __webpack_require__(8) + var templateParser = __webpack_require__(19) + var resolveAsset = _.resolveAsset + + // special binding prefixes + var bindRE = /^v-bind:|^:/ + var onRE = /^v-on:|^@/ + var argRE = /:(.*)$/ + var modifierRE = /\.[^\.]+/g + var transitionRE = /^(v-bind:|:)?transition$/ + + // terminal directives + var terminalDirectives = [ + 'for', + 'if' + ] + + // default directive priority + var DEFAULT_PRIORITY = 1000 + + /** + * Compile a template and return a reusable composite link + * function, which recursively contains more link functions + * inside. This top level compile function would normally + * be called on instance root nodes, but can also be used + * for partial compilation if the partial argument is true. + * + * The returned composite link function, when called, will + * return an unlink function that tearsdown all directives + * created during the linking phase. + * + * @param {Element|DocumentFragment} el + * @param {Object} options + * @param {Boolean} partial + * @return {Function} + */ + + exports.compile = function (el, options, partial) { + // link function for the node itself. + var nodeLinkFn = partial || !options._asComponent + ? compileNode(el, options) + : null + // link function for the childNodes + var childLinkFn = + !(nodeLinkFn && nodeLinkFn.terminal) && + el.tagName !== 'SCRIPT' && + el.hasChildNodes() + ? compileNodeList(el.childNodes, options) + : null + + /** + * A composite linker function to be called on a already + * compiled piece of DOM, which instantiates all directive + * instances. + * + * @param {Vue} vm + * @param {Element|DocumentFragment} el + * @param {Vue} [host] - host vm of transcluded content + * @param {Object} [scope] - v-for scope + * @param {Fragment} [frag] - link context fragment + * @return {Function|undefined} + */ + + return function compositeLinkFn (vm, el, host, scope, frag) { + // cache childNodes before linking parent, fix #657 + var childNodes = _.toArray(el.childNodes) + // link + var dirs = linkAndCapture(function compositeLinkCapturer () { + if (nodeLinkFn) nodeLinkFn(vm, el, host, scope, frag) + if (childLinkFn) childLinkFn(vm, childNodes, host, scope, frag) + }, vm) + return makeUnlinkFn(vm, dirs) + } + } + + /** + * Apply a linker to a vm/element pair and capture the + * directives created during the process. + * + * @param {Function} linker + * @param {Vue} vm + */ + + function linkAndCapture (linker, vm) { + var originalDirCount = vm._directives.length + linker() + var dirs = vm._directives.slice(originalDirCount) + dirs.sort(directiveComparator) + for (var i = 0, l = dirs.length; i < l; i++) { + dirs[i]._bind() + } + return dirs + } + + /** + * Directive priority sort comparator + * + * @param {Object} a + * @param {Object} b + */ + + function directiveComparator (a, b) { + a = a.descriptor.def.priority || DEFAULT_PRIORITY + b = b.descriptor.def.priority || DEFAULT_PRIORITY + return a > b ? -1 : a === b ? 0 : 1 + } + + /** + * Linker functions return an unlink function that + * tearsdown all directives instances generated during + * the process. + * + * We create unlink functions with only the necessary + * information to avoid retaining additional closures. + * + * @param {Vue} vm + * @param {Array} dirs + * @param {Vue} [context] + * @param {Array} [contextDirs] + * @return {Function} + */ + + function makeUnlinkFn (vm, dirs, context, contextDirs) { + return function unlink (destroying) { + teardownDirs(vm, dirs, destroying) + if (context && contextDirs) { + teardownDirs(context, contextDirs) + } + } + } + + /** + * Teardown partial linked directives. + * + * @param {Vue} vm + * @param {Array} dirs + * @param {Boolean} destroying + */ + + function teardownDirs (vm, dirs, destroying) { + var i = dirs.length + while (i--) { + dirs[i]._teardown() + if (!destroying) { + vm._directives.$remove(dirs[i]) + } + } + } + + /** + * Compile link props on an instance. + * + * @param {Vue} vm + * @param {Element} el + * @param {Object} props + * @param {Object} [scope] + * @return {Function} + */ + + exports.compileAndLinkProps = function (vm, el, props, scope) { + var propsLinkFn = compileProps(el, props) + var propDirs = linkAndCapture(function () { + propsLinkFn(vm, scope) + }, vm) + return makeUnlinkFn(vm, propDirs) + } + + /** + * Compile the root element of an instance. + * + * 1. attrs on context container (context scope) + * 2. attrs on the component template root node, if + * replace:true (child scope) + * + * If this is a fragment instance, we only need to compile 1. + * + * @param {Vue} vm + * @param {Element} el + * @param {Object} options + * @param {Object} contextOptions + * @return {Function} + */ + + exports.compileRoot = function (el, options, contextOptions) { + var containerAttrs = options._containerAttrs + var replacerAttrs = options._replacerAttrs + var contextLinkFn, replacerLinkFn + + // only need to compile other attributes for + // non-fragment instances + if (el.nodeType !== 11) { + // for components, container and replacer need to be + // compiled separately and linked in different scopes. + if (options._asComponent) { + // 2. container attributes + if (containerAttrs && contextOptions) { + contextLinkFn = compileDirectives(containerAttrs, contextOptions) + } + if (replacerAttrs) { + // 3. replacer attributes + replacerLinkFn = compileDirectives(replacerAttrs, options) + } + } else { + // non-component, just compile as a normal element. + replacerLinkFn = compileDirectives(el.attributes, options) + } + } else if (("development") !== 'production' && containerAttrs) { + // warn container directives for fragment instances + var names = containerAttrs.map(function (attr) { + return '"' + attr.name + '"' + }).join(', ') + var plural = containerAttrs.length > 1 + _.warn( + 'Attribute' + (plural ? 's ' : ' ') + names + + (plural ? ' are' : ' is') + ' ignored on component ' + + '<' + options.el.tagName.toLowerCase() + '> because ' + + 'the component is a fragment instance: ' + + 'http://vuejs.org/guide/components.html#Fragment_Instance' + ) + } + + return function rootLinkFn (vm, el, scope) { + // link context scope dirs + var context = vm._context + var contextDirs + if (context && contextLinkFn) { + contextDirs = linkAndCapture(function () { + contextLinkFn(context, el, null, scope) + }, context) + } + + // link self + var selfDirs = linkAndCapture(function () { + if (replacerLinkFn) replacerLinkFn(vm, el) + }, vm) + + // return the unlink function that tearsdown context + // container directives. + return makeUnlinkFn(vm, selfDirs, context, contextDirs) + } + } + + /** + * Compile a node and return a nodeLinkFn based on the + * node type. + * + * @param {Node} node + * @param {Object} options + * @return {Function|null} + */ + + function compileNode (node, options) { + var type = node.nodeType + if (type === 1 && node.tagName !== 'SCRIPT') { + return compileElement(node, options) + } else if (type === 3 && node.data.trim()) { + return compileTextNode(node, options) + } else { + return null + } + } + + /** + * Compile an element and return a nodeLinkFn. + * + * @param {Element} el + * @param {Object} options + * @return {Function|null} + */ + + function compileElement (el, options) { + // preprocess textareas. + // textarea treats its text content as the initial value. + // just bind it as an attr directive for value. + if (el.tagName === 'TEXTAREA') { + var tokens = textParser.parse(el.value) + if (tokens) { + el.setAttribute(':value', textParser.tokensToExp(tokens)) + el.value = '' + } + } + var linkFn + var hasAttrs = el.hasAttributes() + // check terminal directives (for & if) + if (hasAttrs) { + linkFn = checkTerminalDirectives(el, options) + } + // check element directives + if (!linkFn) { + linkFn = checkElementDirectives(el, options) + } + // check component + if (!linkFn) { + linkFn = checkComponent(el, options) + } + // normal directives + if (!linkFn && hasAttrs) { + linkFn = compileDirectives(el.attributes, options) + } + return linkFn + } + + /** + * Compile a textNode and return a nodeLinkFn. + * + * @param {TextNode} node + * @param {Object} options + * @return {Function|null} textNodeLinkFn + */ + + function compileTextNode (node, options) { + var tokens = textParser.parse(node.data) + if (!tokens) { + return null + } + var frag = document.createDocumentFragment() + var el, token + for (var i = 0, l = tokens.length; i < l; i++) { + token = tokens[i] + el = token.tag + ? processTextToken(token, options) + : document.createTextNode(token.value) + frag.appendChild(el) + } + return makeTextNodeLinkFn(tokens, frag, options) + } + + /** + * Process a single text token. + * + * @param {Object} token + * @param {Object} options + * @return {Node} + */ + + function processTextToken (token, options) { + var el + if (token.oneTime) { + el = document.createTextNode(token.value) + } else { + if (token.html) { + el = document.createComment('v-html') + setTokenType('html') + } else { + // IE will clean up empty textNodes during + // frag.cloneNode(true), so we have to give it + // something here... + el = document.createTextNode(' ') + setTokenType('text') + } + } + function setTokenType (type) { + if (token.descriptor) return + var parsed = dirParser.parse(token.value) + token.descriptor = { + name: type, + def: publicDirectives[type], + expression: parsed.expression, + filters: parsed.filters + } + } + return el + } + + /** + * Build a function that processes a textNode. + * + * @param {Array} tokens + * @param {DocumentFragment} frag + */ + + function makeTextNodeLinkFn (tokens, frag) { + return function textNodeLinkFn (vm, el, host, scope) { + var fragClone = frag.cloneNode(true) + var childNodes = _.toArray(fragClone.childNodes) + var token, value, node + for (var i = 0, l = tokens.length; i < l; i++) { + token = tokens[i] + value = token.value + if (token.tag) { + node = childNodes[i] + if (token.oneTime) { + value = (scope || vm).$eval(value) + if (token.html) { + _.replace(node, templateParser.parse(value, true)) + } else { + node.data = value + } + } else { + vm._bindDir(token.descriptor, node, host, scope) + } + } + } + _.replace(el, fragClone) + } + } + + /** + * Compile a node list and return a childLinkFn. + * + * @param {NodeList} nodeList + * @param {Object} options + * @return {Function|undefined} + */ + + function compileNodeList (nodeList, options) { + var linkFns = [] + var nodeLinkFn, childLinkFn, node + for (var i = 0, l = nodeList.length; i < l; i++) { + node = nodeList[i] + nodeLinkFn = compileNode(node, options) + childLinkFn = + !(nodeLinkFn && nodeLinkFn.terminal) && + node.tagName !== 'SCRIPT' && + node.hasChildNodes() + ? compileNodeList(node.childNodes, options) + : null + linkFns.push(nodeLinkFn, childLinkFn) + } + return linkFns.length + ? makeChildLinkFn(linkFns) + : null + } + + /** + * Make a child link function for a node's childNodes. + * + * @param {Array} linkFns + * @return {Function} childLinkFn + */ + + function makeChildLinkFn (linkFns) { + return function childLinkFn (vm, nodes, host, scope, frag) { + var node, nodeLinkFn, childrenLinkFn + for (var i = 0, n = 0, l = linkFns.length; i < l; n++) { + node = nodes[n] + nodeLinkFn = linkFns[i++] + childrenLinkFn = linkFns[i++] + // cache childNodes before linking parent, fix #657 + var childNodes = _.toArray(node.childNodes) + if (nodeLinkFn) { + nodeLinkFn(vm, node, host, scope, frag) + } + if (childrenLinkFn) { + childrenLinkFn(vm, childNodes, host, scope, frag) + } + } + } + } + + /** + * Check for element directives (custom elements that should + * be resovled as terminal directives). + * + * @param {Element} el + * @param {Object} options + */ + + function checkElementDirectives (el, options) { + var tag = el.tagName.toLowerCase() + if (_.commonTagRE.test(tag)) return + var def = resolveAsset(options, 'elementDirectives', tag) + if (def) { + return makeTerminalNodeLinkFn(el, tag, '', options, def) + } + } + + /** + * Check if an element is a component. If yes, return + * a component link function. + * + * @param {Element} el + * @param {Object} options + * @return {Function|undefined} + */ + + function checkComponent (el, options) { + var component = _.checkComponent(el, options) + if (component) { + var descriptor = { + name: 'component', + expression: component.id, + def: internalDirectives.component, + modifiers: { + literal: !component.dynamic + } + } + var componentLinkFn = function (vm, el, host, scope, frag) { + vm._bindDir(descriptor, el, host, scope, frag) + } + componentLinkFn.terminal = true + return componentLinkFn + } + } + + /** + * Check an element for terminal directives in fixed order. + * If it finds one, return a terminal link function. + * + * @param {Element} el + * @param {Object} options + * @return {Function} terminalLinkFn + */ + + function checkTerminalDirectives (el, options) { + // skip v-pre + if (_.attr(el, 'v-pre') !== null) { + return skip + } + // skip v-else block, but only if following v-if + if (el.hasAttribute('v-else')) { + var prev = el.previousElementSibling + if (prev && prev.hasAttribute('v-if')) { + return skip + } + } + var value, dirName + for (var i = 0, l = terminalDirectives.length; i < l; i++) { + dirName = terminalDirectives[i] + /* eslint-disable no-cond-assign */ + if (value = el.getAttribute('v-' + dirName)) { + return makeTerminalNodeLinkFn(el, dirName, value, options) + } + /* eslint-enable no-cond-assign */ + } + } + + function skip () {} + skip.terminal = true + + /** + * Build a node link function for a terminal directive. + * A terminal link function terminates the current + * compilation recursion and handles compilation of the + * subtree in the directive. + * + * @param {Element} el + * @param {String} dirName + * @param {String} value + * @param {Object} options + * @param {Object} [def] + * @return {Function} terminalLinkFn + */ + + function makeTerminalNodeLinkFn (el, dirName, value, options, def) { + var parsed = dirParser.parse(value) + var descriptor = { + name: dirName, + expression: parsed.expression, + filters: parsed.filters, + raw: value, + // either an element directive, or if/for + def: def || publicDirectives[dirName] + } + var fn = function terminalNodeLinkFn (vm, el, host, scope, frag) { + vm._bindDir(descriptor, el, host, scope, frag) + } + fn.terminal = true + return fn + } + + /** + * Compile the directives on an element and return a linker. + * + * @param {Array|NamedNodeMap} attrs + * @param {Object} options + * @return {Function} + */ + + function compileDirectives (attrs, options) { + var i = attrs.length + var dirs = [] + var attr, name, value, rawName, rawValue, dirName, arg, modifiers, dirDef, tokens + while (i--) { + attr = attrs[i] + name = rawName = attr.name + value = rawValue = attr.value + tokens = textParser.parse(value) + // reset arg + arg = null + // check modifiers + modifiers = parseModifiers(name) + name = name.replace(modifierRE, '') + + // attribute interpolations + if (tokens) { + value = textParser.tokensToExp(tokens) + arg = name + pushDir('bind', publicDirectives.bind, true) + } else + + // special attribute: transition + if (transitionRE.test(name)) { + modifiers.literal = !bindRE.test(name) + pushDir('transition', internalDirectives.transition) + } else + + // event handlers + if (onRE.test(name)) { + arg = name.replace(onRE, '') + pushDir('on', publicDirectives.on) + } else + + // attribute bindings + if (bindRE.test(name)) { + dirName = name.replace(bindRE, '') + if (dirName === 'style' || dirName === 'class') { + pushDir(dirName, internalDirectives[dirName]) + } else { + arg = dirName + pushDir('bind', publicDirectives.bind) + } + } else + + // normal directives + if (name.indexOf('v-') === 0) { + // check arg + arg = (arg = name.match(argRE)) && arg[1] + if (arg) { + name = name.replace(argRE, '') + } + // extract directive name + dirName = name.slice(2) + + // skip v-else (when used with v-show) + if (dirName === 'else') { + continue + } + + dirDef = resolveAsset(options, 'directives', dirName) + + if (true) { + _.assertAsset(dirDef, 'directive', dirName) + } + + if (dirDef) { + if (_.isLiteral(value)) { + value = _.stripQuotes(value) + modifiers.literal = true + } + pushDir(dirName, dirDef) + } + } + } + + /** + * Push a directive. + * + * @param {String} dirName + * @param {Object|Function} def + * @param {Boolean} [interp] + */ + + function pushDir (dirName, def, interp) { + var parsed = dirParser.parse(value) + dirs.push({ + name: dirName, + attr: rawName, + raw: rawValue, + def: def, + arg: arg, + modifiers: modifiers, + expression: parsed.expression, + filters: parsed.filters, + interp: interp + }) + } + + if (dirs.length) { + return makeNodeLinkFn(dirs) + } + } + + /** + * Parse modifiers from directive attribute name. + * + * @param {String} name + * @return {Object} + */ + + function parseModifiers (name) { + var res = Object.create(null) + var match = name.match(modifierRE) + if (match) { + var i = match.length + while (i--) { + res[match[i].slice(1)] = true + } + } + return res + } + + /** + * Build a link function for all directives on a single node. + * + * @param {Array} directives + * @return {Function} directivesLinkFn + */ + + function makeNodeLinkFn (directives) { + return function nodeLinkFn (vm, el, host, scope, frag) { + // reverse apply because it's sorted low to high + var i = directives.length + while (i--) { + vm._bindDir(directives[i], el, host, scope, frag) + } + } + } + + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + // text & html + exports.text = __webpack_require__(17) + exports.html = __webpack_require__(18) + + // logic control + exports['for'] = __webpack_require__(20) + exports['if'] = __webpack_require__(23) + exports.show = __webpack_require__(24) + + // two-way binding + exports.model = __webpack_require__(25) + + // event handling + exports.on = __webpack_require__(30) + + // attributes + exports.bind = __webpack_require__(31) + + // ref & el + exports.el = __webpack_require__(33) + exports.ref = __webpack_require__(34) + + // cloak + exports.cloak = __webpack_require__(35) + + +/***/ }, +/* 17 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + module.exports = { + + bind: function () { + this.attr = this.el.nodeType === 3 + ? 'data' + : 'textContent' + }, + + update: function (value) { + this.el[this.attr] = _.toString(value) + } + } + + +/***/ }, +/* 18 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var templateParser = __webpack_require__(19) + + module.exports = { + + bind: function () { + // a comment node means this is a binding for + // {{{ inline unescaped html }}} + if (this.el.nodeType === 8) { + // hold nodes + this.nodes = [] + // replace the placeholder with proper anchor + this.anchor = _.createAnchor('v-html') + _.replace(this.el, this.anchor) + } + }, + + update: function (value) { + value = _.toString(value) + if (this.nodes) { + this.swap(value) + } else { + this.el.innerHTML = value + } + }, + + swap: function (value) { + // remove old nodes + var i = this.nodes.length + while (i--) { + _.remove(this.nodes[i]) + } + // convert new value to a fragment + // do not attempt to retrieve from id selector + var frag = templateParser.parse(value, true, true) + // save a reference to these nodes so we can remove later + this.nodes = _.toArray(frag.childNodes) + _.before(frag, this.anchor) + } + } + + +/***/ }, +/* 19 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var Cache = __webpack_require__(7) + var templateCache = new Cache(1000) + var idSelectorCache = new Cache(1000) + + var map = { + _default: [0, '', ''], + legend: [1, '
', '
'], + tr: [2, '', '
'], + col: [ + 2, + '', + '
' + ] + } + + map.td = + map.th = [ + 3, + '', + '
' + ] + + map.option = + map.optgroup = [ + 1, + '' + ] + + map.thead = + map.tbody = + map.colgroup = + map.caption = + map.tfoot = [1, '', '
'] + + map.g = + map.defs = + map.symbol = + map.use = + map.image = + map.text = + map.circle = + map.ellipse = + map.line = + map.path = + map.polygon = + map.polyline = + map.rect = [ + 1, + '', + '' + ] + + /** + * Check if a node is a supported template node with a + * DocumentFragment content. + * + * @param {Node} node + * @return {Boolean} + */ + + function isRealTemplate (node) { + return _.isTemplate(node) && + node.content instanceof DocumentFragment + } + + var tagRE = /<([\w:]+)/ + var entityRE = /&\w+;|&#\d+;|&#x[\dA-F]+;/ + + /** + * Convert a string template to a DocumentFragment. + * Determines correct wrapping by tag types. Wrapping + * strategy found in jQuery & component/domify. + * + * @param {String} templateString + * @return {DocumentFragment} + */ + + function stringToFragment (templateString) { + // try a cache hit first + var hit = templateCache.get(templateString) + if (hit) { + return hit + } + + var frag = document.createDocumentFragment() + var tagMatch = templateString.match(tagRE) + var entityMatch = entityRE.test(templateString) + + if (!tagMatch && !entityMatch) { + // text only, return a single text node. + frag.appendChild( + document.createTextNode(templateString) + ) + } else { + + var tag = tagMatch && tagMatch[1] + var wrap = map[tag] || map._default + var depth = wrap[0] + var prefix = wrap[1] + var suffix = wrap[2] + var node = document.createElement('div') + + node.innerHTML = prefix + templateString.trim() + suffix + while (depth--) { + node = node.lastChild + } + + var child + /* eslint-disable no-cond-assign */ + while (child = node.firstChild) { + /* eslint-enable no-cond-assign */ + frag.appendChild(child) + } + } + + templateCache.put(templateString, frag) + return frag + } + + /** + * Convert a template node to a DocumentFragment. + * + * @param {Node} node + * @return {DocumentFragment} + */ + + function nodeToFragment (node) { + // if its a template tag and the browser supports it, + // its content is already a document fragment. + if (isRealTemplate(node)) { + _.trimNode(node.content) + return node.content + } + // script template + if (node.tagName === 'SCRIPT') { + return stringToFragment(node.textContent) + } + // normal node, clone it to avoid mutating the original + var clone = exports.clone(node) + var frag = document.createDocumentFragment() + var child + /* eslint-disable no-cond-assign */ + while (child = clone.firstChild) { + /* eslint-enable no-cond-assign */ + frag.appendChild(child) + } + _.trimNode(frag) + return frag + } + + // Test for the presence of the Safari template cloning bug + // https://bugs.webkit.org/show_bug.cgi?id=137755 + var hasBrokenTemplate = (function () { + /* istanbul ignore else */ + if (_.inBrowser) { + var a = document.createElement('div') + a.innerHTML = '' + return !a.cloneNode(true).firstChild.innerHTML + } else { + return false + } + })() + + // Test for IE10/11 textarea placeholder clone bug + var hasTextareaCloneBug = (function () { + /* istanbul ignore else */ + if (_.inBrowser) { + var t = document.createElement('textarea') + t.placeholder = 't' + return t.cloneNode(true).value === 't' + } else { + return false + } + })() + + /** + * 1. Deal with Safari cloning nested