diff --git a/app/assets/javascripts/setting_format.js b/app/assets/javascripts/setting_format.js deleted file mode 100644 index ae5cbcc..0000000 --- a/app/assets/javascripts/setting_format.js +++ /dev/null @@ -1,15 +0,0 @@ -(function(){ - "use strict"; - - $(function(){ - var $select = $('#setting-format select'); - if($select.length === 0) return; - - var $options = $('#setting-format-options'); - console.log($options); - debugger; - $select.on("change", function(ev){ - }); - }); -})(); - diff --git a/app/assets/javascripts/vue/fluent_log.js b/app/assets/javascripts/vue/fluent_log.js index 2cab738..016ab86 100644 --- a/app/assets/javascripts/vue/fluent_log.js +++ b/app/assets/javascripts/vue/fluent_log.js @@ -14,10 +14,7 @@ "processing": false }, - created: function(){ - if(this.initialAutoReload) { - this.autoFetch = true; - } + compiled: function(){ this.fetchLogs(); var self = this; @@ -33,6 +30,9 @@ clearInterval(timer); } }); + if(this.initialAutoReload) { + this.autoFetch = true; + } }, computed: { diff --git a/app/assets/javascripts/vue/in_tail_format.js b/app/assets/javascripts/vue/in_tail_format.js index 3b2489e..d7bb0e5 100644 --- a/app/assets/javascripts/vue/in_tail_format.js +++ b/app/assets/javascripts/vue/in_tail_format.js @@ -4,45 +4,58 @@ $(function(){ if($('#in_tail_format').length === 0) return; + var FormatBundle = Vue.component('format-bundle', { + inherit: true, + template: "#format-bundle", + computed: { + options: { + get: function(){ + return _.contains(this.selectableFormats, this.format) && this.formatOptions[this.format]; + }, + }, + selectableFormats: { + get: function() { + if(!this.formatOptions) return [""]; + var formats = Object.keys(this.formatOptions); + return formats; + } + } + } + }); + new Vue({ el: "#in_tail_format", - paramAttributes: ["formatOptions", "initialSelected", "targetFile", "paramsJson"], + paramAttributes: ["formatOptionsJson", "initialSelected", "targetFile", "paramsJson"], data: { - regexp: "", - grok_str: "", - time_format: "", previewProcessing: false, - highlightedLines: null + format: "", + highlightedLines: null, }, - created: function(){ - this.formatOptions = JSON.parse(this.formatOptions); - this.formats = Object.keys(this.formatOptions); + compiled: function(){ + this.$watch('params.setting.regexp', function(){ + this.preview(); + }); + this.$watch('format', function(){ + this.preview(); + }); + this.$set("formatOptions", JSON.parse(this.formatOptionsJson)); this.format = this.initialSelected; - this.params = JSON.parse(this.paramsJson); - if(this.params && this.params.setting) { - this.grok_str = this.params.setting.grok_str; - this.regexp = this.params.setting.regexp; + + // initialize params + // NOTE: if `params.setting.foo` is undefined, Vue can't binding with v-model="params.setting.foo" + var params = JSON.parse(this.paramsJson); + if(!params.setting) { + params.setting = {}; } - this.$watch('regexp', function(ev){ - this.preview(); + _.each(this.formatOptions, function(options){ + _.each(options, function(key){ + if(!params.setting.hasOwnProperty(key)){ + params.setting[key] = ""; + } + }); }); - this.$watch('format', function(ev){ - this.preview(); - }); - - var updateGrokPreview = _.debounce(_.bind(this.generateRegexp, this), 256); - this.$watch('grok_str', updateGrokPreview); - }, - - computed: { - options: function(){ - return this.formatOptions[this.format]; - }, - - selectableFormats: function() { - return _.filter(this.formats, function(format){ return format !== "regexp"; }); - } + this.$set('params', params); }, methods: { @@ -114,38 +127,20 @@ method: "POST", url: "/api/regexp_preview", data: { - regexp: self.regexp, - format: self.formatType == "regexp" ? "regexp" : self.format, - time_format: self.time_format, + regexp: self.params.setting.regexp, + time_format: self.params.setting.time_format, + format: _.isEmpty(self.format) ? "regexp" : self.format, file: self.targetFile } }).done(resolve).fail(reject); }).then(function(result){ - self.time_format = result.time_format; + self.params = _.merge(self.params, result.params); self.regexpMatches = result.matches; self.updateHighlightedLines(); })["catch"](function(error){ console.error(error.stack); }); }, - - generateRegexp: function() { - // for grok - var self = this; - new Promise(function(resolve, reject) { - $.ajax({ - method: "POST", - url: "/api/grok_to_regexp", - data: { - grok_str: self.grok_str - } - }).done(resolve).fail(reject); - }).then(function(regexp){ - self.regexp = regexp; - }).catch(function(e){ - console.error(e); - }); - }, } }); }); diff --git a/app/assets/javascripts/notification.js b/app/assets/javascripts/vue/notification.js similarity index 93% rename from app/assets/javascripts/notification.js rename to app/assets/javascripts/vue/notification.js index 587066f..04aa6ae 100644 --- a/app/assets/javascripts/notification.js +++ b/app/assets/javascripts/vue/notification.js @@ -46,10 +46,10 @@ computed: { alertsCount: { - $get: function(){ return this.alerts.length; } + get: function(){ return this.alerts.length; } }, hasAlerts: { - $get: function(){ return this.alertsCount > 0; } + get: function(){ return this.alertsCount > 0; } } }, diff --git a/app/assets/javascripts/vue/settings.js b/app/assets/javascripts/vue/settings.js index 6148e88..64f685a 100644 --- a/app/assets/javascripts/vue/settings.js +++ b/app/assets/javascripts/vue/settings.js @@ -7,24 +7,29 @@ new Vue({ el: el, - data: { - loaded: false, - loading: false, - sections: { - sources: [], - matches: [] - } + data: function(){ + return { + loaded: false, + loading: false, + sections: { + sources: [], + matches: [] + } + }; }, - created: function() { + ready: function() { this.update(); }, components: { section: { + inherit: true, template: "#vue-setting-section", - data: { - mode: "default", - processing: false, - editContent: null + data: function(){ + return { + mode: "default", + processing: false, + editContent: null + }; }, created: function(){ this.initialState(); @@ -57,16 +62,20 @@ content: this.editContent } }).then(function(data){ - // NOTE: child VM update doesn't effect to parent VM (at least Vue v0.10) - self.$data = data; + // NOTE: self.$data = data doesn't work as well, so using _.each + // whole $data swapping breaks mode switching.. + _.each(data, function(v,k){ + self[k] = v; + }); self.initialState(); }).always(function(){ self.processing = false; }); }, initialState: function(){ - this.mode = "default"; - this.editContent = this.content; + this.$set('processing', false); + this.$set('mode', 'default'); + this.$set('editContent', this.content); }, destroy: function(){ var self = this; diff --git a/app/assets/javascripts/vue/treeview.js b/app/assets/javascripts/vue/treeview.js index 0b8f9f9..51fc929 100644 --- a/app/assets/javascripts/vue/treeview.js +++ b/app/assets/javascripts/vue/treeview.js @@ -9,11 +9,12 @@ paramAttributes: [], data: { preview: "", + path: "", initialPath: "/var/log", paths: [] }, - created: function(){ + compiled: function(){ this.path = this.initialPath; this.fetchTree(); this.$watch("path", this.fetchTree); diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index f8d2f55..998b784 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -22,8 +22,12 @@ class ApiController < ApplicationController preview = RegexpPreview.new(params[:file], params[:format], regexp: params[:regexp], time_format: params[:time_format]) matches = preview.matches render json: { - regexp: preview.regexp.try(:source), - time_format: preview.time_format, + params: { + setting: { + regexp: preview.regexp.try(:source), + time_format: preview.time_format, + } + }, matches: matches.compact, } end diff --git a/app/views/shared/vue/_in_tail_format.html.erb b/app/views/shared/vue/_in_tail_format.html.erb index d784e6c..7b6b66c 100644 --- a/app/views/shared/vue/_in_tail_format.html.erb +++ b/app/views/shared/vue/_in_tail_format.html.erb @@ -1,19 +1,4 @@ -
-
- - -
- -
+ -
-
- - - -
-
- - -
-
+
+ +
{{{ highlightedLines }}}
diff --git a/bower.json b/bower.json index e143c1d..c1dd6ec 100644 --- a/bower.json +++ b/bower.json @@ -2,7 +2,7 @@ "name": "fluentd-ui", "dependencies": { "es6-promise": "~1.0.0", - "vue": "~0.10.0", + "vue": "~0.11.0", "lodash": "~2.4.0" }, "devDependencies": { diff --git a/vendor/assets/javascripts/bower/vue/.bower.json b/vendor/assets/javascripts/bower/vue/.bower.json index 30a2288..ff27e96 100644 --- a/vendor/assets/javascripts/bower/vue/.bower.json +++ b/vendor/assets/javascripts/bower/vue/.bower.json @@ -1,6 +1,6 @@ { "name": "vue", - "version": "0.10.6", + "version": "0.11.0", "main": "dist/vue.js", "description": "Simple, Fast & Composable MVVM for building interative interfaces", "authors": [ @@ -11,19 +11,19 @@ ".*", "examples", "test", - "tasks", - "Gruntfile.js", + "grunt", + "gruntfile.js", "*.json", "*.md" ], "homepage": "https://github.com/yyx990803/vue", - "_release": "0.10.6", + "_release": "0.11.0", "_resolution": { "type": "version", - "tag": "v0.10.6", - "commit": "cf37f7efd6d63c0aa46b50c624816e645ddd7edd" + "tag": "0.11.0", + "commit": "5bc3e30b694dc3b6aeeb87c24f88b9cd7a7259d6" }, "_source": "git://github.com/yyx990803/vue.git", - "_target": "~0.10.0", + "_target": "~0.11.0", "_originalSource": "vue" } \ No newline at end of file diff --git a/vendor/assets/javascripts/bower/vue/LICENSE b/vendor/assets/javascripts/bower/vue/LICENSE index 17a9b2f..405481c 100644 --- a/vendor/assets/javascripts/bower/vue/LICENSE +++ b/vendor/assets/javascripts/bower/vue/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013 Yuxi Evan You +Copyright (c) 2013-2014 Yuxi Evan You Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/assets/javascripts/bower/vue/dist/vue.js b/vendor/assets/javascripts/bower/vue/dist/vue.js index a747ba9..ab0eefc 100644 --- a/vendor/assets/javascripts/bower/vue/dist/vue.js +++ b/vendor/assets/javascripts/bower/vue/dist/vue.js @@ -1,4772 +1,7615 @@ -/* - Vue.js v0.10.6 - (c) 2014 Evan You - License: MIT -*/ -;(function(){ -'use strict'; - /** - * Require the given path. - * - * @param {String} path - * @return {Object} exports - * @api public + * Vue.js v0.11.0 + * (c) 2014 Evan You + * Released under the MIT License. */ -function require(path, parent, orig) { - var resolved = require.resolve(path); +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define(factory); + else if(typeof exports === 'object') + exports["Vue"] = factory(); + else + root["Vue"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // 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 +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // 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 = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { - // lookup failed - if (null == resolved) { - throwError() - return - } + var _ = __webpack_require__(1) + var extend = _.extend - var module = require.modules[resolved]; + /** + * The exposed Vue constructor. + * + * API conventions: + * - public API methods/properties are prefiexed with `$` + * - internal methods/properties are prefixed with `_` + * - non-prefixed properties are assumed to be proxied user + * data. + * + * @constructor + * @param {Object} [options] + * @public + */ - // perform real require() - // by invoking the module's - // registered function - if (!module._resolving && !module.exports) { - var mod = {}; - mod.exports = {}; - mod.client = mod.component = true; - module._resolving = true; - module.call(this, mod.exports, require.relative(resolved), mod); - delete module._resolving; - module.exports = mod.exports; - } + function Vue (options) { + this._init(options) + } - function throwError () { - orig = orig || path; - parent = parent || 'root'; - var err = new Error('Failed to require "' + orig + '" from "' + parent + '"'); - err.path = orig; - err.parent = parent; - err.require = true; - throw err; - } + /** + * Mixin global API + */ - return module.exports; -} + extend(Vue, __webpack_require__(2)) -/** - * Registered modules. - */ + /** + * Vue and every constructor that extends Vue has an + * associated options object, which can be accessed during + * compilation steps as `this.constructor.options`. + * + * These can be seen as the default options of every + * Vue instance. + */ -require.modules = {}; + Vue.options = { + directives : __webpack_require__(8), + filters : __webpack_require__(9), + partials : {}, + transitions : {}, + components : {} + } -/** - * Registered aliases. - */ + /** + * Build up the prototype + */ -require.aliases = {}; + var p = Vue.prototype -/** - * Resolve `path`. - * - * Lookup: - * - * - PATH/index.js - * - PATH.js - * - PATH - * - * @param {String} path - * @return {String} path or null - * @api private - */ + /** + * $data has a setter which does a bunch of + * teardown/setup work + */ -require.exts = [ - '', - '.js', - '.json', - '/index.js', - '/index.json' - ]; + Object.defineProperty(p, '$data', { + get: function () { + return this._data + }, + set: function (newData) { + this._setData(newData) + } + }) -require.resolve = function(path) { - if (path.charAt(0) === '/') path = path.slice(1); + /** + * Mixin internal instance methods + */ - for (var i = 0; i < 5; i++) { - var fullPath = path + require.exts[i]; - if (require.modules.hasOwnProperty(fullPath)) return fullPath; - if (require.aliases.hasOwnProperty(fullPath)) return require.aliases[fullPath]; - } -}; + extend(p, __webpack_require__(10)) + extend(p, __webpack_require__(11)) + extend(p, __webpack_require__(12)) + extend(p, __webpack_require__(13)) -/** - * Normalize `path` relative to the current path. - * - * @param {String} curr - * @param {String} path - * @return {String} - * @api private - */ + /** + * Mixin public API methods + */ -require.normalize = function(curr, path) { + extend(p, __webpack_require__(3)) + extend(p, __webpack_require__(4)) + extend(p, __webpack_require__(5)) + extend(p, __webpack_require__(6)) + extend(p, __webpack_require__(7)) - var segs = []; + module.exports = _.Vue = Vue - if ('.' != path.charAt(0)) return path; +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { - curr = curr.split('/'); - path = path.split('/'); + var lang = __webpack_require__(14) + var extend = lang.extend - for (var i = 0; i < path.length; ++i) { - if ('..' === path[i]) { - curr.pop(); - } else if ('.' != path[i] && '' != path[i]) { - segs.push(path[i]); - } - } - return curr.concat(segs).join('/'); -}; + extend(exports, lang) + extend(exports, __webpack_require__(15)) + extend(exports, __webpack_require__(16)) + extend(exports, __webpack_require__(17)) + extend(exports, __webpack_require__(18)) -/** - * Register module at `path` with callback `definition`. - * - * @param {String} path - * @param {Function} definition - * @api private - */ +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { -require.register = function(path, definition) { - require.modules[path] = definition; -}; + var _ = __webpack_require__(1) + var mergeOptions = __webpack_require__(19) -/** - * Alias a module definition. - * - * @param {String} from - * @param {String} to - * @api private - */ + /** + * Expose useful internals + */ -require.alias = function(from, to) { - if (!require.modules.hasOwnProperty(from)) { - throwError() - return - } - require.aliases[to] = from; + exports.util = _ + exports.nextTick = _.nextTick + exports.config = __webpack_require__(20) - function throwError () { - throw new Error('Failed to alias "' + from + '", it does not exist'); - } -}; + /** + * Each instance constructor, including Vue, has a unique + * cid. This enables us to create wrapped "child + * constructors" for prototypal inheritance and cache them. + */ -/** - * Return a require function relative to the `parent` path. - * - * @param {String} parent - * @return {Function} - * @api private - */ + exports.cid = 0 + var cid = 1 -require.relative = function(parent) { - var p = require.normalize(parent, '..'); + /** + * Class inehritance + * + * @param {Object} extendOptions + */ - /** - * The relative require() itself. - */ + exports.extend = function (extendOptions) { + extendOptions = extendOptions || {} + var Super = this + var Sub = createClass(extendOptions.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. + createAssetRegisters(Sub) + return Sub + } - function localRequire(path) { - var resolved = localRequire.resolve(path); - return require(resolved, parent, path); - } + /** + * 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} + */ - /** - * Resolve relative to the parent. - */ + function createClass (name) { + return new Function( + 'return function ' + _.camelize(name, true) + + ' (options) { this._init(options) }' + )() + } - localRequire.resolve = function(path) { - var c = path.charAt(0); - if ('/' === c) return path.slice(1); - if ('.' === c) return require.normalize(p, path); + /** + * Plugin system + * + * @param {Object} plugin + */ - // resolve deps by returning - // the dep in the nearest "deps" - // directory - var segs = parent.split('/'); - var i = segs.length; - while (i--) { - if (segs[i] === 'deps') { - break; - } - } - path = segs.slice(0, i + 2).join('/') + '/deps/' + path; - return path; - }; + exports.use = function (plugin) { + // 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) + } + return this + } - /** - * Check if module is defined at `path`. - */ + /** + * Define asset registration methods on a constructor. + * + * @param {Function} Constructor + */ - localRequire.exists = function(path) { - return require.modules.hasOwnProperty(localRequire.resolve(path)); - }; + var assetTypes = [ + 'directive', + 'filter', + 'partial', + 'transition' + ] - return localRequire; -}; -require.register("vue/src/main.js", function(exports, require, module){ -var config = require('./config'), - ViewModel = require('./viewmodel'), - utils = require('./utils'), - makeHash = utils.hash, - assetTypes = ['directive', 'filter', 'partial', 'effect', 'component'], - // Internal modules that are exposed for plugins - pluginAPI = { - utils: utils, - config: config, - transition: require('./transition'), - observer: require('./observer') - } + function createAssetRegisters (Constructor) { -ViewModel.options = config.globalAssets = { - directives : require('./directives'), - filters : require('./filters'), - partials : makeHash(), - effects : makeHash(), - components : makeHash() -} + /* Asset registration methods share the same signature: + * + * @param {String} id + * @param {*} definition + */ -/** - * Expose asset registration methods - */ -assetTypes.forEach(function (type) { - ViewModel[type] = function (id, value) { - var hash = this.options[type + 's'] - if (!hash) { - hash = this.options[type + 's'] = makeHash() - } - if (!value) return hash[id] - if (type === 'partial') { - value = utils.parseTemplateOption(value) - } else if (type === 'component') { - value = utils.toConstructor(value) - } else if (type === 'filter') { - utils.checkFilter(value) - } - hash[id] = value - return this - } -}) + assetTypes.forEach(function (type) { + Constructor[type] = function (id, definition) { + if (!definition) { + return this.options[type + 's'][id] + } else { + this.options[type + 's'][id] = definition + } + } + }) -/** - * Set config options - */ -ViewModel.config = function (opts, val) { - if (typeof opts === 'string') { - if (val === undefined) { - return config[opts] - } else { - config[opts] = val - } - } else { - utils.extend(config, opts) - } - return this -} + /** + * Component registration needs to automatically invoke + * Vue.extend on object values. + * + * @param {String} id + * @param {Object|Function} definition + */ -/** - * Expose an interface for plugins - */ -ViewModel.use = function (plugin) { - if (typeof plugin === 'string') { - try { - plugin = require(plugin) - } catch (e) { - utils.warn('Cannot find plugin: ' + plugin) - return - } - } + Constructor.component = function (id, definition) { + if (!definition) { + return this.options.components[id] + } else { + if (_.isPlainObject(definition)) { + definition.name = id + definition = _.Vue.extend(definition) + } + this.options.components[id] = definition + } + } + } - // additional parameters - var args = [].slice.call(arguments, 1) - args.unshift(this) + createAssetRegisters(exports) - if (typeof plugin.install === 'function') { - plugin.install.apply(plugin, args) - } else { - plugin.apply(null, args) - } - return this -} +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { -/** - * Expose internal modules for plugins - */ -ViewModel.require = function (module) { - return pluginAPI[module] -} + var _ = __webpack_require__(1) + var Watcher = __webpack_require__(21) + var Path = __webpack_require__(41) + var textParser = __webpack_require__(42) + var dirParser = __webpack_require__(43) + var expParser = __webpack_require__(44) + var filterRE = /[^|]\|[^|]/ -ViewModel.extend = extend -ViewModel.nextTick = utils.nextTick + /** + * Get the value from an expression on this vm. + * + * @param {String} exp + * @return {*} + */ -/** - * Expose the main ViewModel class - * and add extend method - */ -function extend (options) { + exports.$get = function (exp) { + var res = expParser.parse(exp) + if (res) { + return res.get.call(this, this) + } + } - var ParentVM = this + /** + * Set the value from an expression on this vm. + * The expression must be a valid left-hand + * expression in an assignment. + * + * @param {String} exp + * @param {*} val + */ - // extend data options need to be copied - // on instantiation - if (options.data) { - options.defaultData = options.data - delete options.data - } + exports.$set = function (exp, val) { + var res = expParser.parse(exp, true) + if (res && res.set) { + res.set.call(this, this, val) + } + } - // inherit options - // but only when the super class is not the native Vue. - if (ParentVM !== ViewModel) { - options = inheritOptions(options, ParentVM.options, true) - } - utils.processOptions(options) + /** + * Add a property on the VM + * + * @param {String} key + * @param {*} val + */ - var ExtendedVM = function (opts, asParent) { - if (!asParent) { - opts = inheritOptions(opts, options, true) - } - ParentVM.call(this, opts, true) - } + exports.$add = function (key, val) { + this._data.$add(key, val) + } - // inherit prototype props - var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype) - utils.defProtected(proto, 'constructor', ExtendedVM) + /** + * Delete a property on the VM + * + * @param {String} key + */ - // allow extended VM to be further extended - ExtendedVM.extend = extend - ExtendedVM.super = ParentVM - ExtendedVM.options = options + exports.$delete = function (key) { + this._data.$delete(key) + } - // allow extended VM to add its own assets - assetTypes.forEach(function (type) { - ExtendedVM[type] = ViewModel[type] - }) + /** + * Watch an expression, trigger callback when its + * value changes. + * + * @param {String} exp + * @param {Function} cb + * @param {Boolean} [deep] + * @param {Boolean} [immediate] + * @return {Function} - unwatchFn + */ - // allow extended VM to use plugins - ExtendedVM.use = ViewModel.use - ExtendedVM.require = ViewModel.require + exports.$watch = function (exp, cb, deep, immediate) { + var vm = this + var key = deep ? exp + '**deep**' : exp + var watcher = vm._userWatchers[key] + var wrappedCb = function (val, oldVal) { + cb.call(vm, val, oldVal) + } + if (!watcher) { + watcher = vm._userWatchers[key] = + new Watcher(vm, exp, wrappedCb, null, false, deep) + } else { + watcher.addCb(wrappedCb) + } + if (immediate) { + wrappedCb(watcher.value) + } + return function unwatchFn () { + watcher.removeCb(wrappedCb) + if (!watcher.active) { + vm._userWatchers[key] = null + } + } + } - return ExtendedVM -} + /** + * Evaluate a text directive, including filters. + * + * @param {String} text + * @return {String} + */ -/** - * Inherit options - * - * For options such as `data`, `vms`, `directives`, 'partials', - * they should be further extended. However extending should only - * be done at top level. - * - * `proto` is an exception because it's handled directly on the - * prototype. - * - * `el` is an exception because it's not allowed as an - * extension option, but only as an instance option. - */ -function inheritOptions (child, parent, topLevel) { - child = child || {} - if (!parent) return child - for (var key in parent) { - if (key === 'el') continue - var val = child[key], - parentVal = parent[key] - if (topLevel && typeof val === 'function' && parentVal) { - // merge hook functions into an array - child[key] = [val] - if (Array.isArray(parentVal)) { - child[key] = child[key].concat(parentVal) - } else { - child[key].push(parentVal) - } - } else if ( - topLevel && - (utils.isTrueObject(val) || utils.isTrueObject(parentVal)) - && !(parentVal instanceof ViewModel) - ) { - // merge toplevel object options - child[key] = inheritOptions(val, parentVal) - } else if (val === undefined) { - // inherit if child doesn't override - child[key] = parentVal - } - } - return child -} + exports.$eval = function (text) { + // check for filters. + if (filterRE.test(text)) { + var dir = dirParser.parse(text)[0] + // the filter regex check might give false positive + // for pipes inside strings, so it's possible that + // we don't get any filters here + return dir.filters + ? _.applyFilters( + this.$get(dir.expression), + _.resolveFilters(this, dir.filters).read, + this + ) + : this.$get(dir.expression) + } else { + // no filter + return this.$get(text) + } + } -module.exports = ViewModel + /** + * Interpolate a piece of template text. + * + * @param {String} text + * @return {String} + */ + + exports.$interpolate = function (text) { + var tokens = textParser.parse(text) + var vm = this + if (tokens) { + return tokens.length === 1 + ? vm.$eval(tokens[0].value) + : tokens.map(function (token) { + return token.tag + ? vm.$eval(token.value) + : token.value + }).join('') + } else { + return text + } + } + + /** + * Log instance data as a plain JS object + * so that it is easier to inspect in console. + * This method assumes console is available. + * + * @param {String} [path] + */ + + exports.$log = function (path) { + var data = path + ? Path.get(this, path) + : this._data + console.log(JSON.parse(JSON.stringify(data))) + } + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var transition = __webpack_require__(45) + + /** + * Append instance to target + * + * @param {Node} target + * @param {Function} [cb] + * @param {Boolean} [withTransition] - defaults to true + */ + + exports.$appendTo = function (target, cb, withTransition) { + target = query(target) + var targetIsDetached = !_.inDoc(target) + var op = withTransition === false || targetIsDetached + ? append + : transition.append + insert(this, target, op, targetIsDetached, cb) + return this + } + + /** + * Prepend instance to target + * + * @param {Node} target + * @param {Function} [cb] + * @param {Boolean} [withTransition] - defaults to true + */ + + exports.$prependTo = function (target, cb, withTransition) { + target = query(target) + if (target.hasChildNodes()) { + this.$before(target.firstChild, cb, withTransition) + } else { + this.$appendTo(target, cb, withTransition) + } + return this + } + + /** + * Insert instance before target + * + * @param {Node} target + * @param {Function} [cb] + * @param {Boolean} [withTransition] - defaults to true + */ + + exports.$before = function (target, cb, withTransition) { + target = query(target) + var targetIsDetached = !_.inDoc(target) + var op = withTransition === false || targetIsDetached + ? before + : transition.before + insert(this, target, op, targetIsDetached, cb) + return this + } + + /** + * Insert instance after target + * + * @param {Node} target + * @param {Function} [cb] + * @param {Boolean} [withTransition] - defaults to true + */ + + exports.$after = function (target, cb, withTransition) { + target = query(target) + if (target.nextSibling) { + this.$before(target.nextSibling, cb, withTransition) + } else { + this.$appendTo(target.parentNode, cb, withTransition) + } + return this + } + + /** + * Remove instance from DOM + * + * @param {Function} [cb] + * @param {Boolean} [withTransition] - defaults to true + */ + + exports.$remove = function (cb, withTransition) { + var inDoc = this._isAttached && _.inDoc(this.$el) + // if we are not in document, no need to check + // for transitions + if (!inDoc) withTransition = false + var op + var self = this + var realCb = function () { + if (inDoc) self._callHook('detached') + if (cb) cb() + } + if ( + this._isBlock && + !this._blockFragment.hasChildNodes() + ) { + op = withTransition === false + ? append + : transition.removeThenAppend + blockOp(this, this._blockFragment, op, realCb) + } else { + op = withTransition === false + ? remove + : transition.remove + op(this.$el, this, realCb) + } + return this + } + + /** + * Shared DOM insertion function. + * + * @param {Vue} vm + * @param {Element} target + * @param {Function} op + * @param {Boolean} targetIsDetached + * @param {Function} [cb] + */ + + function insert (vm, target, op, targetIsDetached, cb) { + var shouldCallHook = + !targetIsDetached && + !vm._isAttached && + !_.inDoc(vm.$el) + if (vm._isBlock) { + blockOp(vm, target, op, cb) + } else { + op(vm.$el, target, vm, cb) + } + if (shouldCallHook) { + vm._callHook('attached') + } + } + + /** + * Execute a transition operation on a block instance, + * iterating through all its block nodes. + * + * @param {Vue} vm + * @param {Node} target + * @param {Function} op + * @param {Function} cb + */ + + function blockOp (vm, target, op, cb) { + var current = vm._blockStart + var end = vm._blockEnd + var next + while (next !== end) { + next = current.nextSibling + op(current, target, vm) + current = next + } + op(end, target, vm, cb) + } + + /** + * Check for selectors + * + * @param {String|Element} el + */ + + function query (el) { + return typeof el === 'string' + ? document.querySelector(el) + : el + } + + /** + * Append operation that takes a callback. + * + * @param {Node} el + * @param {Node} target + * @param {Vue} vm - unused + * @param {Function} [cb] + */ + + function append (el, target, vm, cb) { + target.appendChild(el) + if (cb) cb() + } + + /** + * InsertBefore operation that takes a callback. + * + * @param {Node} el + * @param {Node} target + * @param {Vue} vm - unused + * @param {Function} [cb] + */ + + function before (el, target, vm, cb) { + _.before(el, target) + if (cb) cb() + } + + /** + * Remove operation that takes a callback. + * + * @param {Node} el + * @param {Vue} vm - unused + * @param {Function} [cb] + */ + + function remove (el, vm, cb) { + _.remove(el) + if (cb) cb() + } + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + /** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + */ + + exports.$on = function (event, fn) { + (this._events[event] || (this._events[event] = [])) + .push(fn) + modifyListenerCount(this, event, 1) + return this + } + + /** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + */ + + exports.$once = function (event, fn) { + var self = this + function on () { + self.$off(event, on) + fn.apply(this, arguments) + } + on.fn = fn + this.$on(event, on) + return this + } + + /** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + */ + + exports.$off = function (event, fn) { + var cbs + // all + if (!arguments.length) { + if (this.$parent) { + for (event in this._events) { + cbs = this._events[event] + if (cbs) { + modifyListenerCount(this, event, -cbs.length) + } + } + } + this._events = {} + return this + } + // specific event + cbs = this._events[event] + if (!cbs) { + return this + } + if (arguments.length === 1) { + modifyListenerCount(this, event, -cbs.length) + this._events[event] = null + return this + } + // specific handler + var cb + var i = cbs.length + while (i--) { + cb = cbs[i] + if (cb === fn || cb.fn === fn) { + modifyListenerCount(this, event, -1) + cbs.splice(i, 1) + break + } + } + return this + } + + /** + * Trigger an event on self. + * + * @param {String} event + */ + + exports.$emit = function (event) { + this._eventCancelled = false + var cbs = this._events[event] + if (cbs) { + // avoid leaking arguments: + // http://jsperf.com/closure-with-arguments + var i = arguments.length - 1 + var args = new Array(i) + while (i--) { + args[i] = arguments[i + 1] + } + i = 0 + cbs = cbs.length > 1 + ? _.toArray(cbs) + : cbs + for (var l = cbs.length; i < l; i++) { + if (cbs[i].apply(this, args) === false) { + this._eventCancelled = true + } + } + } + return this + } + + /** + * Recursively broadcast an event to all children instances. + * + * @param {String} event + * @param {...*} additional arguments + */ + + exports.$broadcast = function (event) { + // if no child has registered for this event, + // then there's no need to broadcast. + if (!this._eventsCount[event]) return + var children = this._children + if (children) { + for (var i = 0, l = children.length; i < l; i++) { + var child = children[i] + child.$emit.apply(child, arguments) + if (!child._eventCancelled) { + child.$broadcast.apply(child, arguments) + } + } + } + return this + } + + /** + * Recursively propagate an event up the parent chain. + * + * @param {String} event + * @param {...*} additional arguments + */ + + exports.$dispatch = function () { + var parent = this.$parent + while (parent) { + parent.$emit.apply(parent, arguments) + parent = parent._eventCancelled + ? null + : parent.$parent + } + return this + } + + /** + * Modify the listener counts on all parents. + * This bookkeeping allows $broadcast to return early when + * no child has listened to a certain event. + * + * @param {Vue} vm + * @param {String} event + * @param {Number} count + */ + + var hookRE = /^hook:/ + function modifyListenerCount (vm, event, count) { + var parent = vm.$parent + // hooks do not get broadcasted so no need + // to do bookkeeping for them + if (!parent || !count || hookRE.test(event)) return + while (parent) { + parent._eventsCount[event] = + (parent._eventsCount[event] || 0) + count + parent = parent.$parent + } + } + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + /** + * Create a child instance that prototypally inehrits + * data on parent. To achieve that we create an intermediate + * constructor with its prototype pointing to parent. + * + * @param {Object} opts + * @param {Function} [BaseCtor] + * @return {Vue} + * @public + */ + + exports.$addChild = function (opts, BaseCtor) { + BaseCtor = BaseCtor || _.Vue + opts = opts || {} + var parent = this + var ChildVue + var inherit = opts.inherit !== undefined + ? opts.inherit + : BaseCtor.options.inherit + if (inherit) { + var ctors = parent._childCtors + if (!ctors) { + ctors = parent._childCtors = {} + } + ChildVue = ctors[BaseCtor.cid] + if (!ChildVue) { + var optionName = BaseCtor.options.name + var className = optionName + ? _.camelize(optionName, true) + : 'VueComponent' + ChildVue = new Function( + 'return function ' + className + ' (options) {' + + 'this.constructor = ' + className + ';' + + 'this._init(options) }' + )() + ChildVue.options = BaseCtor.options + ChildVue.prototype = this + ctors[BaseCtor.cid] = ChildVue + } + } else { + ChildVue = BaseCtor + } + opts._parent = parent + opts._root = parent.$root + var child = new ChildVue(opts) + if (!this._children) { + this._children = [] + } + this._children.push(child) + return child + } + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var compile = __webpack_require__(46) + + /** + * Set instance target element and kick off the compilation + * process. The passed in `el` can be a selector string, an + * existing Element, or a DocumentFragment (for block + * instances). + * + * @param {Element|DocumentFragment|string} el + * @public + */ + + exports.$mount = function (el) { + if (this._isCompiled) { + _.warn('$mount() should be called only once.') + return + } + if (!el) { + el = document.createElement('div') + } else if (typeof el === 'string') { + var selector = el + el = document.querySelector(el) + if (!el) { + _.warn('Cannot find element: ' + selector) + return + } + } + this._compile(el) + this._isCompiled = true + this._callHook('compiled') + if (_.inDoc(this.$el)) { + this._callHook('attached') + this._initDOMHooks() + ready.call(this) + } else { + this._initDOMHooks() + this.$once('hook:attached', ready) + } + return this + } + + /** + * Mark an instance as ready. + */ + + function ready () { + this._isAttached = true + this._isReady = true + this._callHook('ready') + } + + /** + * Teardown an instance, unobserves the data, unbind all the + * directives, turn off all the event listeners, etc. + * + * @param {Boolean} remove - whether to remove the DOM node. + * @public + */ + + exports.$destroy = function (remove) { + if (this._isBeingDestroyed) { + return + } + this._callHook('beforeDestroy') + this._isBeingDestroyed = true + var i + // remove self from parent. only necessary + // if parent is not being destroyed as well. + var parent = this.$parent + if (parent && !parent._isBeingDestroyed) { + i = parent._children.indexOf(this) + parent._children.splice(i, 1) + } + // destroy all children. + if (this._children) { + i = this._children.length + while (i--) { + this._children[i].$destroy() + } + } + // teardown all directives. this also tearsdown all + // directive-owned watchers. + i = this._directives.length + while (i--) { + this._directives[i]._teardown() + } + // teardown all user watchers. + for (i in this._userWatchers) { + this._userWatchers[i].teardown() + } + // remove reference to self on $el + if (this.$el) { + this.$el.__vue__ = null + } + // remove DOM element + var self = this + if (remove && this.$el) { + this.$remove(function () { + cleanup(self) + }) + } else { + cleanup(self) + } + } + + /** + * Clean up to ensure garbage collection. + * This is called after the leave transition if there + * is any. + * + * @param {Vue} vm + */ + + function cleanup (vm) { + // remove reference from data ob + vm._data.__ob__.removeVm(vm) + vm._data = + vm._watchers = + vm._userWatchers = + vm._watcherList = + vm.$el = + vm.$parent = + vm.$root = + vm._children = + vm._bindings = + vm._directives = null + // call the last hook... + vm._isDestroyed = true + vm._callHook('destroyed') + // turn off all instance listeners. + vm.$off() + } + + /** + * Partially compile a piece of DOM and return a + * decompile function. + * + * @param {Element|DocumentFragment} el + * @return {Function} + */ + + exports.$compile = function (el) { + return compile(el, this.$options, true)(this, el) + } + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { + + // manipulation directives + exports.text = __webpack_require__(22) + exports.html = __webpack_require__(23) + exports.attr = __webpack_require__(24) + exports.show = __webpack_require__(25) + exports['class'] = __webpack_require__(26) + exports.el = __webpack_require__(27) + exports.ref = __webpack_require__(28) + exports.cloak = __webpack_require__(29) + exports.style = __webpack_require__(30) + exports.partial = __webpack_require__(31) + exports.transition = __webpack_require__(32) + + // event listener directives + exports.on = __webpack_require__(33) + exports.model = __webpack_require__(48) + + // child vm directives + exports.component = __webpack_require__(34) + exports.repeat = __webpack_require__(35) + exports['if'] = __webpack_require__(36) + exports['with'] = __webpack_require__(37) + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + /** + * Stringify value. + * + * @param {Number} indent + */ + + exports.json = function (value, indent) { + return JSON.stringify(value, null, Number(indent) || 2) + } + + /** + * 'abc' => 'Abc' + */ + + exports.capitalize = function (value) { + if (!value && value !== 0) return '' + value = value.toString() + return value.charAt(0).toUpperCase() + value.slice(1) + } + + /** + * 'abc' => 'ABC' + */ + + exports.uppercase = function (value) { + return (value || value === 0) + ? value.toString().toUpperCase() + : '' + } + + /** + * 'AbC' => 'abc' + */ + + exports.lowercase = function (value) { + return (value || value === 0) + ? value.toString().toLowerCase() + : '' + } + + /** + * 12345 => $12,345.00 + * + * @param {String} sign + */ + + var digitsRE = /(\d{3})(?=\d)/g + + exports.currency = function (value, sign) { + value = parseFloat(value) + if (!value && value !== 0) return '' + sign = sign || '$' + var s = Math.floor(Math.abs(value)).toString(), + i = s.length % 3, + h = i > 0 + ? (s.slice(0, i) + (s.length > 3 ? ',' : '')) + : '', + f = '.' + value.toFixed(2).slice(-2) + return (value < 0 ? '-' : '') + + sign + h + s.slice(i).replace(digitsRE, '$1,') + f + } + + /** + * 'item' => 'items' + * + * @params + * an array of strings corresponding to + * the single, double, triple ... forms of the word to + * be pluralized. When the number to be pluralized + * exceeds the length of the args, it will use the last + * entry in the array. + * + * e.g. ['single', 'double', 'triple', 'multiple'] + */ + + exports.pluralize = function (value) { + var args = _.toArray(arguments, 1) + return args.length > 1 + ? (args[value % 10 - 1] || args[args.length - 1]) + : (args[0] + (value === 1 ? '' : 's')) + } + + /** + * A special filter that takes a handler function, + * wraps it so it only gets triggered on specific + * keypresses. v-on only. + * + * @param {String} key + */ + + var keyCodes = { + enter : 13, + tab : 9, + 'delete' : 46, + up : 38, + left : 37, + right : 39, + down : 40, + esc : 27 + } + + exports.key = function (handler, key) { + if (!handler) return + var code = keyCodes[key] + if (!code) { + code = parseInt(key, 10) + } + return function (e) { + if (e.keyCode === code) { + return handler.call(this, e) + } + } + } + + /** + * Install special array filters + */ + + _.extend(exports, __webpack_require__(38)) + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + var mergeOptions = __webpack_require__(19) + + /** + * The main init sequence. This is called for every + * instance, including ones that are created from extended + * constructors. + * + * @param {Object} options - this options object should be + * the result of merging class + * options and the options passed + * in to the constructor. + */ + + exports._init = function (options) { + + options = options || {} + + this.$el = null + this.$parent = options._parent + this.$root = options._root || this + this.$ = {} // child vm references + this.$$ = {} // element references + this._watcherList = [] // all watchers as an array + this._watchers = {} // internal watchers as a hash + this._userWatchers = {} // user watchers as a hash + this._directives = [] // all directives + + // a flag to avoid this being observed + this._isVue = true + + // events bookkeeping + this._events = {} // registered callbacks + this._eventsCount = {} // for $broadcast optimization + this._eventCancelled = false // for event cancellation + + // block instance properties + this._isBlock = false + this._blockStart = // @type {CommentNode} + this._blockEnd = null // @type {CommentNode} + + // lifecycle state + this._isCompiled = + this._isDestroyed = + this._isReady = + this._isAttached = + this._isBeingDestroyed = false + + // children + this._children = // @type {Array} + this._childCtors = null // @type {Object} - hash to cache + // child constructors + + // merge options. + options = this.$options = mergeOptions( + this.constructor.options, + options, + this + ) + + // set data after merge. + this._data = options.data || {} + + // initialize data observation and scope inheritance. + this._initScope() + + // setup event system and option events. + this._initEvents() + + // call created hook + this._callHook('created') + + // if `el` option is passed, start compilation. + if (options.el) { + this.$mount(options.el) + } + } + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var inDoc = _.inDoc + + /** + * Setup the instance's option events & watchers. + * If the value is a string, we pull it from the + * instance's methods by name. + */ + + exports._initEvents = function () { + var options = this.$options + registerCallbacks(this, '$on', options.events) + registerCallbacks(this, '$watch', options.watch) + } + + /** + * Register callbacks for option events and watchers. + * + * @param {Vue} vm + * @param {String} action + * @param {Object} hash + */ + + function registerCallbacks (vm, action, hash) { + if (!hash) return + var handlers, key, i, j + for (key in hash) { + handlers = hash[key] + if (_.isArray(handlers)) { + for (i = 0, j = handlers.length; i < j; i++) { + register(vm, action, key, handlers[i]) + } + } else { + register(vm, action, key, handlers) + } + } + } + + /** + * Helper to register an event/watch callback. + * + * @param {Vue} vm + * @param {String} action + * @param {String} key + * @param {*} handler + */ + + function register (vm, action, key, handler) { + var type = typeof handler + if (type === 'function') { + vm[action](key, handler) + } else if (type === 'string') { + var methods = vm.$options.methods + var method = methods && methods[handler] + if (method) { + vm[action](key, method) + } else { + _.warn( + 'Unknown method: "' + handler + '" when ' + + 'registering callback for ' + action + + ': "' + key + '".' + ) + } + } + } + + /** + * Setup recursive attached/detached calls + */ + + exports._initDOMHooks = function () { + this.$on('hook:attached', onAttached) + this.$on('hook:detached', onDetached) + } + + /** + * Callback to recursively call attached hook on children + */ + + function onAttached () { + this._isAttached = true + var children = this._children + if (!children) return + for (var i = 0, l = children.length; i < l; i++) { + var child = children[i] + if (!child._isAttached && inDoc(child.$el)) { + child._callHook('attached') + } + } + } + + /** + * Callback to recursively call detached hook on children + */ + + function onDetached () { + this._isAttached = false + var children = this._children + if (!children) return + for (var i = 0, l = children.length; i < l; i++) { + var child = children[i] + if (child._isAttached && !inDoc(child.$el)) { + child._callHook('detached') + } + } + } + + /** + * Trigger all handlers for a hook + * + * @param {String} hook + */ + + exports._callHook = function (hook) { + var handlers = this.$options[hook] + if (handlers) { + for (var i = 0, j = handlers.length; i < j; i++) { + handlers[i].call(this) + } + } + this.$emit('hook:' + hook) + } + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var Observer = __webpack_require__(49) + var Binding = __webpack_require__(39) + + /** + * Setup the scope of an instance, which contains: + * - observed data + * - computed properties + * - user methods + * - meta properties + */ + + exports._initScope = function () { + this._initData() + this._initComputed() + this._initMethods() + this._initMeta() + } + + /** + * Initialize the data. + */ + + exports._initData = function () { + // proxy data on instance + var data = this._data + var keys = Object.keys(data) + var i = keys.length + var key + while (i--) { + key = keys[i] + if (!_.isReserved(key)) { + this._proxy(key) + } + } + // observe data + Observer.create(data).addVm(this) + } + + /** + * Swap the isntance's $data. Called in $data's setter. + * + * @param {Object} newData + */ + + exports._setData = function (newData) { + newData = newData || {} + var oldData = this._data + this._data = newData + var keys, key, i + // unproxy keys not present in new data + keys = Object.keys(oldData) + i = keys.length + while (i--) { + key = keys[i] + if (!_.isReserved(key) && !(key in newData)) { + this._unproxy(key) + } + } + // proxy keys not already proxied, + // and trigger change for changed values + keys = Object.keys(newData) + i = keys.length + while (i--) { + key = keys[i] + if (!this.hasOwnProperty(key) && !_.isReserved(key)) { + // new property + this._proxy(key) + } + } + oldData.__ob__.removeVm(this) + Observer.create(newData).addVm(this) + this._digest() + } + + /** + * Proxy a property, so that + * vm.prop === vm._data.prop + * + * @param {String} key + */ + + exports._proxy = function (key) { + // need to store ref to self here + // because these getter/setters might + // be called by child instances! + var self = this + Object.defineProperty(self, key, { + configurable: true, + enumerable: true, + get: function proxyGetter () { + return self._data[key] + }, + set: function proxySetter (val) { + self._data[key] = val + } + }) + } + + /** + * Unproxy a property. + * + * @param {String} key + */ + + exports._unproxy = function (key) { + delete this[key] + } + + /** + * Force update on every watcher in scope. + */ + + exports._digest = function () { + var i = this._watcherList.length + while (i--) { + this._watcherList[i].update() + } + var children = this._children + var child + if (children) { + i = children.length + while (i--) { + child = children[i] + if (child.$options.inherit) { + child._digest() + } + } + } + } + + /** + * Setup computed properties. They are essentially + * special getter/setters + */ + + function noop () {} + exports._initComputed = function () { + var computed = this.$options.computed + if (computed) { + for (var key in computed) { + var userDef = computed[key] + var def = { + enumerable: true, + configurable: true + } + if (typeof userDef === 'function') { + def.get = _.bind(userDef, this) + def.set = noop + } else { + def.get = userDef.get + ? _.bind(userDef.get, this) + : noop + def.set = userDef.set + ? _.bind(userDef.set, this) + : noop + } + Object.defineProperty(this, key, def) + } + } + } + + /** + * Setup instance methods. Methods must be bound to the + * instance since they might be called by children + * inheriting them. + */ + + exports._initMethods = function () { + var methods = this.$options.methods + if (methods) { + for (var key in methods) { + this[key] = _.bind(methods[key], this) + } + } + } + + /** + * Initialize meta information like $index, $key & $value. + */ + + exports._initMeta = function () { + var metas = this.$options._meta + if (metas) { + for (var key in metas) { + this._defineMeta(key, metas[key]) + } + } + } + + /** + * Define a meta property, e.g $index, $key, $value + * which only exists on the vm instance but not in $data. + * + * @param {String} key + * @param {*} value + */ + + exports._defineMeta = function (key, value) { + var binding = new Binding() + Object.defineProperty(this, key, { + enumerable: true, + configurable: true, + get: function metaGetter () { + if (Observer.target) { + Observer.target.addDep(binding) + } + return value + }, + set: function metaSetter (val) { + if (val !== value) { + value = val + binding.notify() + } + } + }) + } + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var Directive = __webpack_require__(40) + var compile = __webpack_require__(46) + var transclude = __webpack_require__(47) + + /** + * Transclude, compile and link element. + * + * If a pre-compiled linker is available, that means the + * passed in element will be pre-transcluded and compiled + * as well - all we need to do is to call the linker. + * + * Otherwise we need to call transclude/compile/link here. + * + * @param {Element} el + * @return {Element} + */ + + exports._compile = function (el) { + var options = this.$options + if (options._linker) { + this._initElement(el) + options._linker(this, el) + } else { + var raw = el + el = transclude(el, options) + this._initElement(el) + var linker = compile(el, options) + linker(this, el) + if (options.replace) { + _.replace(raw, el) + } + } + return el + } + + /** + * Initialize instance element. Called in the public + * $mount() method. + * + * @param {Element} el + */ + + exports._initElement = function (el) { + if (el instanceof DocumentFragment) { + this._isBlock = true + this.$el = this._blockStart = el.firstChild + this._blockEnd = el.lastChild + this._blockFragment = el + } else { + this.$el = el + } + this.$el.__vue__ = this + this._callHook('beforeCompile') + } + + /** + * Create and bind a directive to an element. + * + * @param {String} name - directive name + * @param {Node} node - target node + * @param {Object} desc - parsed directive descriptor + * @param {Object} def - directive definition object + * @param {Function} [linker] - pre-compiled linker fn + */ + + exports._bindDir = function (name, node, desc, def, linker) { + this._directives.push( + new Directive(name, node, this, desc, def, linker) + ) + } + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Check is a string starts with $ or _ + * + * @param {String} str + * @return {Boolean} + */ + + exports.isReserved = function (str) { + var c = str.charCodeAt(0) + return c === 0x24 || c === 0x5F + } + + /** + * Guard text output, make sure undefined outputs + * empty string + * + * @param {*} value + * @return {String} + */ + + exports.toString = function (value) { + return value == null + ? '' + : value.toString() + } + + /** + * Check and convert possible numeric numbers before + * setting back to data + * + * @param {*} value + * @return {*|Number} + */ + + exports.toNumber = function (value) { + return ( + isNaN(value) || + value === null || + typeof value === 'boolean' + ) ? value + : Number(value) + } + + /** + * Strip quotes from a string + * + * @param {String} str + * @return {String | false} + */ + + exports.stripQuotes = function (str) { + var a = str.charCodeAt(0) + var b = str.charCodeAt(str.length - 1) + return a === b && (a === 0x22 || a === 0x27) + ? str.slice(1, -1) + : false + } + + /** + * Camelize a hyphen-delmited string. + * + * @param {String} str + * @return {String} + */ + + var camelRE = /[-_](\w)/g + var capitalCamelRE = /(?:^|[-_])(\w)/g + + exports.camelize = function (str, cap) { + var RE = cap ? capitalCamelRE : camelRE + return str.replace(RE, function (_, c) { + return c ? c.toUpperCase () : ''; + }) + } + + /** + * Simple bind, faster than native + * + * @param {Function} fn + * @param {Object} ctx + * @return {Function} + */ + + exports.bind = function (fn, ctx) { + return function () { + return fn.apply(ctx, arguments) + } + } + + /** + * 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) { + for (var key in from) { + to[key] = from[key] + } + } + + /** + * 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 && typeof obj === 'object' + } + + /** + * Strict object type check. Only returns true + * for plain JavaScript objects. + * + * @param {*} obj + * @return {Boolean} + */ + + var toString = Object.prototype.toString + exports.isPlainObject = function (obj) { + return toString.call(obj) === '[object Object]' + } + + /** + * Array type check. + * + * @param {*} obj + * @return {Boolean} + */ + + exports.isArray = function (obj) { + return Array.isArray(obj) + } + + /** + * 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 + }) + } + +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Can we use __proto__? + * + * @type {Boolean} + */ + + exports.hasProto = '__proto__' in {} + + /** + * Indicates we have a window + * + * @type {Boolean} + */ + + var toString = Object.prototype.toString + var inBrowser = exports.inBrowser = + typeof window !== 'undefined' && + toString.call(window) !== '[object Object]' + + /** + * Defer a task to the start of the next event loop + * + * @param {Function} cb + * @param {Object} ctx + */ + + var defer = inBrowser + ? (window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + setTimeout) + : setTimeout + + exports.nextTick = function (cb, ctx) { + if (ctx) { + defer(function () { cb.call(ctx) }, 0) + } else { + defer(cb, 0) + } + } + + /** + * Detect if we are in IE9... + * + * @type {Boolean} + */ + + exports.isIE9 = + inBrowser && + navigator.userAgent.indexOf('MSIE 9.0') > 0 + + /** + * Sniff transition/animation events + */ + + 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' + } + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + var config = __webpack_require__(20) + + /** + * Check if a node is in the document. + * + * @param {Node} node + * @return {Boolean} + */ + + var doc = + typeof document !== 'undefined' && + document.documentElement + + exports.inDoc = function (node) { + return doc && doc.contains(node) + } + + /** + * Extract an attribute from a node. + * + * @param {Node} node + * @param {String} attr + */ + + exports.attr = function (node, attr) { + attr = config.prefix + attr + var val = node.getAttribute(attr) + if (val !== null) { + node.removeAttribute(attr) + } + 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) + } + } + + /** + * Copy attributes from one element to another. + * + * @param {Element} from + * @param {Element} to + */ + + exports.copyAttributes = function (from, to) { + if (from.hasAttributes()) { + var attrs = from.attributes + for (var i = 0, l = attrs.length; i < l; i++) { + var attr = attrs[i] + to.setAttribute(attr.name, attr.value) + } + } + } + + /** + * 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()) + } + } + +/***/ }, +/* 17 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(18) + + /** + * Resolve read & write filters for a vm instance. The + * filters descriptor Array comes from the directive parser. + * + * This is extracted into its own utility so it can + * be used in multiple scenarios. + * + * @param {Vue} vm + * @param {Array} filters + * @param {Object} [target] + * @return {Object} + */ + + exports.resolveFilters = function (vm, filters, target) { + if (!filters) { + return + } + var res = target || {} + // var registry = vm.$options.filters + filters.forEach(function (f) { + var def = vm.$options.filters[f.name] + _.assertAsset(def, 'filter', f.name) + if (!def) return + var args = f.args + var reader, writer + if (typeof def === 'function') { + reader = def + } else { + reader = def.read + writer = def.write + } + if (reader) { + if (!res.read) res.read = [] + res.read.push(function (value) { + return args + ? reader.apply(vm, [value].concat(args)) + : reader.call(vm, value) + }) + } + if (writer) { + if (!res.write) res.write = [] + res.write.push(function (value, oldVal) { + return args + ? writer.apply(vm, [value, oldVal].concat(args)) + : writer.call(vm, value, oldVal) + }) + } + }) + return res + } + + /** + * Apply filters to a value + * + * @param {*} value + * @param {Array} filters + * @param {Vue} vm + * @param {*} oldVal + * @return {*} + */ + + exports.applyFilters = function (value, filters, vm, oldVal) { + if (!filters) { + return value + } + for (var i = 0, l = filters.length; i < l; i++) { + value = filters[i].call(vm, value, oldVal) + } + return value + } + +/***/ }, +/* 18 */ +/***/ function(module, exports, __webpack_require__) { + + var config = __webpack_require__(20) + + /** + * Enable debug utilities. The enableDebug() function and + * all _.log() & _.warn() calls will be dropped in the + * minified production build. + */ + + enableDebug() + + function enableDebug () { + 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) { + if (hasConsole && !config.silent) { + console.warn('[Vue warn]: ' + msg) + if (config.debug && console.trace) { + console.trace() + } + } + } + + /** + * Assert asset exists + */ + + exports.assertAsset = function (val, type, id) { + if (!val) { + exports.warn('Failed to resolve ' + type + ': ' + id) + } + } + } + +/***/ }, +/* 19 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + 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 = Object.create(null) + + /** + * Data + */ + + strats.data = function (parentVal, childVal, vm) { + // in a class merge, both should be functions + // so we just return child if it exists + if (!vm) { + if (childVal && typeof childVal !== 'function') { + _.warn( + 'The "data" option should be a function ' + + 'that returns a per-instance value in component ' + + 'definitions.' + ) + return + } + return childVal || parentVal + } + var instanceData = typeof childVal === 'function' + ? childVal.call(vm) + : childVal + var defaultData = typeof parentVal === 'function' + ? parentVal.call(vm) + : undefined + if (instanceData) { + // mix default data into instance data + for (var key in defaultData) { + if (!instanceData.hasOwnProperty(key)) { + instanceData.$add(key, defaultData[key]) + } + } + return instanceData + } else { + return defaultData + } + } + + /** + * El + */ + + strats.el = function (parentVal, childVal, vm) { + if (!vm && childVal && typeof childVal !== 'function') { + _.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.created = + strats.ready = + strats.attached = + strats.detached = + strats.beforeCompile = + strats.compiled = + strats.beforeDestroy = + strats.destroyed = + strats.paramAttributes = function (parentVal, childVal) { + return childVal + ? parentVal + ? parentVal.concat(childVal) + : _.isArray(childVal) + ? childVal + : [childVal] + : parentVal + } + + /** + * Assets + * + * When a vm is present (instance creation), we need to do + * a three-way merge between constructor options, instance + * options and parent options. + */ + + strats.directives = + strats.filters = + strats.partials = + strats.transitions = + strats.components = function (parentVal, childVal, vm, key) { + var ret = Object.create( + vm && vm.$parent + ? vm.$parent.$options[key] + : _.Vue.options[key] + ) + if (parentVal) { + var keys = Object.keys(parentVal) + var i = keys.length + var field + while (i--) { + field = keys[i] + ret[field] = parentVal[field] + } + } + if (childVal) extend(ret, childVal) + return ret + } + + /** + * 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] + ret[key] = parent + ? parent.concat(child) + : [child] + } + return ret + } + + /** + * Other object hashes. + */ + + strats.methods = + strats.computed = function (parentVal, childVal) { + if (!childVal) return parentVal + if (!parentVal) return childVal + var ret = Object.create(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} components + */ + + function guardComponents (components) { + if (components) { + var def + for (var key in components) { + def = components[key] + if (_.isPlainObject(def)) { + def.name = key + components[key] = _.Vue.extend(def) + } + } + } + } + + /** + * 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. + */ + + module.exports = function mergeOptions (parent, child, vm) { + guardComponents(child.components) + var options = {} + var key + for (key in parent) { + merge(parent[key], child[key], key) + } + for (key in child) { + if (!(parent.hasOwnProperty(key))) { + merge(parent[key], child[key], key) + } + } + var mixins = child.mixins + if (mixins) { + for (var i = 0, l = mixins.length; i < l; i++) { + for (key in mixins[i]) { + merge(options[key], mixins[i][key], key) + } + } + } + function merge (parentVal, childVal, key) { + var strat = strats[key] || defaultStrat + options[key] = strat(parentVal, childVal, vm, key) + } + return options + } + +/***/ }, +/* 20 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = { + + /** + * The prefix to look for when parsing directives. + * + * @type {String} + */ + + prefix: 'v-', + + /** + * Whether to print debug messages. + * Also enables stack trace for warnings. + * + * @type {Boolean} + */ + + debug: false, + + /** + * Whether to suppress warnings. + * + * @type {Boolean} + */ + + silent: false, + + /** + * Whether allow observer to alter data objects' + * __proto__. + * + * @type {Boolean} + */ + + proto: true, + + /** + * Whether to parse mustache tags in templates. + * + * @type {Boolean} + */ + + interpolate: true, + + /** + * Whether to use async rendering. + */ + + async: true, + + /** + * Internal flag to indicate the delimiters have been + * changed. + * + * @type {Boolean} + */ + + _delimitersChanged: true + + } + + /** + * Interpolation delimiters. + * We need to mark the changed flag so that the text parser + * knows it needs to recompile the regex. + * + * @type {Array} + */ + + var delimiters = ['{{', '}}'] + Object.defineProperty(module.exports, 'delimiters', { + get: function () { + return delimiters + }, + set: function (val) { + delimiters = val + this._delimitersChanged = true + } + }) + +/***/ }, +/* 21 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var config = __webpack_require__(20) + var Observer = __webpack_require__(49) + var expParser = __webpack_require__(44) + var Batcher = __webpack_require__(50) + + var batcher = new Batcher() + var uid = 0 + + /** + * A watcher parses an expression, collects dependencies, + * and fires callback when the expression value changes. + * This is used for both the $watch() api and directives. + * + * @param {Vue} vm + * @param {String} expression + * @param {Function} cb + * @param {Array} [filters] + * @param {Boolean} [needSet] + * @param {Boolean} [deep] + * @constructor + */ + + function Watcher (vm, expression, cb, filters, needSet, deep) { + this.vm = vm + vm._watcherList.push(this) + this.expression = expression + this.cbs = [cb] + this.id = ++uid // uid for batching + this.active = true + this.deep = deep + this.deps = Object.create(null) + // setup filters if any. + // We delegate directive filters here to the watcher + // because they need to be included in the dependency + // collection process. + this.readFilters = filters && filters.read + this.writeFilters = filters && filters.write + // parse expression for getter/setter + var res = expParser.parse(expression, needSet) + this.getter = res.get + this.setter = res.set + this.value = this.get() + } + + var p = Watcher.prototype + + /** + * Add a binding dependency to this directive. + * + * @param {Binding} binding + */ + + p.addDep = function (binding) { + var id = binding.id + if (!this.newDeps[id]) { + this.newDeps[id] = binding + if (!this.deps[id]) { + this.deps[id] = binding + binding.addSub(this) + } + } + } + + /** + * Evaluate the getter, and re-collect dependencies. + */ + + p.get = function () { + this.beforeGet() + var vm = this.vm + var value + try { + value = this.getter.call(vm, vm) + } catch (e) {} + // use JSON.stringify to "touch" every property + // so they are all tracked as dependencies for + // deep watching + if (this.deep) JSON.stringify(value) + value = _.applyFilters(value, this.readFilters, vm) + this.afterGet() + return value + } + + /** + * Set the corresponding value with the setter. + * + * @param {*} value + */ + + p.set = function (value) { + var vm = this.vm + value = _.applyFilters( + value, this.writeFilters, vm, this.value + ) + try { + this.setter.call(vm, vm, value) + } catch (e) {} + } + + /** + * Prepare for dependency collection. + */ + + p.beforeGet = function () { + Observer.target = this + this.newDeps = {} + } + + /** + * Clean up for dependency collection. + */ + + p.afterGet = function () { + Observer.target = null + for (var id in this.deps) { + if (!this.newDeps[id]) { + this.deps[id].removeSub(this) + } + } + this.deps = this.newDeps + } + + /** + * Subscriber interface. + * Will be called when a dependency changes. + */ + + p.update = function () { + if (config.async) { + batcher.push(this) + } else { + this.run() + } + } + + /** + * Batcher job interface. + * Will be called by the batcher. + */ + + p.run = function () { + if (this.active) { + var value = this.get() + if ( + (typeof value === 'object' && value !== null) || + value !== this.value + ) { + var oldValue = this.value + this.value = value + var cbs = this.cbs + for (var i = 0, l = cbs.length; i < l; i++) { + cbs[i](value, oldValue) + // if a callback also removed other callbacks, + // we need to adjust the loop accordingly. + var removed = l - cbs.length + if (removed) { + i -= removed + l -= removed + } + } + } + } + } + + /** + * Add a callback. + * + * @param {Function} cb + */ + + p.addCb = function (cb) { + this.cbs.push(cb) + } + + /** + * Remove a callback. + * + * @param {Function} cb + */ + + p.removeCb = function (cb) { + var cbs = this.cbs + if (cbs.length > 1) { + var i = cbs.indexOf(cb) + if (i > -1) { + cbs.splice(i, 1) + } + } else if (cb === cbs[0]) { + this.teardown() + } + } + + /** + * Remove self from all dependencies' subcriber list. + */ + + p.teardown = function () { + if (this.active) { + // remove self from vm's watcher list + // we can skip this if the vm if being destroyed + // which can improve teardown performance. + if (!this.vm._isBeingDestroyed) { + var list = this.vm._watcherList + list.splice(list.indexOf(this)) + } + for (var id in this.deps) { + this.deps[id].removeSub(this) + } + this.active = false + this.vm = this.cbs = this.value = null + } + } + + module.exports = Watcher + +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + module.exports = { + + bind: function () { + this.attr = this.el.nodeType === 3 + ? 'nodeValue' + : 'textContent' + }, + + update: function (value) { + this.el[this.attr] = _.toString(value) + } + + } + +/***/ }, +/* 23 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var templateParser = __webpack_require__(51) + + 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 = [] + } + }, + + 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 + var frag = templateParser.parse(value, true) + // save a reference to these nodes so we can remove later + this.nodes = _.toArray(frag.childNodes) + _.before(frag, this.el) + } + + } + +/***/ }, +/* 24 */ +/***/ function(module, exports, __webpack_require__) { + + // xlink + var xlinkNS = 'http://www.w3.org/1999/xlink' + var xlinkRE = /^xlink:/ + + module.exports = { + + priority: 850, + + bind: function () { + var name = this.arg + this.update = xlinkRE.test(name) + ? xlinkHandler + : defaultHandler + } + + } + + function defaultHandler (value) { + if (value || value === 0) { + this.el.setAttribute(this.arg, value) + } else { + this.el.removeAttribute(this.arg) + } + } + + function xlinkHandler (value) { + if (value != null) { + this.el.setAttributeNS(xlinkNS, this.arg, value) + } else { + this.el.removeAttributeNS(xlinkNS, 'href') + } + } + +/***/ }, +/* 25 */ +/***/ function(module, exports, __webpack_require__) { + + var transition = __webpack_require__(45) + + module.exports = function (value) { + var el = this.el + transition.apply(el, value ? 1 : -1, function () { + el.style.display = value ? '' : 'none' + }, this.vm) + } + +/***/ }, +/* 26 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var addClass = _.addClass + var removeClass = _.removeClass + + module.exports = function (value) { + if (this.arg) { + var method = value ? addClass : removeClass + method(this.el, this.arg) + } else { + if (this.lastVal) { + removeClass(this.el, this.lastVal) + } + if (value) { + addClass(this.el, value) + this.lastVal = value + } + } + } + +/***/ }, +/* 27 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = { + + isLiteral: true, + + bind: function () { + this.vm.$$[this.expression] = this.el + }, + + unbind: function () { + delete this.vm.$$[this.expression] + } + + } + +/***/ }, +/* 28 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + module.exports = { + + isLiteral: true, + + bind: function () { + if (this.el !== this.vm.$el) { + _.warn( + 'v-ref should only be used on instance root nodes.' + ) + return + } + this.owner = this.vm.$parent + this.owner.$[this.expression] = this.vm + }, + + unbind: function () { + if (this.owner.$[this.expression] === this.vm) { + delete this.owner.$[this.expression] + } + } + + } + +/***/ }, +/* 29 */ +/***/ function(module, exports, __webpack_require__) { + + var config = __webpack_require__(20) + + module.exports = { + + bind: function () { + var el = this.el + this.vm.$once('hook:compiled', function () { + el.removeAttribute(config.prefix + 'cloak') + }) + } + + } + +/***/ }, +/* 30 */ +/***/ function(module, exports, __webpack_require__) { + + var prefixes = ['-webkit-', '-moz-', '-ms-'] + var importantRE = /!important;?$/ + + module.exports = { + + bind: function () { + var prop = this.arg + if (!prop) return + if (prop.charAt(0) === '$') { + // properties that start with $ will be auto-prefixed + prop = prop.slice(1) + this.prefixed = true + } + this.prop = prop + }, + + update: function (value) { + var prop = this.prop + // cast possible numbers/booleans into strings + if (value != null) { + value += '' + } + if (prop) { + var isImportant = importantRE.test(value) + ? 'important' + : '' + if (isImportant) { + value = value.replace(importantRE, '').trim() + } + this.el.style.setProperty(prop, value, isImportant) + if (this.prefixed) { + var i = prefixes.length + while (i--) { + this.el.style.setProperty( + prefixes[i] + prop, + value, + isImportant + ) + } + } + } else { + this.el.style.cssText = value + } + } + + } + +/***/ }, +/* 31 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var templateParser = __webpack_require__(51) + var transition = __webpack_require__(45) + + module.exports = { + + isLiteral: true, + + bind: function () { + var el = this.el + this.start = document.createComment('v-partial-start') + this.end = document.createComment('v-partial-end') + if (el.nodeType !== 8) { + el.innerHTML = '' + } + if (el.tagName === 'TEMPLATE' || el.nodeType === 8) { + _.replace(el, this.end) + } else { + el.appendChild(this.end) + } + _.before(this.start, this.end) + if (!this._isDynamicLiteral) { + this.compile(this.expression) + } + }, + + update: function (id) { + this.teardown() + this.compile(id) + }, + + compile: function (id) { + var partial = this.vm.$options.partials[id] + _.assertAsset(partial, 'partial', id) + if (!partial) { + return + } + var vm = this.vm + var frag = templateParser.parse(partial, true) + var decompile = vm.$compile(frag) + this.decompile = function () { + decompile() + transition.blockRemove(this.start, this.end, vm) + } + transition.blockAppend(frag, this.end, vm) + }, + + teardown: function () { + if (this.decompile) { + this.decompile() + this.decompile = null + } + } + + } + +/***/ }, +/* 32 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = { + + priority: 1000, + isLiteral: true, + + bind: function () { + this.el.__v_trans = { + id: this.expression + } + } + + } + +/***/ }, +/* 33 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + module.exports = { + + acceptStatement: true, + priority: 700, + + bind: function () { + // deal with iframes + if ( + this.el.tagName === 'IFRAME' && + this.arg !== 'load' + ) { + var self = this + this.iframeBind = function () { + _.on(self.el.contentWindow, self.arg, self.handler) + } + _.on(this.el, 'load', this.iframeBind) + } + }, + + update: function (handler) { + if (typeof handler !== 'function') { + _.warn( + 'Directive "v-on:' + this.expression + '" ' + + 'expects a function value.' + ) + return + } + this.reset() + var vm = this.vm + this.handler = function (e) { + e.targetVM = vm + vm.$event = e + var res = handler(e) + vm.$event = null + return res + } + if (this.iframeBind) { + this.iframeBind() + } else { + _.on(this.el, this.arg, this.handler) + } + }, + + reset: function () { + var el = this.iframeBind + ? this.el.contentWindow + : this.el + if (this.handler) { + _.off(el, this.arg, this.handler) + } + }, + + unbind: function () { + this.reset() + _.off(this.el, 'load', this.iframeBind) + } + } + +/***/ }, +/* 34 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var templateParser = __webpack_require__(51) + + module.exports = { + + isLiteral: true, + + /** + * Setup. Two possible usages: + * + * - static: + * v-component="comp" + * + * - dynamic: + * v-component="{{currentView}}" + */ + + bind: function () { + if (!this.el.__vue__) { + // create a ref anchor + this.ref = document.createComment('v-component') + _.replace(this.el, this.ref) + // check keep-alive options + this.checkKeepAlive() + // check parent directives + this.parentLinker = this.el._parentLinker + // if static, build right now. + if (!this._isDynamicLiteral) { + this.resolveCtor(this.expression) + this.build() + } + } else { + _.warn( + 'v-component="' + this.expression + '" cannot be ' + + 'used on an already mounted instance.' + ) + } + }, + + /** + * Check if the "keep-alive" flag is present. + * If yes, instead of destroying the active vm when + * hiding (v-if) or switching (dynamic literal) it, + * we simply remove it from the DOM and save it in a + * cache object, with its constructor id as the key. + */ + + checkKeepAlive: function () { + // check keep-alive flag + this.keepAlive = this.el.hasAttribute('keep-alive') + if (this.keepAlive) { + this.el.removeAttribute('keep-alive') + this.cache = {} + } + }, + + /** + * Resolve the component constructor to use when creating + * the child vm. + */ + + resolveCtor: function (id) { + this.ctorId = id + this.Ctor = this.vm.$options.components[id] + _.assertAsset(this.Ctor, 'component', id) + }, + + /** + * Instantiate/insert a new child vm. + * If keep alive and has cached instance, insert that + * instance; otherwise build a new one and cache it. + */ + + build: function () { + if (this.keepAlive) { + var cached = this.cache[this.ctorId] + if (cached) { + this.childVM = cached + cached.$before(this.ref) + return + } + } + var vm = this.vm + if (this.Ctor && !this.childVM) { + this.childVM = vm.$addChild({ + el: templateParser.clone(this.el) + }, this.Ctor) + if (this.parentLinker) { + var dirCount = vm._directives.length + var targetVM = this.childVM.$options.inherit + ? this.childVM + : vm + this.parentLinker(targetVM, this.childVM.$el) + this.parentDirs = vm._directives.slice(dirCount) + } + if (this.keepAlive) { + this.cache[this.ctorId] = this.childVM + } + this.childVM.$before(this.ref) + } + }, + + /** + * Teardown the active vm. + * If keep alive, simply remove it; otherwise destroy it. + * + * @param {Boolean} remove + */ + + unbuild: function (remove) { + var child = this.childVM + if (!child) { + return + } + if (this.keepAlive) { + if (remove) { + child.$remove() + } + } else { + child.$destroy(remove) + var parentDirs = this.parentDirs + if (parentDirs) { + var i = parentDirs.length + while (i--) { + parentDirs[i]._teardown() + } + } + } + this.childVM = null + }, + + /** + * Update callback for the dynamic literal scenario, + * e.g. v-component="{{view}}" + */ + + update: function (value) { + this.unbuild(true) + if (value) { + this.resolveCtor(value) + this.build() + } + }, + + /** + * Unbind. + * Make sure keepAlive is set to false so that the + * instance is always destroyed. + */ + + unbind: function () { + this.keepAlive = false + this.unbuild() + } + + } + +/***/ }, +/* 35 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var isObject = _.isObject + var textParser = __webpack_require__(42) + var expParser = __webpack_require__(44) + var templateParser = __webpack_require__(51) + var compile = __webpack_require__(46) + var transclude = __webpack_require__(47) + var mergeOptions = __webpack_require__(19) + var uid = 0 + + module.exports = { + + /** + * Setup. + */ + + bind: function () { + // uid as a cache identifier + this.id = '__v_repeat_' + (++uid) + // we need to insert the objToArray converter + // as the first read filter. + if (!this.filters) { + this.filters = {} + } + // add the object -> array convert filter + var objectConverter = _.bind(objToArray, this) + if (!this.filters.read) { + this.filters.read = [objectConverter] + } else { + this.filters.read.unshift(objectConverter) + } + // setup ref node + this.ref = document.createComment('v-repeat') + _.replace(this.el, this.ref) + // check if this is a block repeat + this.template = this.el.tagName === 'TEMPLATE' + ? templateParser.parse(this.el, true) + : this.el + // check other directives that need to be handled + // at v-repeat level + this.checkIf() + this.checkRef() + this.checkTrackById() + this.checkComponent() + // cache for primitive value instances + this.cache = Object.create(null) + }, + + /** + * Warn against v-if usage. + */ + + checkIf: function () { + if (_.attr(this.el, 'if') !== null) { + _.warn( + 'Don\'t use v-if with v-repeat. ' + + 'Use v-show or the "filterBy" filter instead.' + ) + } + }, + + /** + * Check if v-ref/ v-el is also present. + */ + + checkRef: function () { + var childId = _.attr(this.el, 'ref') + this.childId = childId + ? this.vm.$interpolate(childId) + : null + var elId = _.attr(this.el, 'el') + this.elId = elId + ? this.vm.$interpolate(elId) + : null + }, + + /** + * Check for a track-by ID, which allows us to identify + * a piece of data and its associated instance by its + * unique id. + */ + + checkTrackById: function () { + this.idKey = this.el.getAttribute('trackby') + if (this.idKey !== null) { + this.el.removeAttribute('trackby') + } + }, + + /** + * Check the component constructor to use for repeated + * instances. If static we resolve it now, otherwise it + * needs to be resolved at build time with actual data. + */ + + checkComponent: function () { + var id = _.attr(this.el, 'component') + var options = this.vm.$options + if (!id) { + this.Ctor = _.Vue // default constructor + this.inherit = true // inline repeats should inherit + // important: transclude with no options, just + // to ensure block start and block end + this.template = transclude(this.template) + this._linker = compile(this.template, options) + } else { + var tokens = textParser.parse(id) + if (!tokens) { // static component + var Ctor = this.Ctor = options.components[id] + _.assertAsset(Ctor, 'component', id) + if (Ctor) { + // merge an empty object with owner vm as parent + // so child vms can access parent assets. + var merged = mergeOptions( + Ctor.options, + {}, + { $parent: this.vm } + ) + this.template = transclude(this.template, merged) + this._linker = compile(this.template, merged) + } + } else { + // to be resolved later + var ctorExp = textParser.tokensToExp(tokens) + this.ctorGetter = expParser.parse(ctorExp).get + } + } + }, + + /** + * Update. + * This is called whenever the Array mutates. + * + * @param {Array} data + */ + + update: function (data) { + if (typeof data === 'number') { + data = range(data) + } + this.vms = this.diff(data || [], this.vms) + // update v-ref + if (this.childId) { + this.vm.$[this.childId] = this.vms + } + if (this.elId) { + this.vm.$$[this.elId] = this.vms.map(function (vm) { + return vm.$el + }) + } + }, + + /** + * Diff, based on new data and old data, determine the + * minimum amount of DOM manipulations needed to make the + * DOM reflect the new data Array. + * + * The algorithm diffs the new data Array by storing a + * hidden reference to an owner vm instance on previously + * seen data. This allows us to achieve O(n) which is + * better than a levenshtein distance based algorithm, + * which is O(m * n). + * + * @param {Array} data + * @param {Array} oldVms + * @return {Array} + */ + + diff: function (data, oldVms) { + var idKey = this.idKey + var converted = this.converted + var ref = this.ref + var alias = this.arg + var init = !oldVms + var vms = new Array(data.length) + var obj, raw, vm, i, l + // First pass, go through the new Array and fill up + // the new vms array. If a piece of data has a cached + // instance for it, we reuse it. Otherwise build a new + // instance. + for (i = 0, l = data.length; i < l; i++) { + obj = data[i] + raw = converted ? obj.value : obj + vm = !init && this.getVm(raw) + if (vm) { // reusable instance + vm._reused = true + vm.$index = i // update $index + if (converted) { + vm.$key = obj.key // update $key + } + if (idKey) { // swap track by id data + if (alias) { + vm[alias] = raw + } else { + vm._setData(raw) + } + } + } else { // new instance + vm = this.build(obj, i) + vm._new = true + } + vms[i] = vm + // insert if this is first run + if (init) { + vm.$before(ref) + } + } + // if this is the first run, we're done. + if (init) { + return vms + } + // Second pass, go through the old vm instances and + // destroy those who are not reused (and remove them + // from cache) + for (i = 0, l = oldVms.length; i < l; i++) { + vm = oldVms[i] + if (!vm._reused) { + this.uncacheVm(vm) + vm.$destroy(true) + } + } + // final pass, move/insert new instances into the + // right place. We're going in reverse here because + // insertBefore relies on the next sibling to be + // resolved. + var targetNext, currentNext + i = vms.length + while (i--) { + vm = vms[i] + // this is the vm that we should be in front of + targetNext = vms[i + 1] + if (!targetNext) { + // This is the last item. If it's reused then + // everything else will eventually be in the right + // place, so no need to touch it. Otherwise, insert + // it. + if (!vm._reused) { + vm.$before(ref) + } + } else { + if (vm._reused) { + // this is the vm we are actually in front of + currentNext = findNextVm(vm, ref) + // we only need to move if we are not in the right + // place already. + if (currentNext !== targetNext) { + vm.$before(targetNext.$el, null, false) + } + } else { + // new instance, insert to existing next + vm.$before(targetNext.$el) + } + } + vm._new = false + vm._reused = false + } + return vms + }, + + /** + * Build a new instance and cache it. + * + * @param {Object} data + * @param {Number} index + */ + + build: function (data, index) { + var original = data + var meta = { $index: index } + if (this.converted) { + meta.$key = original.key + } + var raw = this.converted ? data.value : data + var alias = this.arg + var hasAlias = !isObject(raw) || alias + // wrap the raw data with alias + data = hasAlias ? {} : raw + if (alias) { + data[alias] = raw + } else if (hasAlias) { + meta.$value = raw + } + // resolve constructor + var Ctor = this.Ctor || this.resolveCtor(data, meta) + var vm = this.vm.$addChild({ + el: templateParser.clone(this.template), + _linker: this._linker, + _meta: meta, + data: data, + inherit: this.inherit + }, Ctor) + // cache instance + this.cacheVm(raw, vm) + return vm + }, + + /** + * Resolve a contructor to use for an instance. + * The tricky part here is that there could be dynamic + * components depending on instance data. + * + * @param {Object} data + * @param {Object} meta + * @return {Function} + */ + + resolveCtor: function (data, meta) { + // create a temporary context object and copy data + // and meta properties onto it. + // use _.define to avoid accidentally overwriting scope + // properties. + var context = Object.create(this.vm) + var key + for (key in data) { + _.define(context, key, data[key]) + } + for (key in meta) { + _.define(context, key, meta[key]) + } + var id = this.ctorGetter.call(context, context) + var Ctor = this.vm.$options.components[id] + _.assertAsset(Ctor, 'component', id) + return Ctor + }, + + /** + * Unbind, teardown everything + */ + + unbind: function () { + if (this.childId) { + delete this.vm.$[this.childId] + } + if (this.vms) { + var i = this.vms.length + var vm + while (i--) { + vm = this.vms[i] + this.uncacheVm(vm) + vm.$destroy() + } + } + }, + + /** + * Cache a vm instance based on its data. + * + * If the data is an object, we save the vm's reference on + * the data object as a hidden property. Otherwise we + * cache them in an object and for each primitive value + * there is an array in case there are duplicates. + * + * @param {Object} data + * @param {Vue} vm + */ + + cacheVm: function (data, vm) { + var idKey = this.idKey + var cache = this.cache + var id + if (idKey) { + id = data[idKey] + if (!cache[id]) { + cache[id] = vm + } else { + _.warn('Duplicate ID in v-repeat: ' + id) + } + } else if (isObject(data)) { + id = this.id + if (data.hasOwnProperty(id)) { + if (data[id] === null) { + data[id] = vm + } else { + _.warn( + 'Duplicate objects are not supported in v-repeat.' + ) + } + } else { + _.define(data, this.id, vm) + } + } else { + if (!cache[data]) { + cache[data] = [vm] + } else { + cache[data].push(vm) + } + } + vm._raw = data + }, + + /** + * Try to get a cached instance from a piece of data. + * + * @param {Object} data + * @return {Vue|undefined} + */ + + getVm: function (data) { + if (this.idKey) { + return this.cache[data[this.idKey]] + } else if (isObject(data)) { + return data[this.id] + } else { + var cached = this.cache[data] + if (cached) { + var i = 0 + var vm = cached[i] + // since duplicated vm instances might be a reused + // one OR a newly created one, we need to return the + // first instance that is neither of these. + while (vm && (vm._reused || vm._new)) { + vm = cached[++i] + } + return vm + } + } + }, + + /** + * Delete a cached vm instance. + * + * @param {Vue} vm + */ + + uncacheVm: function (vm) { + var data = vm._raw + if (this.idKey) { + this.cache[data[this.idKey]] = null + } else if (isObject(data)) { + data[this.id] = null + vm._raw = null + } else { + this.cache[data].pop() + } + } + + } + + /** + * Helper to find the next element that is an instance + * root node. This is necessary because a destroyed vm's + * element could still be lingering in the DOM before its + * leaving transition finishes, but its __vue__ reference + * should have been removed so we can skip them. + * + * @param {Vue} vm + * @param {CommentNode} ref + * @return {Vue} + */ + + function findNextVm (vm, ref) { + var el = (vm._blockEnd || vm.$el).nextSibling + while (!el.__vue__ && el !== ref) { + el = el.nextSibling + } + return el.__vue__ + } + + /** + * Attempt to convert non-Array objects to array. + * This is the default filter installed to every v-repeat + * directive. + * + * It will be called with **the directive** as `this` + * context so that we can mark the repeat array as converted + * from an object. + * + * @param {*} obj + * @return {Array} + * @private + */ + + function objToArray (obj) { + if (!_.isPlainObject(obj)) { + return obj + } + var keys = Object.keys(obj) + var i = keys.length + var res = new Array(i) + var key + while (i--) { + key = keys[i] + res[i] = { + key: key, + value: obj[key] + } + } + // `this` points to the repeat directive instance + this.converted = true + return res + } + + /** + * Create a range array from given number. + * + * @param {Number} n + * @return {Array} + */ + + function range (n) { + var i = -1 + var ret = new Array(n) + while (++i < n) { + ret[i] = i + } + return ret + } + +/***/ }, +/* 36 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var compile = __webpack_require__(46) + var templateParser = __webpack_require__(51) + var transition = __webpack_require__(45) + + module.exports = { + + bind: function () { + var el = this.el + if (!el.__vue__) { + this.start = document.createComment('v-if-start') + this.end = document.createComment('v-if-end') + _.replace(el, this.end) + _.before(this.start, this.end) + if (el.tagName === 'TEMPLATE') { + this.template = templateParser.parse(el, true) + } else { + this.template = document.createDocumentFragment() + this.template.appendChild(el) + } + // compile the nested partial + this.linker = compile( + this.template, + this.vm.$options, + true + ) + } else { + this.invalid = true + _.warn( + 'v-if="' + this.expression + '" cannot be ' + + 'used on an already mounted instance.' + ) + } + }, + + update: function (value) { + if (this.invalid) return + if (value) { + this.insert() + } else { + this.teardown() + } + }, + + insert: function () { + // avoid duplicate inserts, since update() can be + // called with different truthy values + if (this.decompile) { + return + } + var vm = this.vm + var frag = templateParser.clone(this.template) + var decompile = this.linker(vm, frag) + this.decompile = function () { + decompile() + transition.blockRemove(this.start, this.end, vm) + } + transition.blockAppend(frag, this.end, vm) + }, + + teardown: function () { + if (this.decompile) { + this.decompile() + this.decompile = null + } + } + + } + +/***/ }, +/* 37 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var Watcher = __webpack_require__(21) + + module.exports = { + + priority: 900, + + bind: function () { + var vm = this.vm + if (this.el !== vm.$el) { + _.warn( + 'v-with can only be used on instance root elements.' + ) + } else if (!vm.$parent) { + _.warn( + 'v-with must be used on an instance with a parent.' + ) + } else { + var key = this.arg + this.watcher = new Watcher( + vm.$parent, + this.expression, + key + ? function (val) { + vm.$set(key, val) + } + : function (val) { + vm.$data = val + } + ) + // initial set + var initialVal = this.watcher.value + if (key) { + vm.$set(key, initialVal) + } else { + vm.$data = initialVal + } + } + }, + + unbind: function () { + if (this.watcher) { + this.watcher.teardown() + } + } + + } + +/***/ }, +/* 38 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var Path = __webpack_require__(41) + + /** + * Filter filter for v-repeat + * + * @param {String} searchKey + * @param {String} [delimiter] + * @param {String} dataKey + */ + + exports.filterBy = function (arr, searchKey, delimiter, dataKey) { + // allow optional `in` delimiter + // because why not + if (delimiter && delimiter !== 'in') { + dataKey = delimiter + } + // get the search string + var search = + _.stripQuotes(searchKey) || + this.$get(searchKey) + if (!search) { + return arr + } + search = search.toLowerCase() + // get the optional dataKey + dataKey = + dataKey && + (_.stripQuotes(dataKey) || this.$get(dataKey)) + return arr.filter(function (item) { + return dataKey + ? contains(Path.get(item, dataKey), search) + : contains(item, search) + }) + } + + /** + * Filter filter for v-repeat + * + * @param {String} sortKey + * @param {String} reverseKey + */ + + exports.orderBy = function (arr, sortKey, reverseKey) { + var key = + _.stripQuotes(sortKey) || + this.$get(sortKey) + if (!key) { + return arr + } + var order = 1 + if (reverseKey) { + if (reverseKey === '-1') { + order = -1 + } else if (reverseKey.charCodeAt(0) === 0x21) { // ! + reverseKey = reverseKey.slice(1) + order = this.$get(reverseKey) ? 1 : -1 + } else { + order = this.$get(reverseKey) ? -1 : 1 + } + } + // sort on a copy to avoid mutating original array + return arr.slice().sort(function (a, b) { + a = Path.get(a, key) + b = Path.get(b, key) + return a === b ? 0 : a > b ? order : -order + }) + } + + /** + * String contain helper + * + * @param {*} val + * @param {String} search + */ + + function contains (val, search) { + if (_.isObject(val)) { + for (var key in val) { + if (contains(val[key], search)) { + return true + } + } + } else if (val != null) { + return val.toString().toLowerCase().indexOf(search) > -1 + } + } + +/***/ }, +/* 39 */ +/***/ function(module, exports, __webpack_require__) { + + var uid = 0 + + /** + * A binding is an observable that can have multiple + * directives subscribing to it. + * + * @constructor + */ + + function Binding () { + this.id = ++uid + this.subs = [] + } + + var p = Binding.prototype + + /** + * Add a directive subscriber. + * + * @param {Directive} sub + */ + + p.addSub = function (sub) { + this.subs.push(sub) + } + + /** + * Remove a directive subscriber. + * + * @param {Directive} sub + */ + + p.removeSub = function (sub) { + if (this.subs.length) { + var i = this.subs.indexOf(sub) + if (i > -1) this.subs.splice(i, 1) + } + } + + /** + * Notify all subscribers of a new value. + */ + + p.notify = function () { + for (var i = 0, l = this.subs.length; i < l; i++) { + this.subs[i].update() + } + } + + module.exports = Binding + +/***/ }, +/* 40 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var config = __webpack_require__(20) + var Watcher = __webpack_require__(21) + var textParser = __webpack_require__(42) + var expParser = __webpack_require__(44) + + /** + * A directive links a DOM element with a piece of data, + * which is the result of evaluating an expression. + * It registers a watcher with the expression and calls + * the DOM update function when a change is triggered. + * + * @param {String} name + * @param {Node} el + * @param {Vue} vm + * @param {Object} descriptor + * - {String} expression + * - {String} [arg] + * - {Array} [filters] + * @param {Object} def - directive definition object + * @param {Function} [linker] - pre-compiled linker function + * @constructor + */ + + function Directive (name, el, vm, descriptor, def, linker) { + // public + this.name = name + this.el = el + this.vm = vm + // copy descriptor props + this.raw = descriptor.raw + this.expression = descriptor.expression + this.arg = descriptor.arg + this.filters = _.resolveFilters(vm, descriptor.filters) + // private + this._linker = linker + this._locked = false + this._bound = false + // init + this._bind(def) + } + + var p = Directive.prototype + + /** + * Initialize the directive, mixin definition properties, + * setup the watcher, call definition bind() and update() + * if present. + * + * @param {Object} def + */ + + p._bind = function (def) { + if (this.name !== 'cloak' && this.el.removeAttribute) { + this.el.removeAttribute(config.prefix + this.name) + } + if (typeof def === 'function') { + this.update = def + } else { + _.extend(this, def) + } + this._watcherExp = this.expression + this._checkDynamicLiteral() + if (this.bind) { + this.bind() + } + if ( + this.update && this._watcherExp && + (!this.isLiteral || this._isDynamicLiteral) && + !this._checkStatement() + ) { + // use raw expression as identifier because filters + // make them different watchers + var watcher = this.vm._watchers[this.raw] + // wrapped updater for context + var dir = this + var update = this._update = function (val, oldVal) { + if (!dir._locked) { + dir.update(val, oldVal) + } + } + if (!watcher) { + watcher = this.vm._watchers[this.raw] = new Watcher( + this.vm, + this._watcherExp, + update, // callback + this.filters, + this.twoWay // need setter + ) + } else { + watcher.addCb(update) + } + this._watcher = watcher + if (this._initValue != null) { + watcher.set(this._initValue) + } else { + this.update(watcher.value) + } + } + this._bound = true + } + + /** + * check if this is a dynamic literal binding. + * + * e.g. v-component="{{currentView}}" + */ + + p._checkDynamicLiteral = function () { + var expression = this.expression + if (expression && this.isLiteral) { + var tokens = textParser.parse(expression) + if (tokens) { + var exp = textParser.tokensToExp(tokens) + this.expression = this.vm.$get(exp) + this._watcherExp = exp + this._isDynamicLiteral = true + } + } + } + + /** + * Check if the directive is a function caller + * and if the expression is a callable one. If both true, + * we wrap up the expression and use it as the event + * handler. + * + * e.g. v-on="click: a++" + * + * @return {Boolean} + */ + + p._checkStatement = function () { + var expression = this.expression + if ( + expression && this.acceptStatement && + !expParser.pathTestRE.test(expression) + ) { + var fn = expParser.parse(expression).get + var vm = this.vm + var handler = function () { + fn.call(vm, vm) + } + if (this.filters) { + handler = _.applyFilters( + handler, + this.filters.read, + vm + ) + } + this.update(handler) + return true + } + } + + /** + * Teardown the watcher and call unbind. + */ + + p._teardown = function () { + if (this._bound) { + if (this.unbind) { + this.unbind() + } + var watcher = this._watcher + if (watcher && watcher.active) { + watcher.removeCb(this._update) + if (!watcher.active) { + this.vm._watchers[this.raw] = null + } + } + this._bound = false + this.vm = this.el = this._watcher = null + } + } + + /** + * Set the corresponding value with the setter. + * This should only be used in two-way directives + * e.g. v-model. + * + * @param {*} value + * @param {Boolean} lock - prevent wrtie triggering update. + * @public + */ + + p.set = function (value, lock) { + if (this.twoWay) { + if (lock) { + this._locked = true + } + this._watcher.set(value) + if (lock) { + var self = this + _.nextTick(function () { + self._locked = false + }) + } + } + } + + module.exports = Directive + +/***/ }, +/* 41 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var Cache = __webpack_require__(52) + var pathCache = new Cache(1000) + var identRE = /^[$_a-zA-Z]+[\w$]*$/ + + /** + * Path-parsing algorithm scooped from Polymer/observe-js + */ + + var pathStateMachine = { + 'beforePath': { + 'ws': ['beforePath'], + 'ident': ['inIdent', 'append'], + '[': ['beforeElement'], + 'eof': ['afterPath'] + }, + + 'inPath': { + 'ws': ['inPath'], + '.': ['beforeIdent'], + '[': ['beforeElement'], + 'eof': ['afterPath'] + }, + + 'beforeIdent': { + 'ws': ['beforeIdent'], + 'ident': ['inIdent', 'append'] + }, + + 'inIdent': { + 'ident': ['inIdent', 'append'], + '0': ['inIdent', 'append'], + 'number': ['inIdent', 'append'], + 'ws': ['inPath', 'push'], + '.': ['beforeIdent', 'push'], + '[': ['beforeElement', 'push'], + 'eof': ['afterPath', 'push'] + }, + + 'beforeElement': { + 'ws': ['beforeElement'], + '0': ['afterZero', 'append'], + 'number': ['inIndex', 'append'], + "'": ['inSingleQuote', 'append', ''], + '"': ['inDoubleQuote', 'append', ''] + }, + + 'afterZero': { + 'ws': ['afterElement', 'push'], + ']': ['inPath', 'push'] + }, + + 'inIndex': { + '0': ['inIndex', 'append'], + 'number': ['inIndex', 'append'], + 'ws': ['afterElement'], + ']': ['inPath', 'push'] + }, + + 'inSingleQuote': { + "'": ['afterElement'], + 'eof': 'error', + 'else': ['inSingleQuote', 'append'] + }, + + 'inDoubleQuote': { + '"': ['afterElement'], + 'eof': 'error', + 'else': ['inDoubleQuote', 'append'] + }, + + 'afterElement': { + 'ws': ['afterElement'], + ']': ['inPath', 'push'] + } + } + + function noop () {} + + /** + * Determine the type of a character in a keypath. + * + * @param {Char} char + * @return {String} type + */ + + function getPathCharType (char) { + if (char === undefined) { + return 'eof' + } + + var code = char.charCodeAt(0) + + switch(code) { + case 0x5B: // [ + case 0x5D: // ] + case 0x2E: // . + case 0x22: // " + case 0x27: // ' + case 0x30: // 0 + return char + + case 0x5F: // _ + case 0x24: // $ + return 'ident' + + case 0x20: // Space + case 0x09: // Tab + case 0x0A: // Newline + case 0x0D: // Return + case 0xA0: // No-break space + case 0xFEFF: // Byte Order Mark + case 0x2028: // Line Separator + case 0x2029: // Paragraph Separator + return 'ws' + } + + // a-z, A-Z + if ((0x61 <= code && code <= 0x7A) || + (0x41 <= code && code <= 0x5A)) { + return 'ident' + } + + // 1-9 + if (0x31 <= code && code <= 0x39) { + return 'number' + } + + return 'else' + } + + /** + * Parse a string path into an array of segments + * Todo implement cache + * + * @param {String} path + * @return {Array|undefined} + */ + + function parsePath (path) { + var keys = [] + var index = -1 + var mode = 'beforePath' + var c, newChar, key, type, transition, action, typeMap + + var actions = { + push: function() { + if (key === undefined) { + return + } + keys.push(key) + key = undefined + }, + append: function() { + if (key === undefined) { + key = newChar + } else { + key += newChar + } + } + } + + function maybeUnescapeQuote () { + var nextChar = path[index + 1] + if ((mode === 'inSingleQuote' && nextChar === "'") || + (mode === 'inDoubleQuote' && nextChar === '"')) { + index++ + newChar = nextChar + actions.append() + return true + } + } + + while (mode) { + index++ + c = path[index] + + if (c === '\\' && maybeUnescapeQuote()) { + continue + } + + type = getPathCharType(c) + typeMap = pathStateMachine[mode] + transition = typeMap[type] || typeMap['else'] || 'error' + + if (transition === 'error') { + return // parse error + } + + mode = transition[0] + action = actions[transition[1]] || noop + newChar = transition[2] === undefined + ? c + : transition[2] + action() + + if (mode === 'afterPath') { + return keys + } + } + } + + /** + * Format a accessor segment based on its type. + * + * @param {String} key + * @return {Boolean} + */ + + function formatAccessor(key) { + if (identRE.test(key)) { // identifier + return '.' + key + } else if (+key === key >>> 0) { // bracket index + return '[' + key + ']'; + } else { // bracket string + return '["' + key.replace(/"/g, '\\"') + '"]'; + } + } + + /** + * Compiles a getter function with a fixed path. + * + * @param {Array} path + * @return {Function} + */ + + exports.compileGetter = function (path) { + var body = + 'try{return o' + + path.map(formatAccessor).join('') + + '}catch(e){};' + return new Function('o', body) + } + + /** + * External parse that check for a cache hit first + * + * @param {String} path + * @return {Array|undefined} + */ + + exports.parse = function (path) { + var hit = pathCache.get(path) + if (!hit) { + hit = parsePath(path) + if (hit) { + hit.get = exports.compileGetter(hit) + pathCache.put(path, hit) + } + } + return hit + } + + /** + * Get from an object from a path string + * + * @param {Object} obj + * @param {String} path + */ + + exports.get = function (obj, path) { + path = exports.parse(path) + if (path) { + return path.get(obj) + } + } + + /** + * Set on an object from a path + * + * @param {Object} obj + * @param {String | Array} path + * @param {*} val + */ + + exports.set = function (obj, path, val) { + if (typeof path === 'string') { + path = exports.parse(path) + } + if (!path || !_.isObject(obj)) { + return false + } + var last, key + for (var i = 0, l = path.length - 1; i < l; i++) { + last = obj + key = path[i] + obj = obj[key] + if (!_.isObject(obj)) { + obj = {} + last.$add(key, obj) + } + } + key = path[i] + if (key in obj) { + obj[key] = val + } else { + obj.$add(key, val) + } + return true + } + +/***/ }, +/* 42 */ +/***/ function(module, exports, __webpack_require__) { + + var Cache = __webpack_require__(52) + var config = __webpack_require__(20) + var dirParser = __webpack_require__(43) + var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g + var cache, tagRE, htmlRE, firstChar, lastChar + + /** + * Escape a string so it can be used in a RegExp + * constructor. + * + * @param {String} str + */ + + function escapeRegex (str) { + return str.replace(regexEscapeRE, '\\$&') + } + + /** + * Compile the interpolation tag regex. + * + * @return {RegExp} + */ + + function compileRegex () { + config._delimitersChanged = false + var open = config.delimiters[0] + var close = config.delimiters[1] + firstChar = open.charAt(0) + lastChar = close.charAt(close.length - 1) + var firstCharRE = escapeRegex(firstChar) + var lastCharRE = escapeRegex(lastChar) + var openRE = escapeRegex(open) + var closeRE = escapeRegex(close) + tagRE = new RegExp( + firstCharRE + '?' + openRE + + '(.+?)' + + closeRE + lastCharRE + '?', + 'g' + ) + htmlRE = new RegExp( + '^' + firstCharRE + openRE + + '.*' + + closeRE + lastCharRE + '$' + ) + // 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 (config._delimitersChanged) { + compileRegex() + } + var hit = cache.get(text) + if (hit) { + return hit + } + if (!tagRE.test(text)) { + return null + } + var tokens = [] + var lastIndex = tagRE.lastIndex = 0 + var match, index, value, first, oneTime, partial + /* jshint boss:true */ + while (match = tagRE.exec(text)) { + index = match.index + // push text token + if (index > lastIndex) { + tokens.push({ + value: text.slice(lastIndex, index) + }) + } + // tag token + first = match[1].charCodeAt(0) + oneTime = first === 0x2A // * + partial = first === 0x3E // > + value = (oneTime || partial) + ? match[1].slice(1) + : match[1] + tokens.push({ + tag: true, + value: value.trim(), + html: htmlRE.test(match[0]), + oneTime: oneTime, + partial: partial + }) + 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 + * @param {Vue} [vm] + * @return {String} + */ + + exports.tokensToExp = function (tokens, vm) { + return tokens.length > 1 + ? tokens.map(function (token) { + return formatToken(token, vm) + }).join('+') + : formatToken(tokens[0], vm, true) + } + + /** + * Format a single token. + * + * @param {Object} token + * @param {Vue} [vm] + * @param {Boolean} single + * @return {String} + */ + + function formatToken (token, vm, single) { + return token.tag + ? vm && token.oneTime + ? '"' + vm.$eval(token.value) + '"' + : single + ? token.value + : inlineFilters(token.value) + : '"' + 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 + * @return {String} + */ + + var filterRE = /[^|]\|[^|]/ + function inlineFilters (exp) { + if (!filterRE.test(exp)) { + return '(' + exp + ')' + } else { + var dir = dirParser.parse(exp)[0] + if (!dir.filters) { + return '(' + exp + ')' + } else { + exp = dir.expression + for (var i = 0, l = dir.filters.length; i < l; i++) { + var filter = dir.filters[i] + var args = filter.args + ? ',"' + filter.args.join('","') + '"' + : '' + exp = 'this.$options.filters["' + filter.name + '"]' + + '.apply(this,[' + exp + args + '])' + } + return exp + } + } + } + +/***/ }, +/* 43 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var Cache = __webpack_require__(52) + var cache = new Cache(1000) + var argRE = /^[^\{\?]+$|^'[^']*'$|^"[^"]*"$/ + var filterTokenRE = /[^\s'"]+|'[^']+'|"[^"]+"/g + + /** + * Parser state + */ + + var str + var c, i, l + var inSingle + var inDouble + var curly + var square + var paren + var begin + var argIndex + var dirs + var dir + var lastFilterIndex + var arg + + /** + * Push a directive object into the result Array + */ + + function pushDir () { + dir.raw = str.slice(begin, i).trim() + if (dir.expression === undefined) { + dir.expression = str.slice(argIndex, i).trim() + } else if (lastFilterIndex !== begin) { + pushFilter() + } + if (i === 0 || dir.expression) { + dirs.push(dir) + } + } + + /** + * 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] + filter.args = tokens.length > 1 ? tokens.slice(1) : null + } + if (filter) { + (dir.filters = dir.filters || []).push(filter) + } + lastFilterIndex = i + 1 + } + + /** + * Parse a directive string into an Array of AST-like + * objects representing directives. + * + * Example: + * + * "click: a = a + 1 | uppercase" will yield: + * { + * arg: 'click', + * expression: 'a = a + 1', + * filters: [ + * { name: 'uppercase', args: null } + * ] + * } + * + * @param {String} str + * @return {Array} + */ + + exports.parse = function (s) { + + var hit = cache.get(s) + if (hit) { + return hit + } + + // reset parser state + str = s + inSingle = inDouble = false + curly = square = paren = begin = argIndex = 0 + lastFilterIndex = 0 + dirs = [] + dir = {} + arg = null + + 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 === 0x2C && // comma + !paren && !curly && !square + ) { + // reached the end of a directive + pushDir() + // reset & skip the comma + dir = {} + begin = argIndex = lastFilterIndex = i + 1 + } else if ( + c === 0x3A && // colon + !dir.expression && + !dir.arg + ) { + // argument + arg = str.slice(begin, i).trim() + // test for valid argument here + // since we may have caught stuff like first half of + // an object literal or a ternary expression. + if (argRE.test(arg)) { + argIndex = i + 1 + dir.arg = _.stripQuotes(arg) || arg + } + } else if ( + c === 0x7C && // pipe + str.charCodeAt(i + 1) !== 0x7C && + str.charCodeAt(i - 1) !== 0x7C + ) { + if (dir.expression === undefined) { + // first filter, end of expression + lastFilterIndex = i + 1 + dir.expression = str.slice(argIndex, 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 (i === 0 || begin !== i) { + pushDir() + } + + cache.put(s, dirs) + return dirs + } + +/***/ }, +/* 44 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var Path = __webpack_require__(41) + var Cache = __webpack_require__(52) + var expressionCache = new Cache(1000) + + var keywords = + 'Math,break,case,catch,continue,debugger,default,' + + 'delete,do,else,false,finally,for,function,if,in,' + + 'instanceof,new,null,return,switch,this,throw,true,try,' + + 'typeof,var,void,while,with,undefined,abstract,boolean,' + + 'byte,char,class,const,double,enum,export,extends,' + + 'final,float,goto,implements,import,int,interface,long,' + + 'native,package,private,protected,public,short,static,' + + 'super,synchronized,throws,transient,volatile,' + + 'arguments,let,yield' + + var wsRE = /\s/g + var newlineRE = /\n/g + var saveRE = /[\{,]\s*[\w\$_]+\s*:|'[^']*'|"[^"]*"/g + var restoreRE = /"(\d+)"/g + var pathTestRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\])*$/ + var pathReplaceRE = /[^\w$\.]([A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\])*)/g + var keywordsRE = new RegExp('^(' + keywords.replace(/,/g, '\\b|') + '\\b)') + + /** + * Save / Rewrite / Restore + * + * When rewriting paths found in an expression, it is + * possible for the same letter sequences to be found in + * strings and Object literal property keys. Therefore we + * remove and store these parts in a temporary array, and + * restore them after the path rewrite. + */ + + var saved = [] + + /** + * Save replacer + * + * @param {String} str + * @return {String} - placeholder with index + */ + + function save (str) { + var i = saved.length + saved[i] = str.replace(newlineRE, '\\n') + return '"' + i + '"' + } + + /** + * Path rewrite replacer + * + * @param {String} raw + * @return {String} + */ + + function rewrite (raw) { + var c = raw.charAt(0) + var path = raw.slice(1) + if (keywordsRE.test(path)) { + return raw + } else { + path = path.indexOf('"') > -1 + ? path.replace(restoreRE, restore) + : path + return c + 'scope.' + path + } + } + + /** + * Restore replacer + * + * @param {String} str + * @param {String} i - matched save index + * @return {String} + */ + + function restore (str, i) { + return saved[i] + } + + /** + * Rewrite an expression, prefixing all path accessors with + * `scope.` and generate getter/setter functions. + * + * @param {String} exp + * @param {Boolean} needSet + * @return {Function} + */ + + function compileExpFns (exp, needSet) { + // reset state + saved.length = 0 + // save strings and object literal keys + var body = exp + .replace(saveRE, save) + .replace(wsRE, '') + // rewrite all paths + // pad 1 space here becaue the regex matches 1 extra char + body = (' ' + body) + .replace(pathReplaceRE, rewrite) + .replace(restoreRE, restore) + var getter = makeGetter(body) + if (getter) { + return { + get: getter, + body: body, + set: needSet + ? makeSetter(body) + : null + } + } + } + + /** + * Compile getter setters for a simple path. + * + * @param {String} exp + * @return {Function} + */ + + function compilePathFns (exp) { + var getter, path + if (exp.indexOf('[') < 0) { + // really simple path + path = exp.split('.') + getter = Path.compileGetter(path) + } else { + // do the real parsing + path = Path.parse(exp) + getter = path.get + } + return { + get: getter, + // always generate setter for simple paths + set: function (obj, val) { + Path.set(obj, path, val) + } + } + } + + /** + * Build a getter function. Requires eval. + * + * We isolate the try/catch so it doesn't affect the + * optimization of the parse function when it is not called. + * + * @param {String} body + * @return {Function|undefined} + */ + + function makeGetter (body) { + try { + return new Function('scope', 'return ' + body + ';') + } catch (e) { + _.warn( + 'Invalid expression. ' + + 'Generated function body: ' + body + ) + } + } + + /** + * Build a setter function. + * + * This is only needed in rare situations like "a[b]" where + * a settable path requires dynamic evaluation. + * + * This setter function may throw error when called if the + * expression body is not a valid left-hand expression in + * assignment. + * + * @param {String} body + * @return {Function|undefined} + */ + + function makeSetter (body) { + try { + return new Function('scope', 'value', body + '=value;') + } catch (e) { + _.warn('Invalid setter function body: ' + body) + } + } + + /** + * Check for setter existence on a cache hit. + * + * @param {Function} hit + */ + + function checkSetter (hit) { + if (!hit.set) { + hit.set = makeSetter(hit.body) + } + } + + /** + * Parse an expression into re-written getter/setters. + * + * @param {String} exp + * @param {Boolean} needSet + * @return {Function} + */ + + exports.parse = function (exp, needSet) { + exp = exp.trim() + // try cache + var hit = expressionCache.get(exp) + if (hit) { + if (needSet) { + checkSetter(hit) + } + return hit + } + // we do a simple path check to optimize for them. + // the check fails valid paths with unusal whitespaces, + // but that's too rare and we don't care. + var res = pathTestRE.test(exp) + ? compilePathFns(exp) + : compileExpFns(exp, needSet) + expressionCache.put(exp, res) + return res + } + + // Export the pathRegex for external use + exports.pathTestRE = pathTestRE + +/***/ }, +/* 45 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var applyCSSTransition = __webpack_require__(53) + var applyJSTransition = __webpack_require__(54) + + /** + * Append with transition. + * + * @oaram {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. + * + * @oaram {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. + * + * @oaram {Element} el + * @param {Vue} vm + * @param {Function} [cb] + */ + + exports.remove = function (el, vm, cb) { + apply(el, -1, function () { + _.remove(el) + }, vm, cb) + } + + /** + * Remove by appending to another parent with transition. + * This is only used in block operations. + * + * @oaram {Element} el + * @param {Element} target + * @param {Vue} vm + * @param {Function} [cb] + */ + + exports.removeThenAppend = function (el, target, vm, cb) { + apply(el, -1, function () { + target.appendChild(el) + }, vm, cb) + } + + /** + * Append the childNodes of a fragment to target. + * + * @param {DocumentFragment} block + * @param {Node} target + * @param {Vue} vm + */ + + exports.blockAppend = function (block, target, vm) { + var nodes = _.toArray(block.childNodes) + for (var i = 0, l = nodes.length; i < l; i++) { + exports.before(nodes[i], target, vm) + } + } + + /** + * Remove a block of nodes between two edge nodes. + * + * @param {Node} start + * @param {Node} end + * @param {Vue} vm + */ + + exports.blockRemove = function (start, end, vm) { + var node = start.nextSibling + var next + while (node !== end) { + next = node.nextSibling + exports.remove(node, vm) + node = next + } + } + + /** + * Apply transitions with an operation callback. + * + * @oaram {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 transData = el.__v_trans + if ( + !transData || + !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 + } + // determine the transition type on the element + var jsTransition = vm.$options.transitions[transData.id] + if (jsTransition) { + // js + applyJSTransition( + el, + direction, + op, + transData, + jsTransition, + vm, + cb + ) + } else if (_.transitionEndEvent) { + // css + applyCSSTransition( + el, + direction, + op, + transData, + cb + ) + } else { + // not applicable + op() + if (cb) cb() + } + } + +/***/ }, +/* 46 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var config = __webpack_require__(20) + var textParser = __webpack_require__(42) + var dirParser = __webpack_require__(43) + var templateParser = __webpack_require__(51) + + /** + * Compile a template and return a reusable composite link + * function, which recursively contains more link functions + * inside. This top level compile function should only be + * called on instance root nodes. + * + * @param {Element|DocumentFragment} el + * @param {Object} options + * @param {Boolean} partial + * @return {Function} + */ + + module.exports = function compile (el, options, partial) { + var params = !partial && options.paramAttributes + var paramsLinkFn = params + ? compileParamAttributes(el, params, options) + : null + var nodeLinkFn = el instanceof DocumentFragment + ? null + : compileNode(el, options) + var childLinkFn = + (!nodeLinkFn || !nodeLinkFn.terminal) && + el.hasChildNodes() + ? compileNodeList(el.childNodes, options) + : null + + /** + * A linker function to be called on a already compiled + * piece of DOM, which instantiates all directive + * instances. + * + * @param {Vue} vm + * @param {Element|DocumentFragment} el + * @return {Function|undefined} + */ + + return function link (vm, el) { + var originalDirCount = vm._directives.length + if (paramsLinkFn) paramsLinkFn(vm, el) + if (nodeLinkFn) nodeLinkFn(vm, el) + if (childLinkFn) childLinkFn(vm, el.childNodes) + + /** + * If this is a partial compile, the linker function + * returns an unlink function that tearsdown all + * directives instances generated during the partial + * linking. + */ + + if (partial) { + var dirs = vm._directives.slice(originalDirCount) + return function unlink () { + var i = dirs.length + while (i--) { + dirs[i]._teardown() + } + i = vm._directives.indexOf(dirs[0]) + vm._directives.splice(i, dirs.length) + } + } + } + } + + /** + * Compile a node and return a nodeLinkFn based on the + * node type. + * + * @param {Node} node + * @param {Object} options + * @return {Function|undefined} + */ + + function compileNode (node, options) { + var type = node.nodeType + if (type === 1 && node.tagName !== 'SCRIPT') { + return compileElement(node, options) + } else if (type === 3 && config.interpolate) { + return compileTextNode(node, options) + } + } + + /** + * Compile an element and return a nodeLinkFn. + * + * @param {Element} el + * @param {Object} options + * @return {Function|null} + */ + + function compileElement (el, options) { + var linkFn, tag, component + // check custom element component, but only on non-root + if (!el.__vue__) { + tag = el.tagName.toLowerCase() + component = + tag.indexOf('-') > 0 && + options.components[tag] + if (component) { + el.setAttribute(config.prefix + 'component', tag) + } + } + if (component || el.hasAttributes()) { + // check terminal direcitves + linkFn = checkTerminalDirectives(el, options) + // if not terminal, build normal link function + if (!linkFn) { + var directives = collectDirectives(el, options) + linkFn = directives.length + ? makeDirectivesLinkFn(directives) + : null + } + } + // if the element is a textarea, we need to interpolate + // its content on initial render. + if (el.tagName === 'TEXTAREA') { + var realLinkFn = linkFn + linkFn = function (vm, el) { + el.value = vm.$interpolate(el.value) + if (realLinkFn) realLinkFn(vm, el) + } + linkFn.terminal = true + } + return linkFn + } + + /** + * Build a multi-directive link function. + * + * @param {Array} directives + * @return {Function} directivesLinkFn + */ + + function makeDirectivesLinkFn (directives) { + return function directivesLinkFn (vm, el) { + // reverse apply because it's sorted low to high + var i = directives.length + var dir, j, k + while (i--) { + dir = directives[i] + if (dir._link) { + // custom link fn + dir._link(vm, el) + } else { + k = dir.descriptors.length + for (j = 0; j < k; j++) { + vm._bindDir(dir.name, el, + dir.descriptors[j], dir.def) + } + } + } + } + } + + /** + * 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.nodeValue) + if (!tokens) { + return null + } + var frag = document.createDocumentFragment() + var dirs = options.directives + var el, token, value + for (var i = 0, l = tokens.length; i < l; i++) { + token = tokens[i] + value = token.value + if (token.tag) { + if (token.oneTime) { + el = document.createTextNode(value) + } else { + if (token.html) { + el = document.createComment('v-html') + token.type = 'html' + token.def = dirs.html + token.descriptor = dirParser.parse(value)[0] + } else if (token.partial) { + el = document.createComment('v-partial') + token.type = 'partial' + token.def = dirs.partial + token.descriptor = dirParser.parse(value)[0] + } else { + // IE will clean up empty textNodes during + // frag.cloneNode(true), so we have to give it + // something here... + el = document.createTextNode(' ') + token.type = 'text' + token.def = dirs.text + token.descriptor = dirParser.parse(value)[0] + } + } + } else { + el = document.createTextNode(value) + } + frag.appendChild(el) + } + return makeTextNodeLinkFn(tokens, frag, options) + } + + /** + * Build a function that processes a textNode. + * + * @param {Array} tokens + * @param {DocumentFragment} frag + */ + + function makeTextNodeLinkFn (tokens, frag) { + return function textNodeLinkFn (vm, el) { + 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 = vm.$eval(value) + if (token.html) { + _.replace(node, templateParser.parse(value, true)) + } else { + node.nodeValue = value + } + } else { + vm._bindDir(token.type, node, + token.descriptor, token.def) + } + } + } + _.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.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) { + // stablize nodes + nodes = _.toArray(nodes) + 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++] + if (nodeLinkFn) { + nodeLinkFn(vm, node) + } + if (childrenLinkFn) { + childrenLinkFn(vm, node.childNodes) + } + } + } + } + + /** + * Compile param attributes on a root element and return + * a paramAttributes link function. + * + * @param {Element} el + * @param {Array} attrs + * @param {Object} options + * @return {Function} paramsLinkFn + */ + + function compileParamAttributes (el, attrs, options) { + var params = [] + var i = attrs.length + var name, value, param + while (i--) { + name = attrs[i] + value = el.getAttribute(name) + if (value !== null) { + param = { + name: name, + value: value + } + var tokens = textParser.parse(value) + if (tokens) { + el.removeAttribute(name) + if (tokens.length > 1) { + _.warn( + 'Invalid param attribute binding: "' + + name + '="' + value + '"' + + '\nDon\'t mix binding tags with plain text ' + + 'in param attribute bindings.' + ) + continue + } else { + param.dynamic = true + param.value = tokens[0].value + } + } + params.push(param) + } + } + return makeParamsLinkFn(params, options) + } + + /** + * Build a function that applies param attributes to a vm. + * + * @param {Array} params + * @param {Object} options + * @return {Function} paramsLinkFn + */ + + var dataAttrRE = /^data-/ + + function makeParamsLinkFn (params, options) { + var def = options.directives['with'] + return function paramsLinkFn (vm, el) { + var i = params.length + var param, path + while (i--) { + param = params[i] + // params could contain dashes, which will be + // interpreted as minus calculations by the parser + // so we need to wrap the path here + path = _.camelize(param.name.replace(dataAttrRE, '')) + if (param.dynamic) { + // dynamic param attribtues are bound as v-with. + // we can directly duck the descriptor here beacuse + // param attributes cannot use expressions or + // filters. + vm._bindDir('with', el, { + arg: path, + expression: param.value + }, def) + } else { + // just set once + vm.$set(path, param.value) + } + } + } + } + + /** + * 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 + */ + + var terminalDirectives = [ + 'repeat', + 'if', + 'component' + ] + + function skip () {} + skip.terminal = true + + function checkTerminalDirectives (el, options) { + if (_.attr(el, 'pre') !== null) { + return skip + } + var value, dirName + /* jshint boss: true */ + for (var i = 0; i < 3; i++) { + dirName = terminalDirectives[i] + if (value = _.attr(el, dirName)) { + return makeTeriminalLinkFn(el, dirName, value, options) + } + } + } + + /** + * Build a link function for a terminal directive. + * + * @param {Element} el + * @param {String} dirName + * @param {String} value + * @param {Object} options + * @return {Function} terminalLinkFn + */ + + function makeTeriminalLinkFn (el, dirName, value, options) { + var descriptor = dirParser.parse(value)[0] + var def = options.directives[dirName] + // special case: we need to collect directives found + // on a component root node, but defined in the parent + // template. These directives need to be compiled in + // the parent scope. + if (dirName === 'component') { + var dirs = collectDirectives(el, options, true) + el._parentLinker = dirs.length + ? makeDirectivesLinkFn(dirs) + : null + } + var terminalLinkFn = function (vm, el) { + vm._bindDir(dirName, el, descriptor, def) + } + terminalLinkFn.terminal = true + return terminalLinkFn + } + + /** + * Collect the directives on an element. + * + * @param {Element} el + * @param {Object} options + * @param {Boolean} asParent + * @return {Array} + */ + + function collectDirectives (el, options, asParent) { + var attrs = _.toArray(el.attributes) + var i = attrs.length + var dirs = [] + var attr, attrName, dir, dirName, dirDef + while (i--) { + attr = attrs[i] + attrName = attr.name + if (attrName.indexOf(config.prefix) === 0) { + dirName = attrName.slice(config.prefix.length) + if ( + asParent && + (dirName === 'with' || dirName === 'ref') + ) { + continue + } + dirDef = options.directives[dirName] + _.assertAsset(dirDef, 'directive', dirName) + if (dirDef) { + dirs.push({ + name: dirName, + descriptors: dirParser.parse(attr.value), + def: dirDef + }) + } + } else if (config.interpolate) { + dir = collectAttrDirective(el, attrName, attr.value, + options) + if (dir) { + dirs.push(dir) + } + } + } + // sort by priority, LOW to HIGH + dirs.sort(directiveComparator) + return dirs + } + + /** + * Check an attribute for potential dynamic bindings, + * and return a directive object. + * + * @param {Element} el + * @param {String} name + * @param {String} value + * @param {Object} options + * @return {Object} + */ + + function collectAttrDirective (el, name, value, options) { + var tokens = textParser.parse(value) + if (tokens) { + var def = options.directives.attr + var i = tokens.length + var allOneTime = true + while (i--) { + var token = tokens[i] + if (token.tag && !token.oneTime) { + allOneTime = false + } + } + return { + def: def, + _link: allOneTime + ? function (vm, el) { + el.setAttribute(name, vm.$interpolate(value)) + } + : function (vm, el) { + var value = textParser.tokensToExp(tokens, vm) + var desc = dirParser.parse(name + ':' + value)[0] + vm._bindDir('attr', el, desc, def) + } + } + } + } + + /** + * Directive priority sort comparator + * + * @param {Object} a + * @param {Object} b + */ + + function directiveComparator (a, b) { + a = a.def.priority || 0 + b = b.def.priority || 0 + return a > b ? 1 : -1 + } + +/***/ }, +/* 47 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + var templateParser = __webpack_require__(51) + + /** + * Process an element or a DocumentFragment based on a + * instance option object. This allows us to transclude + * a template node/fragment before the instance is created, + * so the processed fragment can then be cloned and reused + * in v-repeat. + * + * @param {Element} el + * @param {Object} options + * @return {Element|DocumentFragment} + */ + + module.exports = function transclude (el, options) { + // for template tags, what we want is its content as + // a documentFragment (for block instances) + if (el.tagName === 'TEMPLATE') { + el = templateParser.parse(el) + } + if (options && options.template) { + el = transcludeTemplate(el, options) + } + if (el instanceof DocumentFragment) { + _.prepend(document.createComment('v-start'), el) + el.appendChild(document.createComment('v-end')) + } + return el + } + + /** + * Process the template option. + * If the replace option is true this will swap the $el. + * + * @param {Element} el + * @param {Object} options + * @return {Element|DocumentFragment} + */ + + function transcludeTemplate (el, options) { + var template = options.template + var frag = templateParser.parse(template, true) + if (!frag) { + _.warn('Invalid template option: ' + template) + } else { + collectRawContent(el) + if (options.replace) { + if (frag.childNodes.length > 1) { + transcludeContent(frag) + return frag + } else { + var replacer = frag.firstChild + _.copyAttributes(el, replacer) + transcludeContent(replacer) + return replacer + } + } else { + el.appendChild(frag) + transcludeContent(el) + return el + } + } + } + + /** + * Collect raw content inside $el before they are + * replaced by template content. + */ + + var rawContent + function collectRawContent (el) { + var child + rawContent = null + if (el.hasChildNodes()) { + rawContent = document.createElement('div') + /* jshint boss:true */ + while (child = el.firstChild) { + rawContent.appendChild(child) + } + } + } + + /** + * Resolve insertion points mimicking the behavior + * of the Shadow DOM spec: + * + * http://w3c.github.io/webcomponents/spec/shadow/#insertion-points + * + * @param {Element|DocumentFragment} el + */ + + function transcludeContent (el) { + var outlets = getOutlets(el) + var i = outlets.length + if (!i) return + var outlet, select, selected, j, main + // first pass, collect corresponding content + // for each outlet. + while (i--) { + outlet = outlets[i] + if (rawContent) { + select = outlet.getAttribute('select') + if (select) { // select content + selected = rawContent.querySelectorAll(select) + outlet.content = _.toArray( + selected.length + ? selected + : outlet.childNodes + ) + } else { // default content + main = outlet + } + } else { // fallback content + outlet.content = _.toArray(outlet.childNodes) + } + } + // second pass, actually insert the contents + for (i = 0, j = outlets.length; i < j; i++) { + outlet = outlets[i] + if (outlet !== main) { + insertContentAt(outlet, outlet.content) + } + } + // finally insert the main content + if (main) { + insertContentAt(main, _.toArray(rawContent.childNodes)) + } + } + + /** + * Get outlets from the element/list + * + * @param {Element|Array} el + * @return {Array} + */ + + var concat = [].concat + function getOutlets (el) { + return _.isArray(el) + ? concat.apply([], el.map(getOutlets)) + : el.querySelectorAll + ? _.toArray(el.querySelectorAll('content')) + : [] + } + + /** + * Insert an array of nodes at outlet, + * then remove the outlet. + * + * @param {Element} outlet + * @param {Array} contents + */ + + function insertContentAt (outlet, contents) { + // not using util DOM methods here because + // parentNode can be cached + var parent = outlet.parentNode + for (var i = 0, j = contents.length; i < j; i++) { + parent.insertBefore(contents[i], outlet) + } + parent.removeChild(outlet) + } + +/***/ }, +/* 48 */ +/***/ function(module, exports, __webpack_require__) { + + var _ = __webpack_require__(1) + + var handlers = { + _default: __webpack_require__(55), + radio: __webpack_require__(56), + select: __webpack_require__(57), + checkbox: __webpack_require__(58) + } + + module.exports = { + + priority: 800, + twoWay: true, + handlers: handlers, + + /** + * Possible elements: + *