aboutsummaryrefslogtreecommitdiff
path: root/node_modules/vue/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/vue/src/core')
-rw-r--r--node_modules/vue/src/core/components/index.js5
-rw-r--r--node_modules/vue/src/core/components/keep-alive.js124
-rw-r--r--node_modules/vue/src/core/config.js121
-rw-r--r--node_modules/vue/src/core/global-api/assets.js34
-rw-r--r--node_modules/vue/src/core/global-api/extend.js95
-rw-r--r--node_modules/vue/src/core/global-api/index.js62
-rw-r--r--node_modules/vue/src/core/global-api/mixin.js10
-rw-r--r--node_modules/vue/src/core/global-api/use.js23
-rw-r--r--node_modules/vue/src/core/index.js26
-rw-r--r--node_modules/vue/src/core/instance/events.js142
-rw-r--r--node_modules/vue/src/core/instance/index.js23
-rw-r--r--node_modules/vue/src/core/instance/init.js150
-rw-r--r--node_modules/vue/src/core/instance/inject.js74
-rw-r--r--node_modules/vue/src/core/instance/lifecycle.js336
-rw-r--r--node_modules/vue/src/core/instance/proxy.js79
-rw-r--r--node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js22
-rw-r--r--node_modules/vue/src/core/instance/render-helpers/bind-object-props.js60
-rw-r--r--node_modules/vue/src/core/instance/render-helpers/check-keycodes.js34
-rw-r--r--node_modules/vue/src/core/instance/render-helpers/index.js30
-rw-r--r--node_modules/vue/src/core/instance/render-helpers/render-list.js39
-rw-r--r--node_modules/vue/src/core/instance/render-helpers/render-slot.js50
-rw-r--r--node_modules/vue/src/core/instance/render-helpers/render-static.js60
-rw-r--r--node_modules/vue/src/core/instance/render-helpers/resolve-filter.js10
-rw-r--r--node_modules/vue/src/core/instance/render-helpers/resolve-slots.js65
-rw-r--r--node_modules/vue/src/core/instance/render.js119
-rw-r--r--node_modules/vue/src/core/instance/state.js360
-rw-r--r--node_modules/vue/src/core/observer/array.js45
-rw-r--r--node_modules/vue/src/core/observer/dep.js58
-rw-r--r--node_modules/vue/src/core/observer/index.js273
-rw-r--r--node_modules/vue/src/core/observer/scheduler.js148
-rw-r--r--node_modules/vue/src/core/observer/traverse.js40
-rw-r--r--node_modules/vue/src/core/observer/watcher.js240
-rw-r--r--node_modules/vue/src/core/util/debug.js100
-rw-r--r--node_modules/vue/src/core/util/env.js95
-rw-r--r--node_modules/vue/src/core/util/error.js48
-rw-r--r--node_modules/vue/src/core/util/index.js11
-rw-r--r--node_modules/vue/src/core/util/lang.js39
-rw-r--r--node_modules/vue/src/core/util/next-tick.js117
-rw-r--r--node_modules/vue/src/core/util/options.js438
-rw-r--r--node_modules/vue/src/core/util/perf.js24
-rw-r--r--node_modules/vue/src/core/util/props.js202
-rw-r--r--node_modules/vue/src/core/vdom/create-component.js257
-rw-r--r--node_modules/vue/src/core/vdom/create-element.js160
-rw-r--r--node_modules/vue/src/core/vdom/create-functional-component.js136
-rw-r--r--node_modules/vue/src/core/vdom/helpers/extract-props.js75
-rw-r--r--node_modules/vue/src/core/vdom/helpers/get-first-component-child.js15
-rw-r--r--node_modules/vue/src/core/vdom/helpers/index.js9
-rw-r--r--node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js5
-rw-r--r--node_modules/vue/src/core/vdom/helpers/merge-hook.js38
-rw-r--r--node_modules/vue/src/core/vdom/helpers/normalize-children.js89
-rw-r--r--node_modules/vue/src/core/vdom/helpers/resolve-async-component.js140
-rw-r--r--node_modules/vue/src/core/vdom/helpers/update-listeners.js83
-rw-r--r--node_modules/vue/src/core/vdom/modules/directives.js119
-rw-r--r--node_modules/vue/src/core/vdom/modules/index.js7
-rw-r--r--node_modules/vue/src/core/vdom/modules/ref.js45
-rw-r--r--node_modules/vue/src/core/vdom/patch.js787
-rw-r--r--node_modules/vue/src/core/vdom/vnode.js108
57 files changed, 6104 insertions, 0 deletions
diff --git a/node_modules/vue/src/core/components/index.js b/node_modules/vue/src/core/components/index.js
new file mode 100644
index 00000000..5461c763
--- /dev/null
+++ b/node_modules/vue/src/core/components/index.js
@@ -0,0 +1,5 @@
+import KeepAlive from './keep-alive'
+
+export default {
+ KeepAlive
+}
diff --git a/node_modules/vue/src/core/components/keep-alive.js b/node_modules/vue/src/core/components/keep-alive.js
new file mode 100644
index 00000000..fb4cf1e8
--- /dev/null
+++ b/node_modules/vue/src/core/components/keep-alive.js
@@ -0,0 +1,124 @@
+/* @flow */
+
+import { isRegExp, remove } from 'shared/util'
+import { getFirstComponentChild } from 'core/vdom/helpers/index'
+
+type VNodeCache = { [key: string]: ?VNode };
+
+function getComponentName (opts: ?VNodeComponentOptions): ?string {
+ return opts && (opts.Ctor.options.name || opts.tag)
+}
+
+function matches (pattern: string | RegExp | Array<string>, name: string): boolean {
+ if (Array.isArray(pattern)) {
+ return pattern.indexOf(name) > -1
+ } else if (typeof pattern === 'string') {
+ return pattern.split(',').indexOf(name) > -1
+ } else if (isRegExp(pattern)) {
+ return pattern.test(name)
+ }
+ /* istanbul ignore next */
+ return false
+}
+
+function pruneCache (keepAliveInstance: any, filter: Function) {
+ const { cache, keys, _vnode } = keepAliveInstance
+ for (const key in cache) {
+ const cachedNode: ?VNode = cache[key]
+ if (cachedNode) {
+ const name: ?string = getComponentName(cachedNode.componentOptions)
+ if (name && !filter(name)) {
+ pruneCacheEntry(cache, key, keys, _vnode)
+ }
+ }
+ }
+}
+
+function pruneCacheEntry (
+ cache: VNodeCache,
+ key: string,
+ keys: Array<string>,
+ current?: VNode
+) {
+ const cached = cache[key]
+ if (cached && (!current || cached.tag !== current.tag)) {
+ cached.componentInstance.$destroy()
+ }
+ cache[key] = null
+ remove(keys, key)
+}
+
+const patternTypes: Array<Function> = [String, RegExp, Array]
+
+export default {
+ name: 'keep-alive',
+ abstract: true,
+
+ props: {
+ include: patternTypes,
+ exclude: patternTypes,
+ max: [String, Number]
+ },
+
+ created () {
+ this.cache = Object.create(null)
+ this.keys = []
+ },
+
+ destroyed () {
+ for (const key in this.cache) {
+ pruneCacheEntry(this.cache, key, this.keys)
+ }
+ },
+
+ mounted () {
+ this.$watch('include', val => {
+ pruneCache(this, name => matches(val, name))
+ })
+ this.$watch('exclude', val => {
+ pruneCache(this, name => !matches(val, name))
+ })
+ },
+
+ render () {
+ const slot = this.$slots.default
+ const vnode: VNode = getFirstComponentChild(slot)
+ const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
+ if (componentOptions) {
+ // check pattern
+ const name: ?string = getComponentName(componentOptions)
+ const { include, exclude } = this
+ if (
+ // not included
+ (include && (!name || !matches(include, name))) ||
+ // excluded
+ (exclude && name && matches(exclude, name))
+ ) {
+ return vnode
+ }
+
+ const { cache, keys } = this
+ const key: ?string = vnode.key == null
+ // same constructor may get registered as different local components
+ // so cid alone is not enough (#3269)
+ ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
+ : vnode.key
+ if (cache[key]) {
+ vnode.componentInstance = cache[key].componentInstance
+ // make current key freshest
+ remove(keys, key)
+ keys.push(key)
+ } else {
+ cache[key] = vnode
+ keys.push(key)
+ // prune oldest entry
+ if (this.max && keys.length > parseInt(this.max)) {
+ pruneCacheEntry(cache, keys[0], keys, this._vnode)
+ }
+ }
+
+ vnode.data.keepAlive = true
+ }
+ return vnode || (slot && slot[0])
+ }
+}
diff --git a/node_modules/vue/src/core/config.js b/node_modules/vue/src/core/config.js
new file mode 100644
index 00000000..f25f09d1
--- /dev/null
+++ b/node_modules/vue/src/core/config.js
@@ -0,0 +1,121 @@
+/* @flow */
+
+import {
+ no,
+ noop,
+ identity
+} from 'shared/util'
+
+import { LIFECYCLE_HOOKS } from 'shared/constants'
+
+export type Config = {
+ // user
+ optionMergeStrategies: { [key: string]: Function };
+ silent: boolean;
+ productionTip: boolean;
+ performance: boolean;
+ devtools: boolean;
+ errorHandler: ?(err: Error, vm: Component, info: string) => void;
+ warnHandler: ?(msg: string, vm: Component, trace: string) => void;
+ ignoredElements: Array<string | RegExp>;
+ keyCodes: { [key: string]: number | Array<number> };
+
+ // platform
+ isReservedTag: (x?: string) => boolean;
+ isReservedAttr: (x?: string) => boolean;
+ parsePlatformTagName: (x: string) => string;
+ isUnknownElement: (x?: string) => boolean;
+ getTagNamespace: (x?: string) => string | void;
+ mustUseProp: (tag: string, type: ?string, name: string) => boolean;
+
+ // legacy
+ _lifecycleHooks: Array<string>;
+};
+
+export default ({
+ /**
+ * Option merge strategies (used in core/util/options)
+ */
+ // $flow-disable-line
+ optionMergeStrategies: Object.create(null),
+
+ /**
+ * Whether to suppress warnings.
+ */
+ silent: false,
+
+ /**
+ * Show production mode tip message on boot?
+ */
+ productionTip: process.env.NODE_ENV !== 'production',
+
+ /**
+ * Whether to enable devtools
+ */
+ devtools: process.env.NODE_ENV !== 'production',
+
+ /**
+ * Whether to record perf
+ */
+ performance: false,
+
+ /**
+ * Error handler for watcher errors
+ */
+ errorHandler: null,
+
+ /**
+ * Warn handler for watcher warns
+ */
+ warnHandler: null,
+
+ /**
+ * Ignore certain custom elements
+ */
+ ignoredElements: [],
+
+ /**
+ * Custom user key aliases for v-on
+ */
+ // $flow-disable-line
+ keyCodes: Object.create(null),
+
+ /**
+ * Check if a tag is reserved so that it cannot be registered as a
+ * component. This is platform-dependent and may be overwritten.
+ */
+ isReservedTag: no,
+
+ /**
+ * Check if an attribute is reserved so that it cannot be used as a component
+ * prop. This is platform-dependent and may be overwritten.
+ */
+ isReservedAttr: no,
+
+ /**
+ * Check if a tag is an unknown element.
+ * Platform-dependent.
+ */
+ isUnknownElement: no,
+
+ /**
+ * Get the namespace of an element
+ */
+ getTagNamespace: noop,
+
+ /**
+ * Parse the real tag name for the specific platform.
+ */
+ parsePlatformTagName: identity,
+
+ /**
+ * Check if an attribute must be bound using property, e.g. value
+ * Platform-dependent.
+ */
+ mustUseProp: no,
+
+ /**
+ * Exposed for legacy reasons
+ */
+ _lifecycleHooks: LIFECYCLE_HOOKS
+}: Config)
diff --git a/node_modules/vue/src/core/global-api/assets.js b/node_modules/vue/src/core/global-api/assets.js
new file mode 100644
index 00000000..d975a6a5
--- /dev/null
+++ b/node_modules/vue/src/core/global-api/assets.js
@@ -0,0 +1,34 @@
+/* @flow */
+
+import { ASSET_TYPES } from 'shared/constants'
+import { isPlainObject, validateComponentName } from '../util/index'
+
+export function initAssetRegisters (Vue: GlobalAPI) {
+ /**
+ * Create asset registration methods.
+ */
+ ASSET_TYPES.forEach(type => {
+ Vue[type] = function (
+ id: string,
+ definition: Function | Object
+ ): Function | Object | void {
+ if (!definition) {
+ return this.options[type + 's'][id]
+ } else {
+ /* istanbul ignore if */
+ if (process.env.NODE_ENV !== 'production' && type === 'component') {
+ validateComponentName(id)
+ }
+ if (type === 'component' && isPlainObject(definition)) {
+ definition.name = definition.name || id
+ definition = this.options._base.extend(definition)
+ }
+ if (type === 'directive' && typeof definition === 'function') {
+ definition = { bind: definition, update: definition }
+ }
+ this.options[type + 's'][id] = definition
+ return definition
+ }
+ }
+ })
+}
diff --git a/node_modules/vue/src/core/global-api/extend.js b/node_modules/vue/src/core/global-api/extend.js
new file mode 100644
index 00000000..c1bbda3f
--- /dev/null
+++ b/node_modules/vue/src/core/global-api/extend.js
@@ -0,0 +1,95 @@
+/* @flow */
+
+import { ASSET_TYPES } from 'shared/constants'
+import { defineComputed, proxy } from '../instance/state'
+import { extend, mergeOptions, validateComponentName } from '../util/index'
+
+export function initExtend (Vue: GlobalAPI) {
+ /**
+ * Each instance constructor, including Vue, has a unique
+ * cid. This enables us to create wrapped "child
+ * constructors" for prototypal inheritance and cache them.
+ */
+ Vue.cid = 0
+ let cid = 1
+
+ /**
+ * Class inheritance
+ */
+ Vue.extend = function (extendOptions: Object): Function {
+ extendOptions = extendOptions || {}
+ const Super = this
+ const SuperId = Super.cid
+ const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
+ if (cachedCtors[SuperId]) {
+ return cachedCtors[SuperId]
+ }
+
+ const name = extendOptions.name || Super.options.name
+ if (process.env.NODE_ENV !== 'production' && name) {
+ validateComponentName(name)
+ }
+
+ const Sub = function VueComponent (options) {
+ this._init(options)
+ }
+ Sub.prototype = Object.create(Super.prototype)
+ Sub.prototype.constructor = Sub
+ Sub.cid = cid++
+ Sub.options = mergeOptions(
+ Super.options,
+ extendOptions
+ )
+ Sub['super'] = Super
+
+ // For props and computed properties, we define the proxy getters on
+ // the Vue instances at extension time, on the extended prototype. This
+ // avoids Object.defineProperty calls for each instance created.
+ if (Sub.options.props) {
+ initProps(Sub)
+ }
+ if (Sub.options.computed) {
+ initComputed(Sub)
+ }
+
+ // allow further extension/mixin/plugin usage
+ Sub.extend = Super.extend
+ Sub.mixin = Super.mixin
+ Sub.use = Super.use
+
+ // create asset registers, so extended classes
+ // can have their private assets too.
+ ASSET_TYPES.forEach(function (type) {
+ Sub[type] = Super[type]
+ })
+ // enable recursive self-lookup
+ if (name) {
+ Sub.options.components[name] = Sub
+ }
+
+ // keep a reference to the super options at extension time.
+ // later at instantiation we can check if Super's options have
+ // been updated.
+ Sub.superOptions = Super.options
+ Sub.extendOptions = extendOptions
+ Sub.sealedOptions = extend({}, Sub.options)
+
+ // cache constructor
+ cachedCtors[SuperId] = Sub
+ return Sub
+ }
+}
+
+function initProps (Comp) {
+ const props = Comp.options.props
+ for (const key in props) {
+ proxy(Comp.prototype, `_props`, key)
+ }
+}
+
+function initComputed (Comp) {
+ const computed = Comp.options.computed
+ for (const key in computed) {
+ defineComputed(Comp.prototype, key, computed[key])
+ }
+}
diff --git a/node_modules/vue/src/core/global-api/index.js b/node_modules/vue/src/core/global-api/index.js
new file mode 100644
index 00000000..03ffa0fb
--- /dev/null
+++ b/node_modules/vue/src/core/global-api/index.js
@@ -0,0 +1,62 @@
+/* @flow */
+
+import config from '../config'
+import { initUse } from './use'
+import { initMixin } from './mixin'
+import { initExtend } from './extend'
+import { initAssetRegisters } from './assets'
+import { set, del } from '../observer/index'
+import { ASSET_TYPES } from 'shared/constants'
+import builtInComponents from '../components/index'
+
+import {
+ warn,
+ extend,
+ nextTick,
+ mergeOptions,
+ defineReactive
+} from '../util/index'
+
+export function initGlobalAPI (Vue: GlobalAPI) {
+ // config
+ const configDef = {}
+ configDef.get = () => config
+ if (process.env.NODE_ENV !== 'production') {
+ configDef.set = () => {
+ warn(
+ 'Do not replace the Vue.config object, set individual fields instead.'
+ )
+ }
+ }
+ Object.defineProperty(Vue, 'config', configDef)
+
+ // exposed util methods.
+ // NOTE: these are not considered part of the public API - avoid relying on
+ // them unless you are aware of the risk.
+ Vue.util = {
+ warn,
+ extend,
+ mergeOptions,
+ defineReactive
+ }
+
+ Vue.set = set
+ Vue.delete = del
+ Vue.nextTick = nextTick
+
+ Vue.options = Object.create(null)
+ ASSET_TYPES.forEach(type => {
+ Vue.options[type + 's'] = Object.create(null)
+ })
+
+ // this is used to identify the "base" constructor to extend all plain-object
+ // components with in Weex's multi-instance scenarios.
+ Vue.options._base = Vue
+
+ extend(Vue.options.components, builtInComponents)
+
+ initUse(Vue)
+ initMixin(Vue)
+ initExtend(Vue)
+ initAssetRegisters(Vue)
+}
diff --git a/node_modules/vue/src/core/global-api/mixin.js b/node_modules/vue/src/core/global-api/mixin.js
new file mode 100644
index 00000000..36017a32
--- /dev/null
+++ b/node_modules/vue/src/core/global-api/mixin.js
@@ -0,0 +1,10 @@
+/* @flow */
+
+import { mergeOptions } from '../util/index'
+
+export function initMixin (Vue: GlobalAPI) {
+ Vue.mixin = function (mixin: Object) {
+ this.options = mergeOptions(this.options, mixin)
+ return this
+ }
+}
diff --git a/node_modules/vue/src/core/global-api/use.js b/node_modules/vue/src/core/global-api/use.js
new file mode 100644
index 00000000..a5b69988
--- /dev/null
+++ b/node_modules/vue/src/core/global-api/use.js
@@ -0,0 +1,23 @@
+/* @flow */
+
+import { toArray } from '../util/index'
+
+export function initUse (Vue: GlobalAPI) {
+ Vue.use = function (plugin: Function | Object) {
+ const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
+ if (installedPlugins.indexOf(plugin) > -1) {
+ return this
+ }
+
+ // additional parameters
+ const args = toArray(arguments, 1)
+ args.unshift(this)
+ if (typeof plugin.install === 'function') {
+ plugin.install.apply(plugin, args)
+ } else if (typeof plugin === 'function') {
+ plugin.apply(null, args)
+ }
+ installedPlugins.push(plugin)
+ return this
+ }
+}
diff --git a/node_modules/vue/src/core/index.js b/node_modules/vue/src/core/index.js
new file mode 100644
index 00000000..daf6203b
--- /dev/null
+++ b/node_modules/vue/src/core/index.js
@@ -0,0 +1,26 @@
+import Vue from './instance/index'
+import { initGlobalAPI } from './global-api/index'
+import { isServerRendering } from 'core/util/env'
+import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
+
+initGlobalAPI(Vue)
+
+Object.defineProperty(Vue.prototype, '$isServer', {
+ get: isServerRendering
+})
+
+Object.defineProperty(Vue.prototype, '$ssrContext', {
+ get () {
+ /* istanbul ignore next */
+ return this.$vnode && this.$vnode.ssrContext
+ }
+})
+
+// expose FunctionalRenderContext for ssr runtime helper installation
+Object.defineProperty(Vue, 'FunctionalRenderContext', {
+ value: FunctionalRenderContext
+})
+
+Vue.version = '__VERSION__'
+
+export default Vue
diff --git a/node_modules/vue/src/core/instance/events.js b/node_modules/vue/src/core/instance/events.js
new file mode 100644
index 00000000..58779996
--- /dev/null
+++ b/node_modules/vue/src/core/instance/events.js
@@ -0,0 +1,142 @@
+/* @flow */
+
+import {
+ tip,
+ toArray,
+ hyphenate,
+ handleError,
+ formatComponentName
+} from '../util/index'
+import { updateListeners } from '../vdom/helpers/index'
+
+export function initEvents (vm: Component) {
+ vm._events = Object.create(null)
+ vm._hasHookEvent = false
+ // init parent attached events
+ const listeners = vm.$options._parentListeners
+ if (listeners) {
+ updateComponentListeners(vm, listeners)
+ }
+}
+
+let target: any
+
+function add (event, fn, once) {
+ if (once) {
+ target.$once(event, fn)
+ } else {
+ target.$on(event, fn)
+ }
+}
+
+function remove (event, fn) {
+ target.$off(event, fn)
+}
+
+export function updateComponentListeners (
+ vm: Component,
+ listeners: Object,
+ oldListeners: ?Object
+) {
+ target = vm
+ updateListeners(listeners, oldListeners || {}, add, remove, vm)
+ target = undefined
+}
+
+export function eventsMixin (Vue: Class<Component>) {
+ const hookRE = /^hook:/
+ Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component {
+ const vm: Component = this
+ if (Array.isArray(event)) {
+ for (let i = 0, l = event.length; i < l; i++) {
+ this.$on(event[i], fn)
+ }
+ } else {
+ (vm._events[event] || (vm._events[event] = [])).push(fn)
+ // optimize hook:event cost by using a boolean flag marked at registration
+ // instead of a hash lookup
+ if (hookRE.test(event)) {
+ vm._hasHookEvent = true
+ }
+ }
+ return vm
+ }
+
+ Vue.prototype.$once = function (event: string, fn: Function): Component {
+ const vm: Component = this
+ function on () {
+ vm.$off(event, on)
+ fn.apply(vm, arguments)
+ }
+ on.fn = fn
+ vm.$on(event, on)
+ return vm
+ }
+
+ Vue.prototype.$off = function (event?: string | Array<string>, fn?: Function): Component {
+ const vm: Component = this
+ // all
+ if (!arguments.length) {
+ vm._events = Object.create(null)
+ return vm
+ }
+ // array of events
+ if (Array.isArray(event)) {
+ for (let i = 0, l = event.length; i < l; i++) {
+ this.$off(event[i], fn)
+ }
+ return vm
+ }
+ // specific event
+ const cbs = vm._events[event]
+ if (!cbs) {
+ return vm
+ }
+ if (!fn) {
+ vm._events[event] = null
+ return vm
+ }
+ if (fn) {
+ // specific handler
+ let cb
+ let i = cbs.length
+ while (i--) {
+ cb = cbs[i]
+ if (cb === fn || cb.fn === fn) {
+ cbs.splice(i, 1)
+ break
+ }
+ }
+ }
+ return vm
+ }
+
+ Vue.prototype.$emit = function (event: string): Component {
+ const vm: Component = this
+ if (process.env.NODE_ENV !== 'production') {
+ const lowerCaseEvent = event.toLowerCase()
+ if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
+ tip(
+ `Event "${lowerCaseEvent}" is emitted in component ` +
+ `${formatComponentName(vm)} but the handler is registered for "${event}". ` +
+ `Note that HTML attributes are case-insensitive and you cannot use ` +
+ `v-on to listen to camelCase events when using in-DOM templates. ` +
+ `You should probably use "${hyphenate(event)}" instead of "${event}".`
+ )
+ }
+ }
+ let cbs = vm._events[event]
+ if (cbs) {
+ cbs = cbs.length > 1 ? toArray(cbs) : cbs
+ const args = toArray(arguments, 1)
+ for (let i = 0, l = cbs.length; i < l; i++) {
+ try {
+ cbs[i].apply(vm, args)
+ } catch (e) {
+ handleError(e, vm, `event handler for "${event}"`)
+ }
+ }
+ }
+ return vm
+ }
+}
diff --git a/node_modules/vue/src/core/instance/index.js b/node_modules/vue/src/core/instance/index.js
new file mode 100644
index 00000000..8a440231
--- /dev/null
+++ b/node_modules/vue/src/core/instance/index.js
@@ -0,0 +1,23 @@
+import { initMixin } from './init'
+import { stateMixin } from './state'
+import { renderMixin } from './render'
+import { eventsMixin } from './events'
+import { lifecycleMixin } from './lifecycle'
+import { warn } from '../util/index'
+
+function Vue (options) {
+ if (process.env.NODE_ENV !== 'production' &&
+ !(this instanceof Vue)
+ ) {
+ warn('Vue is a constructor and should be called with the `new` keyword')
+ }
+ this._init(options)
+}
+
+initMixin(Vue)
+stateMixin(Vue)
+eventsMixin(Vue)
+lifecycleMixin(Vue)
+renderMixin(Vue)
+
+export default Vue
diff --git a/node_modules/vue/src/core/instance/init.js b/node_modules/vue/src/core/instance/init.js
new file mode 100644
index 00000000..ed2550d0
--- /dev/null
+++ b/node_modules/vue/src/core/instance/init.js
@@ -0,0 +1,150 @@
+/* @flow */
+
+import config from '../config'
+import { initProxy } from './proxy'
+import { initState } from './state'
+import { initRender } from './render'
+import { initEvents } from './events'
+import { mark, measure } from '../util/perf'
+import { initLifecycle, callHook } from './lifecycle'
+import { initProvide, initInjections } from './inject'
+import { extend, mergeOptions, formatComponentName } from '../util/index'
+
+let uid = 0
+
+export function initMixin (Vue: Class<Component>) {
+ Vue.prototype._init = function (options?: Object) {
+ const vm: Component = this
+ // a uid
+ vm._uid = uid++
+
+ let startTag, endTag
+ /* istanbul ignore if */
+ if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
+ startTag = `vue-perf-start:${vm._uid}`
+ endTag = `vue-perf-end:${vm._uid}`
+ mark(startTag)
+ }
+
+ // a flag to avoid this being observed
+ vm._isVue = true
+ // merge options
+ if (options && options._isComponent) {
+ // optimize internal component instantiation
+ // since dynamic options merging is pretty slow, and none of the
+ // internal component options needs special treatment.
+ initInternalComponent(vm, options)
+ } else {
+ vm.$options = mergeOptions(
+ resolveConstructorOptions(vm.constructor),
+ options || {},
+ vm
+ )
+ }
+ /* istanbul ignore else */
+ if (process.env.NODE_ENV !== 'production') {
+ initProxy(vm)
+ } else {
+ vm._renderProxy = vm
+ }
+ // expose real self
+ vm._self = vm
+ initLifecycle(vm)
+ initEvents(vm)
+ initRender(vm)
+ callHook(vm, 'beforeCreate')
+ initInjections(vm) // resolve injections before data/props
+ initState(vm)
+ initProvide(vm) // resolve provide after data/props
+ callHook(vm, 'created')
+
+ /* istanbul ignore if */
+ if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
+ vm._name = formatComponentName(vm, false)
+ mark(endTag)
+ measure(`vue ${vm._name} init`, startTag, endTag)
+ }
+
+ if (vm.$options.el) {
+ vm.$mount(vm.$options.el)
+ }
+ }
+}
+
+export function initInternalComponent (vm: Component, options: InternalComponentOptions) {
+ const opts = vm.$options = Object.create(vm.constructor.options)
+ // doing this because it's faster than dynamic enumeration.
+ const parentVnode = options._parentVnode
+ opts.parent = options.parent
+ opts._parentVnode = parentVnode
+ opts._parentElm = options._parentElm
+ opts._refElm = options._refElm
+
+ const vnodeComponentOptions = parentVnode.componentOptions
+ opts.propsData = vnodeComponentOptions.propsData
+ opts._parentListeners = vnodeComponentOptions.listeners
+ opts._renderChildren = vnodeComponentOptions.children
+ opts._componentTag = vnodeComponentOptions.tag
+
+ if (options.render) {
+ opts.render = options.render
+ opts.staticRenderFns = options.staticRenderFns
+ }
+}
+
+export function resolveConstructorOptions (Ctor: Class<Component>) {
+ let options = Ctor.options
+ if (Ctor.super) {
+ const superOptions = resolveConstructorOptions(Ctor.super)
+ const cachedSuperOptions = Ctor.superOptions
+ if (superOptions !== cachedSuperOptions) {
+ // super option changed,
+ // need to resolve new options.
+ Ctor.superOptions = superOptions
+ // check if there are any late-modified/attached options (#4976)
+ const modifiedOptions = resolveModifiedOptions(Ctor)
+ // update base extend options
+ if (modifiedOptions) {
+ extend(Ctor.extendOptions, modifiedOptions)
+ }
+ options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
+ if (options.name) {
+ options.components[options.name] = Ctor
+ }
+ }
+ }
+ return options
+}
+
+function resolveModifiedOptions (Ctor: Class<Component>): ?Object {
+ let modified
+ const latest = Ctor.options
+ const extended = Ctor.extendOptions
+ const sealed = Ctor.sealedOptions
+ for (const key in latest) {
+ if (latest[key] !== sealed[key]) {
+ if (!modified) modified = {}
+ modified[key] = dedupe(latest[key], extended[key], sealed[key])
+ }
+ }
+ return modified
+}
+
+function dedupe (latest, extended, sealed) {
+ // compare latest and sealed to ensure lifecycle hooks won't be duplicated
+ // between merges
+ if (Array.isArray(latest)) {
+ const res = []
+ sealed = Array.isArray(sealed) ? sealed : [sealed]
+ extended = Array.isArray(extended) ? extended : [extended]
+ for (let i = 0; i < latest.length; i++) {
+ // push original options and not sealed options to exclude duplicated options
+ if (extended.indexOf(latest[i]) >= 0 || sealed.indexOf(latest[i]) < 0) {
+ res.push(latest[i])
+ }
+ }
+ return res
+ } else {
+ return latest
+ }
+}
diff --git a/node_modules/vue/src/core/instance/inject.js b/node_modules/vue/src/core/instance/inject.js
new file mode 100644
index 00000000..e464e12a
--- /dev/null
+++ b/node_modules/vue/src/core/instance/inject.js
@@ -0,0 +1,74 @@
+/* @flow */
+
+import { hasOwn } from 'shared/util'
+import { warn, hasSymbol } from '../util/index'
+import { defineReactive, toggleObserving } from '../observer/index'
+
+export function initProvide (vm: Component) {
+ const provide = vm.$options.provide
+ if (provide) {
+ vm._provided = typeof provide === 'function'
+ ? provide.call(vm)
+ : provide
+ }
+}
+
+export function initInjections (vm: Component) {
+ const result = resolveInject(vm.$options.inject, vm)
+ if (result) {
+ toggleObserving(false)
+ Object.keys(result).forEach(key => {
+ /* istanbul ignore else */
+ if (process.env.NODE_ENV !== 'production') {
+ defineReactive(vm, key, result[key], () => {
+ warn(
+ `Avoid mutating an injected value directly since the changes will be ` +
+ `overwritten whenever the provided component re-renders. ` +
+ `injection being mutated: "${key}"`,
+ vm
+ )
+ })
+ } else {
+ defineReactive(vm, key, result[key])
+ }
+ })
+ toggleObserving(true)
+ }
+}
+
+export function resolveInject (inject: any, vm: Component): ?Object {
+ if (inject) {
+ // inject is :any because flow is not smart enough to figure out cached
+ const result = Object.create(null)
+ const keys = hasSymbol
+ ? Reflect.ownKeys(inject).filter(key => {
+ /* istanbul ignore next */
+ return Object.getOwnPropertyDescriptor(inject, key).enumerable
+ })
+ : Object.keys(inject)
+
+ for (let i = 0; i < keys.length; i++) {
+ const key = keys[i]
+ const provideKey = inject[key].from
+ let source = vm
+ while (source) {
+ if (source._provided && hasOwn(source._provided, provideKey)) {
+ result[key] = source._provided[provideKey]
+ break
+ }
+ source = source.$parent
+ }
+ if (!source) {
+ if ('default' in inject[key]) {
+ const provideDefault = inject[key].default
+ result[key] = typeof provideDefault === 'function'
+ ? provideDefault.call(vm)
+ : provideDefault
+ } else if (process.env.NODE_ENV !== 'production') {
+ warn(`Injection "${key}" not found`, vm)
+ }
+ }
+ }
+ return result
+ }
+}
diff --git a/node_modules/vue/src/core/instance/lifecycle.js b/node_modules/vue/src/core/instance/lifecycle.js
new file mode 100644
index 00000000..169a54a6
--- /dev/null
+++ b/node_modules/vue/src/core/instance/lifecycle.js
@@ -0,0 +1,336 @@
+/* @flow */
+
+import config from '../config'
+import Watcher from '../observer/watcher'
+import { mark, measure } from '../util/perf'
+import { createEmptyVNode } from '../vdom/vnode'
+import { updateComponentListeners } from './events'
+import { resolveSlots } from './render-helpers/resolve-slots'
+import { toggleObserving } from '../observer/index'
+import { pushTarget, popTarget } from '../observer/dep'
+
+import {
+ warn,
+ noop,
+ remove,
+ handleError,
+ emptyObject,
+ validateProp
+} from '../util/index'
+
+export let activeInstance: any = null
+export let isUpdatingChildComponent: boolean = false
+
+export function initLifecycle (vm: Component) {
+ const options = vm.$options
+
+ // locate first non-abstract parent
+ let parent = options.parent
+ if (parent && !options.abstract) {
+ while (parent.$options.abstract && parent.$parent) {
+ parent = parent.$parent
+ }
+ parent.$children.push(vm)
+ }
+
+ vm.$parent = parent
+ vm.$root = parent ? parent.$root : vm
+
+ vm.$children = []
+ vm.$refs = {}
+
+ vm._watcher = null
+ vm._inactive = null
+ vm._directInactive = false
+ vm._isMounted = false
+ vm._isDestroyed = false
+ vm._isBeingDestroyed = false
+}
+
+export function lifecycleMixin (Vue: Class<Component>) {
+ Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
+ const vm: Component = this
+ if (vm._isMounted) {
+ callHook(vm, 'beforeUpdate')
+ }
+ const prevEl = vm.$el
+ const prevVnode = vm._vnode
+ const prevActiveInstance = activeInstance
+ activeInstance = vm
+ vm._vnode = vnode
+ // Vue.prototype.__patch__ is injected in entry points
+ // based on the rendering backend used.
+ if (!prevVnode) {
+ // initial render
+ vm.$el = vm.__patch__(
+ vm.$el, vnode, hydrating, false /* removeOnly */,
+ vm.$options._parentElm,
+ vm.$options._refElm
+ )
+ // no need for the ref nodes after initial patch
+ // this prevents keeping a detached DOM tree in memory (#5851)
+ vm.$options._parentElm = vm.$options._refElm = null
+ } else {
+ // updates
+ vm.$el = vm.__patch__(prevVnode, vnode)
+ }
+ activeInstance = prevActiveInstance
+ // update __vue__ reference
+ if (prevEl) {
+ prevEl.__vue__ = null
+ }
+ if (vm.$el) {
+ vm.$el.__vue__ = vm
+ }
+ // if parent is an HOC, update its $el as well
+ if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
+ vm.$parent.$el = vm.$el
+ }
+ // updated hook is called by the scheduler to ensure that children are
+ // updated in a parent's updated hook.
+ }
+
+ Vue.prototype.$forceUpdate = function () {
+ const vm: Component = this
+ if (vm._watcher) {
+ vm._watcher.update()
+ }
+ }
+
+ Vue.prototype.$destroy = function () {
+ const vm: Component = this
+ if (vm._isBeingDestroyed) {
+ return
+ }
+ callHook(vm, 'beforeDestroy')
+ vm._isBeingDestroyed = true
+ // remove self from parent
+ const parent = vm.$parent
+ if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {
+ remove(parent.$children, vm)
+ }
+ // teardown watchers
+ if (vm._watcher) {
+ vm._watcher.teardown()
+ }
+ let i = vm._watchers.length
+ while (i--) {
+ vm._watchers[i].teardown()
+ }
+ // remove reference from data ob
+ // frozen object may not have observer.
+ if (vm._data.__ob__) {
+ vm._data.__ob__.vmCount--
+ }
+ // call the last hook...
+ vm._isDestroyed = true
+ // invoke destroy hooks on current rendered tree
+ vm.__patch__(vm._vnode, null)
+ // fire destroyed hook
+ callHook(vm, 'destroyed')
+ // turn off all instance listeners.
+ vm.$off()
+ // remove __vue__ reference
+ if (vm.$el) {
+ vm.$el.__vue__ = null
+ }
+ // release circular reference (#6759)
+ if (vm.$vnode) {
+ vm.$vnode.parent = null
+ }
+ }
+}
+
+export function mountComponent (
+ vm: Component,
+ el: ?Element,
+ hydrating?: boolean
+): Component {
+ vm.$el = el
+ if (!vm.$options.render) {
+ vm.$options.render = createEmptyVNode
+ if (process.env.NODE_ENV !== 'production') {
+ /* istanbul ignore if */
+ if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||
+ vm.$options.el || el) {
+ warn(
+ 'You are using the runtime-only build of Vue where the template ' +
+ 'compiler is not available. Either pre-compile the templates into ' +
+ 'render functions, or use the compiler-included build.',
+ vm
+ )
+ } else {
+ warn(
+ 'Failed to mount component: template or render function not defined.',
+ vm
+ )
+ }
+ }
+ }
+ callHook(vm, 'beforeMount')
+
+ let updateComponent
+ /* istanbul ignore if */
+ if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
+ updateComponent = () => {
+ const name = vm._name
+ const id = vm._uid
+ const startTag = `vue-perf-start:${id}`
+ const endTag = `vue-perf-end:${id}`
+
+ mark(startTag)
+ const vnode = vm._render()
+ mark(endTag)
+ measure(`vue ${name} render`, startTag, endTag)
+
+ mark(startTag)
+ vm._update(vnode, hydrating)
+ mark(endTag)
+ measure(`vue ${name} patch`, startTag, endTag)
+ }
+ } else {
+ updateComponent = () => {
+ vm._update(vm._render(), hydrating)
+ }
+ }
+
+ // we set this to vm._watcher inside the watcher's constructor
+ // since the watcher's initial patch may call $forceUpdate (e.g. inside child
+ // component's mounted hook), which relies on vm._watcher being already defined
+ new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */)
+ hydrating = false
+
+ // manually mounted instance, call mounted on self
+ // mounted is called for render-created child components in its inserted hook
+ if (vm.$vnode == null) {
+ vm._isMounted = true
+ callHook(vm, 'mounted')
+ }
+ return vm
+}
+
+export function updateChildComponent (
+ vm: Component,
+ propsData: ?Object,
+ listeners: ?Object,
+ parentVnode: MountedComponentVNode,
+ renderChildren: ?Array<VNode>
+) {
+ if (process.env.NODE_ENV !== 'production') {
+ isUpdatingChildComponent = true
+ }
+
+ // determine whether component has slot children
+ // we need to do this before overwriting $options._renderChildren
+ const hasChildren = !!(
+ renderChildren || // has new static slots
+ vm.$options._renderChildren || // has old static slots
+ parentVnode.data.scopedSlots || // has new scoped slots
+ vm.$scopedSlots !== emptyObject // has old scoped slots
+ )
+
+ vm.$options._parentVnode = parentVnode
+ vm.$vnode = parentVnode // update vm's placeholder node without re-render
+
+ if (vm._vnode) { // update child tree's parent
+ vm._vnode.parent = parentVnode
+ }
+ vm.$options._renderChildren = renderChildren
+
+ // update $attrs and $listeners hash
+ // these are also reactive so they may trigger child update if the child
+ // used them during render
+ vm.$attrs = parentVnode.data.attrs || emptyObject
+ vm.$listeners = listeners || emptyObject
+
+ // update props
+ if (propsData && vm.$options.props) {
+ toggleObserving(false)
+ const props = vm._props
+ const propKeys = vm.$options._propKeys || []
+ for (let i = 0; i < propKeys.length; i++) {
+ const key = propKeys[i]
+ const propOptions: any = vm.$options.props // wtf flow?
+ props[key] = validateProp(key, propOptions, propsData, vm)
+ }
+ toggleObserving(true)
+ // keep a copy of raw propsData
+ vm.$options.propsData = propsData
+ }
+
+ // update listeners
+ listeners = listeners || emptyObject
+ const oldListeners = vm.$options._parentListeners
+ vm.$options._parentListeners = listeners
+ updateComponentListeners(vm, listeners, oldListeners)
+
+ // resolve slots + force update if has children
+ if (hasChildren) {
+ vm.$slots = resolveSlots(renderChildren, parentVnode.context)
+ vm.$forceUpdate()
+ }
+
+ if (process.env.NODE_ENV !== 'production') {
+ isUpdatingChildComponent = false
+ }
+}
+
+function isInInactiveTree (vm) {
+ while (vm && (vm = vm.$parent)) {
+ if (vm._inactive) return true
+ }
+ return false
+}
+
+export function activateChildComponent (vm: Component, direct?: boolean) {
+ if (direct) {
+ vm._directInactive = false
+ if (isInInactiveTree(vm)) {
+ return
+ }
+ } else if (vm._directInactive) {
+ return
+ }
+ if (vm._inactive || vm._inactive === null) {
+ vm._inactive = false
+ for (let i = 0; i < vm.$children.length; i++) {
+ activateChildComponent(vm.$children[i])
+ }
+ callHook(vm, 'activated')
+ }
+}
+
+export function deactivateChildComponent (vm: Component, direct?: boolean) {
+ if (direct) {
+ vm._directInactive = true
+ if (isInInactiveTree(vm)) {
+ return
+ }
+ }
+ if (!vm._inactive) {
+ vm._inactive = true
+ for (let i = 0; i < vm.$children.length; i++) {
+ deactivateChildComponent(vm.$children[i])
+ }
+ callHook(vm, 'deactivated')
+ }
+}
+
+export function callHook (vm: Component, hook: string) {
+ // #7573 disable dep collection when invoking lifecycle hooks
+ pushTarget()
+ const handlers = vm.$options[hook]
+ if (handlers) {
+ for (let i = 0, j = handlers.length; i < j; i++) {
+ try {
+ handlers[i].call(vm)
+ } catch (e) {
+ handleError(e, vm, `${hook} hook`)
+ }
+ }
+ }
+ if (vm._hasHookEvent) {
+ vm.$emit('hook:' + hook)
+ }
+ popTarget()
+}
diff --git a/node_modules/vue/src/core/instance/proxy.js b/node_modules/vue/src/core/instance/proxy.js
new file mode 100644
index 00000000..0d6dcf80
--- /dev/null
+++ b/node_modules/vue/src/core/instance/proxy.js
@@ -0,0 +1,79 @@
+/* not type checking this file because flow doesn't play well with Proxy */
+
+import config from 'core/config'
+import { warn, makeMap, isNative } from '../util/index'
+
+let initProxy
+
+if (process.env.NODE_ENV !== 'production') {
+ const allowedGlobals = makeMap(
+ 'Infinity,undefined,NaN,isFinite,isNaN,' +
+ 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
+ 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
+ 'require' // for Webpack/Browserify
+ )
+
+ const warnNonPresent = (target, key) => {
+ warn(
+ `Property or method "${key}" is not defined on the instance but ` +
+ 'referenced during render. Make sure that this property is reactive, ' +
+ 'either in the data option, or for class-based components, by ' +
+ 'initializing the property. ' +
+ 'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
+ target
+ )
+ }
+
+ const hasProxy =
+ typeof Proxy !== 'undefined' && isNative(Proxy)
+
+ if (hasProxy) {
+ const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact')
+ config.keyCodes = new Proxy(config.keyCodes, {
+ set (target, key, value) {
+ if (isBuiltInModifier(key)) {
+ warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`)
+ return false
+ } else {
+ target[key] = value
+ return true
+ }
+ }
+ })
+ }
+
+ const hasHandler = {
+ has (target, key) {
+ const has = key in target
+ const isAllowed = allowedGlobals(key) || key.charAt(0) === '_'
+ if (!has && !isAllowed) {
+ warnNonPresent(target, key)
+ }
+ return has || !isAllowed
+ }
+ }
+
+ const getHandler = {
+ get (target, key) {
+ if (typeof key === 'string' && !(key in target)) {
+ warnNonPresent(target, key)
+ }
+ return target[key]
+ }
+ }
+
+ initProxy = function initProxy (vm) {
+ if (hasProxy) {
+ // determine which proxy handler to use
+ const options = vm.$options
+ const handlers = options.render && options.render._withStripped
+ ? getHandler
+ : hasHandler
+ vm._renderProxy = new Proxy(vm, handlers)
+ } else {
+ vm._renderProxy = vm
+ }
+ }
+}
+
+export { initProxy }
diff --git a/node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js b/node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js
new file mode 100644
index 00000000..5bfc7514
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js
@@ -0,0 +1,22 @@
+/* @flow */
+
+import { warn, extend, isPlainObject } from 'core/util/index'
+
+export function bindObjectListeners (data: any, value: any): VNodeData {
+ if (value) {
+ if (!isPlainObject(value)) {
+ process.env.NODE_ENV !== 'production' && warn(
+ 'v-on without argument expects an Object value',
+ this
+ )
+ } else {
+ const on = data.on = data.on ? extend({}, data.on) : {}
+ for (const key in value) {
+ const existing = on[key]
+ const ours = value[key]
+ on[key] = existing ? [].concat(existing, ours) : ours
+ }
+ }
+ }
+ return data
+}
diff --git a/node_modules/vue/src/core/instance/render-helpers/bind-object-props.js b/node_modules/vue/src/core/instance/render-helpers/bind-object-props.js
new file mode 100644
index 00000000..c71dce5c
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render-helpers/bind-object-props.js
@@ -0,0 +1,60 @@
+/* @flow */
+
+import config from 'core/config'
+
+import {
+ warn,
+ isObject,
+ toObject,
+ isReservedAttribute
+} from 'core/util/index'
+
+/**
+ * Runtime helper for merging v-bind="object" into a VNode's data.
+ */
+export function bindObjectProps (
+ data: any,
+ tag: string,
+ value: any,
+ asProp: boolean,
+ isSync?: boolean
+): VNodeData {
+ if (value) {
+ if (!isObject(value)) {
+ process.env.NODE_ENV !== 'production' && warn(
+ 'v-bind without argument expects an Object or Array value',
+ this
+ )
+ } else {
+ if (Array.isArray(value)) {
+ value = toObject(value)
+ }
+ let hash
+ for (const key in value) {
+ if (
+ key === 'class' ||
+ key === 'style' ||
+ isReservedAttribute(key)
+ ) {
+ hash = data
+ } else {
+ const type = data.attrs && data.attrs.type
+ hash = asProp || config.mustUseProp(tag, type, key)
+ ? data.domProps || (data.domProps = {})
+ : data.attrs || (data.attrs = {})
+ }
+ if (!(key in hash)) {
+ hash[key] = value[key]
+
+ if (isSync) {
+ const on = data.on || (data.on = {})
+ on[`update:${key}`] = function ($event) {
+ value[key] = $event
+ }
+ }
+ }
+ }
+ }
+ }
+ return data
+}
diff --git a/node_modules/vue/src/core/instance/render-helpers/check-keycodes.js b/node_modules/vue/src/core/instance/render-helpers/check-keycodes.js
new file mode 100644
index 00000000..c12402b1
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render-helpers/check-keycodes.js
@@ -0,0 +1,34 @@
+/* @flow */
+
+import config from 'core/config'
+import { hyphenate } from 'shared/util'
+
+function isKeyNotMatch<T> (expect: T | Array<T>, actual: T): boolean {
+ if (Array.isArray(expect)) {
+ return expect.indexOf(actual) === -1
+ } else {
+ return expect !== actual
+ }
+}
+
+/**
+ * Runtime helper for checking keyCodes from config.
+ * exposed as Vue.prototype._k
+ * passing in eventKeyName as last argument separately for backwards compat
+ */
+export function checkKeyCodes (
+ eventKeyCode: number,
+ key: string,
+ builtInKeyCode?: number | Array<number>,
+ eventKeyName?: string,
+ builtInKeyName?: string | Array<string>
+): ?boolean {
+ const mappedKeyCode = config.keyCodes[key] || builtInKeyCode
+ if (builtInKeyName && eventKeyName && !config.keyCodes[key]) {
+ return isKeyNotMatch(builtInKeyName, eventKeyName)
+ } else if (mappedKeyCode) {
+ return isKeyNotMatch(mappedKeyCode, eventKeyCode)
+ } else if (eventKeyName) {
+ return hyphenate(eventKeyName) !== key
+ }
+}
diff --git a/node_modules/vue/src/core/instance/render-helpers/index.js b/node_modules/vue/src/core/instance/render-helpers/index.js
new file mode 100644
index 00000000..38414a9a
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render-helpers/index.js
@@ -0,0 +1,30 @@
+/* @flow */
+
+import { toNumber, toString, looseEqual, looseIndexOf } from 'shared/util'
+import { createTextVNode, createEmptyVNode } from 'core/vdom/vnode'
+import { renderList } from './render-list'
+import { renderSlot } from './render-slot'
+import { resolveFilter } from './resolve-filter'
+import { checkKeyCodes } from './check-keycodes'
+import { bindObjectProps } from './bind-object-props'
+import { renderStatic, markOnce } from './render-static'
+import { bindObjectListeners } from './bind-object-listeners'
+import { resolveScopedSlots } from './resolve-slots'
+
+export function installRenderHelpers (target: any) {
+ target._o = markOnce
+ target._n = toNumber
+ target._s = toString
+ target._l = renderList
+ target._t = renderSlot
+ target._q = looseEqual
+ target._i = looseIndexOf
+ target._m = renderStatic
+ target._f = resolveFilter
+ target._k = checkKeyCodes
+ target._b = bindObjectProps
+ target._v = createTextVNode
+ target._e = createEmptyVNode
+ target._u = resolveScopedSlots
+ target._g = bindObjectListeners
+}
diff --git a/node_modules/vue/src/core/instance/render-helpers/render-list.js b/node_modules/vue/src/core/instance/render-helpers/render-list.js
new file mode 100644
index 00000000..abe99db4
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render-helpers/render-list.js
@@ -0,0 +1,39 @@
+/* @flow */
+
+import { isObject, isDef } from 'core/util/index'
+
+/**
+ * Runtime helper for rendering v-for lists.
+ */
+export function renderList (
+ val: any,
+ render: (
+ val: any,
+ keyOrIndex: string | number,
+ index?: number
+ ) => VNode
+): ?Array<VNode> {
+ let ret: ?Array<VNode>, i, l, keys, key
+ if (Array.isArray(val) || typeof val === 'string') {
+ ret = new Array(val.length)
+ for (i = 0, l = val.length; i < l; i++) {
+ ret[i] = render(val[i], i)
+ }
+ } else if (typeof val === 'number') {
+ ret = new Array(val)
+ for (i = 0; i < val; i++) {
+ ret[i] = render(i + 1, i)
+ }
+ } else if (isObject(val)) {
+ keys = Object.keys(val)
+ ret = new Array(keys.length)
+ for (i = 0, l = keys.length; i < l; i++) {
+ key = keys[i]
+ ret[i] = render(val[key], key, i)
+ }
+ }
+ if (isDef(ret)) {
+ (ret: any)._isVList = true
+ }
+ return ret
+}
diff --git a/node_modules/vue/src/core/instance/render-helpers/render-slot.js b/node_modules/vue/src/core/instance/render-helpers/render-slot.js
new file mode 100644
index 00000000..a58daa74
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render-helpers/render-slot.js
@@ -0,0 +1,50 @@
+/* @flow */
+
+import { extend, warn, isObject } from 'core/util/index'
+
+/**
+ * Runtime helper for rendering <slot>
+ */
+export function renderSlot (
+ name: string,
+ fallback: ?Array<VNode>,
+ props: ?Object,
+ bindObject: ?Object
+): ?Array<VNode> {
+ const scopedSlotFn = this.$scopedSlots[name]
+ let nodes
+ if (scopedSlotFn) { // scoped slot
+ props = props || {}
+ if (bindObject) {
+ if (process.env.NODE_ENV !== 'production' && !isObject(bindObject)) {
+ warn(
+ 'slot v-bind without argument expects an Object',
+ this
+ )
+ }
+ props = extend(extend({}, bindObject), props)
+ }
+ nodes = scopedSlotFn(props) || fallback
+ } else {
+ const slotNodes = this.$slots[name]
+ // warn duplicate slot usage
+ if (slotNodes) {
+ if (process.env.NODE_ENV !== 'production' && slotNodes._rendered) {
+ warn(
+ `Duplicate presence of slot "${name}" found in the same render tree ` +
+ `- this will likely cause render errors.`,
+ this
+ )
+ }
+ slotNodes._rendered = true
+ }
+ nodes = slotNodes || fallback
+ }
+
+ const target = props && props.slot
+ if (target) {
+ return this.$createElement('template', { slot: target }, nodes)
+ } else {
+ return nodes
+ }
+}
diff --git a/node_modules/vue/src/core/instance/render-helpers/render-static.js b/node_modules/vue/src/core/instance/render-helpers/render-static.js
new file mode 100644
index 00000000..f56510b3
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render-helpers/render-static.js
@@ -0,0 +1,60 @@
+/* @flow */
+
+/**
+ * Runtime helper for rendering static trees.
+ */
+export function renderStatic (
+ index: number,
+ isInFor: boolean
+): VNode | Array<VNode> {
+ const cached = this._staticTrees || (this._staticTrees = [])
+ let tree = cached[index]
+ // if has already-rendered static tree and not inside v-for,
+ // we can reuse the same tree.
+ if (tree && !isInFor) {
+ return tree
+ }
+ // otherwise, render a fresh tree.
+ tree = cached[index] = this.$options.staticRenderFns[index].call(
+ this._renderProxy,
+ null,
+ this // for render fns generated for functional component templates
+ )
+ markStatic(tree, `__static__${index}`, false)
+ return tree
+}
+
+/**
+ * Runtime helper for v-once.
+ * Effectively it means marking the node as static with a unique key.
+ */
+export function markOnce (
+ tree: VNode | Array<VNode>,
+ index: number,
+ key: string
+) {
+ markStatic(tree, `__once__${index}${key ? `_${key}` : ``}`, true)
+ return tree
+}
+
+function markStatic (
+ tree: VNode | Array<VNode>,
+ key: string,
+ isOnce: boolean
+) {
+ if (Array.isArray(tree)) {
+ for (let i = 0; i < tree.length; i++) {
+ if (tree[i] && typeof tree[i] !== 'string') {
+ markStaticNode(tree[i], `${key}_${i}`, isOnce)
+ }
+ }
+ } else {
+ markStaticNode(tree, key, isOnce)
+ }
+}
+
+function markStaticNode (node, key, isOnce) {
+ node.isStatic = true
+ node.key = key
+ node.isOnce = isOnce
+}
diff --git a/node_modules/vue/src/core/instance/render-helpers/resolve-filter.js b/node_modules/vue/src/core/instance/render-helpers/resolve-filter.js
new file mode 100644
index 00000000..08a81e14
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render-helpers/resolve-filter.js
@@ -0,0 +1,10 @@
+/* @flow */
+
+import { identity, resolveAsset } from 'core/util/index'
+
+/**
+ * Runtime helper for resolving filters
+ */
+export function resolveFilter (id: string): Function {
+ return resolveAsset(this.$options, 'filters', id, true) || identity
+}
diff --git a/node_modules/vue/src/core/instance/render-helpers/resolve-slots.js b/node_modules/vue/src/core/instance/render-helpers/resolve-slots.js
new file mode 100644
index 00000000..02f007cf
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render-helpers/resolve-slots.js
@@ -0,0 +1,65 @@
+/* @flow */
+
+import type VNode from 'core/vdom/vnode'
+
+/**
+ * Runtime helper for resolving raw children VNodes into a slot object.
+ */
+export function resolveSlots (
+ children: ?Array<VNode>,
+ context: ?Component
+): { [key: string]: Array<VNode> } {
+ const slots = {}
+ if (!children) {
+ return slots
+ }
+ for (let i = 0, l = children.length; i < l; i++) {
+ const child = children[i]
+ const data = child.data
+ // remove slot attribute if the node is resolved as a Vue slot node
+ if (data && data.attrs && data.attrs.slot) {
+ delete data.attrs.slot
+ }
+ // named slots should only be respected if the vnode was rendered in the
+ // same context.
+ if ((child.context === context || child.fnContext === context) &&
+ data && data.slot != null
+ ) {
+ const name = data.slot
+ const slot = (slots[name] || (slots[name] = []))
+ if (child.tag === 'template') {
+ slot.push.apply(slot, child.children || [])
+ } else {
+ slot.push(child)
+ }
+ } else {
+ (slots.default || (slots.default = [])).push(child)
+ }
+ }
+ // ignore slots that contains only whitespace
+ for (const name in slots) {
+ if (slots[name].every(isWhitespace)) {
+ delete slots[name]
+ }
+ }
+ return slots
+}
+
+function isWhitespace (node: VNode): boolean {
+ return (node.isComment && !node.asyncFactory) || node.text === ' '
+}
+
+export function resolveScopedSlots (
+ fns: ScopedSlotsData, // see flow/vnode
+ res?: Object
+): { [key: string]: Function } {
+ res = res || {}
+ for (let i = 0; i < fns.length; i++) {
+ if (Array.isArray(fns[i])) {
+ resolveScopedSlots(fns[i], res)
+ } else {
+ res[fns[i].key] = fns[i].fn
+ }
+ }
+ return res
+}
diff --git a/node_modules/vue/src/core/instance/render.js b/node_modules/vue/src/core/instance/render.js
new file mode 100644
index 00000000..70fb2c0e
--- /dev/null
+++ b/node_modules/vue/src/core/instance/render.js
@@ -0,0 +1,119 @@
+/* @flow */
+
+import {
+ warn,
+ nextTick,
+ emptyObject,
+ handleError,
+ defineReactive
+} from '../util/index'
+
+import { createElement } from '../vdom/create-element'
+import { installRenderHelpers } from './render-helpers/index'
+import { resolveSlots } from './render-helpers/resolve-slots'
+import VNode, { createEmptyVNode } from '../vdom/vnode'
+
+import { isUpdatingChildComponent } from './lifecycle'
+
+export function initRender (vm: Component) {
+ vm._vnode = null // the root of the child tree
+ vm._staticTrees = null // v-once cached trees
+ const options = vm.$options
+ const parentVnode = vm.$vnode = options._parentVnode // the placeholder node in parent tree
+ const renderContext = parentVnode && parentVnode.context
+ vm.$slots = resolveSlots(options._renderChildren, renderContext)
+ vm.$scopedSlots = emptyObject
+ // bind the createElement fn to this instance
+ // so that we get proper render context inside it.
+ // args order: tag, data, children, normalizationType, alwaysNormalize
+ // internal version is used by render functions compiled from templates
+ vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
+ // normalization is always applied for the public version, used in
+ // user-written render functions.
+ vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
+
+ // $attrs & $listeners are exposed for easier HOC creation.
+ // they need to be reactive so that HOCs using them are always updated
+ const parentData = parentVnode && parentVnode.data
+
+ /* istanbul ignore else */
+ if (process.env.NODE_ENV !== 'production') {
+ defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, () => {
+ !isUpdatingChildComponent && warn(`$attrs is readonly.`, vm)
+ }, true)
+ defineReactive(vm, '$listeners', options._parentListeners || emptyObject, () => {
+ !isUpdatingChildComponent && warn(`$listeners is readonly.`, vm)
+ }, true)
+ } else {
+ defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true)
+ defineReactive(vm, '$listeners', options._parentListeners || emptyObject, null, true)
+ }
+}
+
+export function renderMixin (Vue: Class<Component>) {
+ // install runtime convenience helpers
+ installRenderHelpers(Vue.prototype)
+
+ Vue.prototype.$nextTick = function (fn: Function) {
+ return nextTick(fn, this)
+ }
+
+ Vue.prototype._render = function (): VNode {
+ const vm: Component = this
+ const { render, _parentVnode } = vm.$options
+
+ // reset _rendered flag on slots for duplicate slot check
+ if (process.env.NODE_ENV !== 'production') {
+ for (const key in vm.$slots) {
+ // $flow-disable-line
+ vm.$slots[key]._rendered = false
+ }
+ }
+
+ if (_parentVnode) {
+ vm.$scopedSlots = _parentVnode.data.scopedSlots || emptyObject
+ }
+
+ // set parent vnode. this allows render functions to have access
+ // to the data on the placeholder node.
+ vm.$vnode = _parentVnode
+ // render self
+ let vnode
+ try {
+ vnode = render.call(vm._renderProxy, vm.$createElement)
+ } catch (e) {
+ handleError(e, vm, `render`)
+ // return error render result,
+ // or previous vnode to prevent render error causing blank component
+ /* istanbul ignore else */
+ if (process.env.NODE_ENV !== 'production') {
+ if (vm.$options.renderError) {
+ try {
+ vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e)
+ } catch (e) {
+ handleError(e, vm, `renderError`)
+ vnode = vm._vnode
+ }
+ } else {
+ vnode = vm._vnode
+ }
+ } else {
+ vnode = vm._vnode
+ }
+ }
+ // return empty vnode in case the render function errored out
+ if (!(vnode instanceof VNode)) {
+ if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) {
+ warn(
+ 'Multiple root nodes returned from render function. Render function ' +
+ 'should return a single root node.',
+ vm
+ )
+ }
+ vnode = createEmptyVNode()
+ }
+ // set parent
+ vnode.parent = _parentVnode
+ return vnode
+ }
+}
diff --git a/node_modules/vue/src/core/instance/state.js b/node_modules/vue/src/core/instance/state.js
new file mode 100644
index 00000000..b1549b0d
--- /dev/null
+++ b/node_modules/vue/src/core/instance/state.js
@@ -0,0 +1,360 @@
+/* @flow */
+
+import config from '../config'
+import Watcher from '../observer/watcher'
+import Dep, { pushTarget, popTarget } from '../observer/dep'
+import { isUpdatingChildComponent } from './lifecycle'
+
+import {
+ set,
+ del,
+ observe,
+ defineReactive,
+ toggleObserving
+} from '../observer/index'
+
+import {
+ warn,
+ bind,
+ noop,
+ hasOwn,
+ hyphenate,
+ isReserved,
+ handleError,
+ nativeWatch,
+ validateProp,
+ isPlainObject,
+ isServerRendering,
+ isReservedAttribute
+} from '../util/index'
+
+const sharedPropertyDefinition = {
+ enumerable: true,
+ configurable: true,
+ get: noop,
+ set: noop
+}
+
+export function proxy (target: Object, sourceKey: string, key: string) {
+ sharedPropertyDefinition.get = function proxyGetter () {
+ return this[sourceKey][key]
+ }
+ sharedPropertyDefinition.set = function proxySetter (val) {
+ this[sourceKey][key] = val
+ }
+ Object.defineProperty(target, key, sharedPropertyDefinition)
+}
+
+export function initState (vm: Component) {
+ vm._watchers = []
+ const opts = vm.$options
+ if (opts.props) initProps(vm, opts.props)
+ if (opts.methods) initMethods(vm, opts.methods)
+ if (opts.data) {
+ initData(vm)
+ } else {
+ observe(vm._data = {}, true /* asRootData */)
+ }
+ if (opts.computed) initComputed(vm, opts.computed)
+ if (opts.watch && opts.watch !== nativeWatch) {
+ initWatch(vm, opts.watch)
+ }
+}
+
+function initProps (vm: Component, propsOptions: Object) {
+ const propsData = vm.$options.propsData || {}
+ const props = vm._props = {}
+ // cache prop keys so that future props updates can iterate using Array
+ // instead of dynamic object key enumeration.
+ const keys = vm.$options._propKeys = []
+ const isRoot = !vm.$parent
+ // root instance props should be converted
+ if (!isRoot) {
+ toggleObserving(false)
+ }
+ for (const key in propsOptions) {
+ keys.push(key)
+ const value = validateProp(key, propsOptions, propsData, vm)
+ /* istanbul ignore else */
+ if (process.env.NODE_ENV !== 'production') {
+ const hyphenatedKey = hyphenate(key)
+ if (isReservedAttribute(hyphenatedKey) ||
+ config.isReservedAttr(hyphenatedKey)) {
+ warn(
+ `"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`,
+ vm
+ )
+ }
+ defineReactive(props, key, value, () => {
+ if (vm.$parent && !isUpdatingChildComponent) {
+ warn(
+ `Avoid mutating a prop directly since the value will be ` +
+ `overwritten whenever the parent component re-renders. ` +
+ `Instead, use a data or computed property based on the prop's ` +
+ `value. Prop being mutated: "${key}"`,
+ vm
+ )
+ }
+ })
+ } else {
+ defineReactive(props, key, value)
+ }
+ // static props are already proxied on the component's prototype
+ // during Vue.extend(). We only need to proxy props defined at
+ // instantiation here.
+ if (!(key in vm)) {
+ proxy(vm, `_props`, key)
+ }
+ }
+ toggleObserving(true)
+}
+
+function initData (vm: Component) {
+ let data = vm.$options.data
+ data = vm._data = typeof data === 'function'
+ ? getData(data, vm)
+ : data || {}
+ if (!isPlainObject(data)) {
+ data = {}
+ process.env.NODE_ENV !== 'production' && warn(
+ 'data functions should return an object:\n' +
+ 'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
+ vm
+ )
+ }
+ // proxy data on instance
+ const keys = Object.keys(data)
+ const props = vm.$options.props
+ const methods = vm.$options.methods
+ let i = keys.length
+ while (i--) {
+ const key = keys[i]
+ if (process.env.NODE_ENV !== 'production') {
+ if (methods && hasOwn(methods, key)) {
+ warn(
+ `Method "${key}" has already been defined as a data property.`,
+ vm
+ )
+ }
+ }
+ if (props && hasOwn(props, key)) {
+ process.env.NODE_ENV !== 'production' && warn(
+ `The data property "${key}" is already declared as a prop. ` +
+ `Use prop default value instead.`,
+ vm
+ )
+ } else if (!isReserved(key)) {
+ proxy(vm, `_data`, key)
+ }
+ }
+ // observe data
+ observe(data, true /* asRootData */)
+}
+
+export function getData (data: Function, vm: Component): any {
+ // #7573 disable dep collection when invoking data getters
+ pushTarget()
+ try {
+ return data.call(vm, vm)
+ } catch (e) {
+ handleError(e, vm, `data()`)
+ return {}
+ } finally {
+ popTarget()
+ }
+}
+
+const computedWatcherOptions = { lazy: true }
+
+function initComputed (vm: Component, computed: Object) {
+ // $flow-disable-line
+ const watchers = vm._computedWatchers = Object.create(null)
+ // computed properties are just getters during SSR
+ const isSSR = isServerRendering()
+
+ for (const key in computed) {
+ const userDef = computed[key]
+ const getter = typeof userDef === 'function' ? userDef : userDef.get
+ if (process.env.NODE_ENV !== 'production' && getter == null) {
+ warn(
+ `Getter is missing for computed property "${key}".`,
+ vm
+ )
+ }
+
+ if (!isSSR) {
+ // create internal watcher for the computed property.
+ watchers[key] = new Watcher(
+ vm,
+ getter || noop,
+ noop,
+ computedWatcherOptions
+ )
+ }
+
+ // component-defined computed properties are already defined on the
+ // component prototype. We only need to define computed properties defined
+ // at instantiation here.
+ if (!(key in vm)) {
+ defineComputed(vm, key, userDef)
+ } else if (process.env.NODE_ENV !== 'production') {
+ if (key in vm.$data) {
+ warn(`The computed property "${key}" is already defined in data.`, vm)
+ } else if (vm.$options.props && key in vm.$options.props) {
+ warn(`The computed property "${key}" is already defined as a prop.`, vm)
+ }
+ }
+ }
+}
+
+export function defineComputed (
+ target: any,
+ key: string,
+ userDef: Object | Function
+) {
+ const shouldCache = !isServerRendering()
+ if (typeof userDef === 'function') {
+ sharedPropertyDefinition.get = shouldCache
+ ? createComputedGetter(key)
+ : userDef
+ sharedPropertyDefinition.set = noop
+ } else {
+ sharedPropertyDefinition.get = userDef.get
+ ? shouldCache && userDef.cache !== false
+ ? createComputedGetter(key)
+ : userDef.get
+ : noop
+ sharedPropertyDefinition.set = userDef.set
+ ? userDef.set
+ : noop
+ }
+ if (process.env.NODE_ENV !== 'production' &&
+ sharedPropertyDefinition.set === noop) {
+ sharedPropertyDefinition.set = function () {
+ warn(
+ `Computed property "${key}" was assigned to but it has no setter.`,
+ this
+ )
+ }
+ }
+ Object.defineProperty(target, key, sharedPropertyDefinition)
+}
+
+function createComputedGetter (key) {
+ return function computedGetter () {
+ const watcher = this._computedWatchers && this._computedWatchers[key]
+ if (watcher) {
+ if (watcher.dirty) {
+ watcher.evaluate()
+ }
+ if (Dep.target) {
+ watcher.depend()
+ }
+ return watcher.value
+ }
+ }
+}
+
+function initMethods (vm: Component, methods: Object) {
+ const props = vm.$options.props
+ for (const key in methods) {
+ if (process.env.NODE_ENV !== 'production') {
+ if (methods[key] == null) {
+ warn(
+ `Method "${key}" has an undefined value in the component definition. ` +
+ `Did you reference the function correctly?`,
+ vm
+ )
+ }
+ if (props && hasOwn(props, key)) {
+ warn(
+ `Method "${key}" has already been defined as a prop.`,
+ vm
+ )
+ }
+ if ((key in vm) && isReserved(key)) {
+ warn(
+ `Method "${key}" conflicts with an existing Vue instance method. ` +
+ `Avoid defining component methods that start with _ or $.`
+ )
+ }
+ }
+ vm[key] = methods[key] == null ? noop : bind(methods[key], vm)
+ }
+}
+
+function initWatch (vm: Component, watch: Object) {
+ for (const key in watch) {
+ const handler = watch[key]
+ if (Array.isArray(handler)) {
+ for (let i = 0; i < handler.length; i++) {
+ createWatcher(vm, key, handler[i])
+ }
+ } else {
+ createWatcher(vm, key, handler)
+ }
+ }
+}
+
+function createWatcher (
+ vm: Component,
+ expOrFn: string | Function,
+ handler: any,
+ options?: Object
+) {
+ if (isPlainObject(handler)) {
+ options = handler
+ handler = handler.handler
+ }
+ if (typeof handler === 'string') {
+ handler = vm[handler]
+ }
+ return vm.$watch(expOrFn, handler, options)
+}
+
+export function stateMixin (Vue: Class<Component>) {
+ // flow somehow has problems with directly declared definition object
+ // when using Object.defineProperty, so we have to procedurally build up
+ // the object here.
+ const dataDef = {}
+ dataDef.get = function () { return this._data }
+ const propsDef = {}
+ propsDef.get = function () { return this._props }
+ if (process.env.NODE_ENV !== 'production') {
+ dataDef.set = function (newData: Object) {
+ warn(
+ 'Avoid replacing instance root $data. ' +
+ 'Use nested data properties instead.',
+ this
+ )
+ }
+ propsDef.set = function () {
+ warn(`$props is readonly.`, this)
+ }
+ }
+ Object.defineProperty(Vue.prototype, '$data', dataDef)
+ Object.defineProperty(Vue.prototype, '$props', propsDef)
+
+ Vue.prototype.$set = set
+ Vue.prototype.$delete = del
+
+ Vue.prototype.$watch = function (
+ expOrFn: string | Function,
+ cb: any,
+ options?: Object
+ ): Function {
+ const vm: Component = this
+ if (isPlainObject(cb)) {
+ return createWatcher(vm, expOrFn, cb, options)
+ }
+ options = options || {}
+ options.user = true
+ const watcher = new Watcher(vm, expOrFn, cb, options)
+ if (options.immediate) {
+ cb.call(vm, watcher.value)
+ }
+ return function unwatchFn () {
+ watcher.teardown()
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/observer/array.js b/node_modules/vue/src/core/observer/array.js
new file mode 100644
index 00000000..684e37ec
--- /dev/null
+++ b/node_modules/vue/src/core/observer/array.js
@@ -0,0 +1,45 @@
+/*
+ * not type checking this file because flow doesn't play well with
+ * dynamically accessing methods on Array prototype
+ */
+
+import { def } from '../util/index'
+
+const arrayProto = Array.prototype
+export const arrayMethods = Object.create(arrayProto)
+
+const methodsToPatch = [
+ 'push',
+ 'pop',
+ 'shift',
+ 'unshift',
+ 'splice',
+ 'sort',
+ 'reverse'
+]
+
+/**
+ * Intercept mutating methods and emit events
+ */
+methodsToPatch.forEach(function (method) {
+ // cache original method
+ const original = arrayProto[method]
+ def(arrayMethods, method, function mutator (...args) {
+ const result = original.apply(this, args)
+ const ob = this.__ob__
+ let inserted
+ switch (method) {
+ case 'push':
+ case 'unshift':
+ inserted = args
+ break
+ case 'splice':
+ inserted = args.slice(2)
+ break
+ }
+ if (inserted) ob.observeArray(inserted)
+ // notify change
+ ob.dep.notify()
+ return result
+ })
+})
diff --git a/node_modules/vue/src/core/observer/dep.js b/node_modules/vue/src/core/observer/dep.js
new file mode 100644
index 00000000..abf3b275
--- /dev/null
+++ b/node_modules/vue/src/core/observer/dep.js
@@ -0,0 +1,58 @@
+/* @flow */
+
+import type Watcher from './watcher'
+import { remove } from '../util/index'
+
+let uid = 0
+
+/**
+ * A dep is an observable that can have multiple
+ * directives subscribing to it.
+ */
+export default class Dep {
+ static target: ?Watcher;
+ id: number;
+ subs: Array<Watcher>;
+
+ constructor () {
+ this.id = uid++
+ this.subs = []
+ }
+
+ addSub (sub: Watcher) {
+ this.subs.push(sub)
+ }
+
+ removeSub (sub: Watcher) {
+ remove(this.subs, sub)
+ }
+
+ depend () {
+ if (Dep.target) {
+ Dep.target.addDep(this)
+ }
+ }
+
+ notify () {
+ // stabilize the subscriber list first
+ const subs = this.subs.slice()
+ for (let i = 0, l = subs.length; i < l; i++) {
+ subs[i].update()
+ }
+ }
+}
+
+// the current target watcher being evaluated.
+// this is globally unique because there could be only one
+// watcher being evaluated at any time.
+Dep.target = null
+const targetStack = []
+
+export function pushTarget (_target: ?Watcher) {
+ if (Dep.target) targetStack.push(Dep.target)
+ Dep.target = _target
+}
+
+export function popTarget () {
+ Dep.target = targetStack.pop()
+}
diff --git a/node_modules/vue/src/core/observer/index.js b/node_modules/vue/src/core/observer/index.js
new file mode 100644
index 00000000..4a030ed7
--- /dev/null
+++ b/node_modules/vue/src/core/observer/index.js
@@ -0,0 +1,273 @@
+/* @flow */
+
+import Dep from './dep'
+import VNode from '../vdom/vnode'
+import { arrayMethods } from './array'
+import {
+ def,
+ warn,
+ hasOwn,
+ hasProto,
+ isObject,
+ isPlainObject,
+ isPrimitive,
+ isUndef,
+ isValidArrayIndex,
+ isServerRendering
+} from '../util/index'
+
+const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
+
+/**
+ * In some cases we may want to disable observation inside a component's
+ * update computation.
+ */
+export let shouldObserve: boolean = true
+
+export function toggleObserving (value: boolean) {
+ shouldObserve = value
+}
+
+/**
+ * Observer class that is attached to each observed
+ * object. Once attached, the observer converts the target
+ * object's property keys into getter/setters that
+ * collect dependencies and dispatch updates.
+ */
+export class Observer {
+ value: any;
+ dep: Dep;
+ vmCount: number; // number of vms that has this object as root $data
+
+ constructor (value: any) {
+ this.value = value
+ this.dep = new Dep()
+ this.vmCount = 0
+ def(value, '__ob__', this)
+ if (Array.isArray(value)) {
+ const augment = hasProto
+ ? protoAugment
+ : copyAugment
+ augment(value, arrayMethods, arrayKeys)
+ this.observeArray(value)
+ } else {
+ this.walk(value)
+ }
+ }
+
+ /**
+ * Walk through each property and convert them into
+ * getter/setters. This method should only be called when
+ * value type is Object.
+ */
+ walk (obj: Object) {
+ const keys = Object.keys(obj)
+ for (let i = 0; i < keys.length; i++) {
+ defineReactive(obj, keys[i])
+ }
+ }
+
+ /**
+ * Observe a list of Array items.
+ */
+ observeArray (items: Array<any>) {
+ for (let i = 0, l = items.length; i < l; i++) {
+ observe(items[i])
+ }
+ }
+}
+
+// helpers
+
+/**
+ * Augment an target Object or Array by intercepting
+ * the prototype chain using __proto__
+ */
+function protoAugment (target, src: Object, keys: any) {
+ /* eslint-disable no-proto */
+ target.__proto__ = src
+ /* eslint-enable no-proto */
+}
+
+/**
+ * Augment an target Object or Array by defining
+ * hidden properties.
+ */
+/* istanbul ignore next */
+function copyAugment (target: Object, src: Object, keys: Array<string>) {
+ for (let i = 0, l = keys.length; i < l; i++) {
+ const key = keys[i]
+ def(target, key, src[key])
+ }
+}
+
+/**
+ * Attempt to create an observer instance for a value,
+ * returns the new observer if successfully observed,
+ * or the existing observer if the value already has one.
+ */
+export function observe (value: any, asRootData: ?boolean): Observer | void {
+ if (!isObject(value) || value instanceof VNode) {
+ return
+ }
+ let ob: Observer | void
+ if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
+ ob = value.__ob__
+ } else if (
+ shouldObserve &&
+ !isServerRendering() &&
+ (Array.isArray(value) || isPlainObject(value)) &&
+ Object.isExtensible(value) &&
+ !value._isVue
+ ) {
+ ob = new Observer(value)
+ }
+ if (asRootData && ob) {
+ ob.vmCount++
+ }
+ return ob
+}
+
+/**
+ * Define a reactive property on an Object.
+ */
+export function defineReactive (
+ obj: Object,
+ key: string,
+ val: any,
+ customSetter?: ?Function,
+ shallow?: boolean
+) {
+ const dep = new Dep()
+
+ const property = Object.getOwnPropertyDescriptor(obj, key)
+ if (property && property.configurable === false) {
+ return
+ }
+
+ // cater for pre-defined getter/setters
+ const getter = property && property.get
+ if (!getter && arguments.length === 2) {
+ val = obj[key]
+ }
+ const setter = property && property.set
+
+ let childOb = !shallow && observe(val)
+ Object.defineProperty(obj, key, {
+ enumerable: true,
+ configurable: true,
+ get: function reactiveGetter () {
+ const value = getter ? getter.call(obj) : val
+ if (Dep.target) {
+ dep.depend()
+ if (childOb) {
+ childOb.dep.depend()
+ if (Array.isArray(value)) {
+ dependArray(value)
+ }
+ }
+ }
+ return value
+ },
+ set: function reactiveSetter (newVal) {
+ const value = getter ? getter.call(obj) : val
+ /* eslint-disable no-self-compare */
+ if (newVal === value || (newVal !== newVal && value !== value)) {
+ return
+ }
+ /* eslint-enable no-self-compare */
+ if (process.env.NODE_ENV !== 'production' && customSetter) {
+ customSetter()
+ }
+ if (setter) {
+ setter.call(obj, newVal)
+ } else {
+ val = newVal
+ }
+ childOb = !shallow && observe(newVal)
+ dep.notify()
+ }
+ })
+}
+
+/**
+ * Set a property on an object. Adds the new property and
+ * triggers change notification if the property doesn't
+ * already exist.
+ */
+export function set (target: Array<any> | Object, key: any, val: any): any {
+ if (process.env.NODE_ENV !== 'production' &&
+ (isUndef(target) || isPrimitive(target))
+ ) {
+ warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
+ }
+ if (Array.isArray(target) && isValidArrayIndex(key)) {
+ target.length = Math.max(target.length, key)
+ target.splice(key, 1, val)
+ return val
+ }
+ if (key in target && !(key in Object.prototype)) {
+ target[key] = val
+ return val
+ }
+ const ob = (target: any).__ob__
+ if (target._isVue || (ob && ob.vmCount)) {
+ process.env.NODE_ENV !== 'production' && warn(
+ 'Avoid adding reactive properties to a Vue instance or its root $data ' +
+ 'at runtime - declare it upfront in the data option.'
+ )
+ return val
+ }
+ if (!ob) {
+ target[key] = val
+ return val
+ }
+ defineReactive(ob.value, key, val)
+ ob.dep.notify()
+ return val
+}
+
+/**
+ * Delete a property and trigger change if necessary.
+ */
+export function del (target: Array<any> | Object, key: any) {
+ if (process.env.NODE_ENV !== 'production' &&
+ (isUndef(target) || isPrimitive(target))
+ ) {
+ warn(`Cannot delete reactive property on undefined, null, or primitive value: ${(target: any)}`)
+ }
+ if (Array.isArray(target) && isValidArrayIndex(key)) {
+ target.splice(key, 1)
+ return
+ }
+ const ob = (target: any).__ob__
+ if (target._isVue || (ob && ob.vmCount)) {
+ process.env.NODE_ENV !== 'production' && warn(
+ 'Avoid deleting properties on a Vue instance or its root $data ' +
+ '- just set it to null.'
+ )
+ return
+ }
+ if (!hasOwn(target, key)) {
+ return
+ }
+ delete target[key]
+ if (!ob) {
+ return
+ }
+ ob.dep.notify()
+}
+
+/**
+ * Collect dependencies on array elements when the array is touched, since
+ * we cannot intercept array element access like property getters.
+ */
+function dependArray (value: Array<any>) {
+ for (let e, i = 0, l = value.length; i < l; i++) {
+ e = value[i]
+ e && e.__ob__ && e.__ob__.dep.depend()
+ if (Array.isArray(e)) {
+ dependArray(e)
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/observer/scheduler.js b/node_modules/vue/src/core/observer/scheduler.js
new file mode 100644
index 00000000..fce86e5f
--- /dev/null
+++ b/node_modules/vue/src/core/observer/scheduler.js
@@ -0,0 +1,148 @@
+/* @flow */
+
+import type Watcher from './watcher'
+import config from '../config'
+import { callHook, activateChildComponent } from '../instance/lifecycle'
+
+import {
+ warn,
+ nextTick,
+ devtools
+} from '../util/index'
+
+export const MAX_UPDATE_COUNT = 100
+
+const queue: Array<Watcher> = []
+const activatedChildren: Array<Component> = []
+let has: { [key: number]: ?true } = {}
+let circular: { [key: number]: number } = {}
+let waiting = false
+let flushing = false
+let index = 0
+
+/**
+ * Reset the scheduler's state.
+ */
+function resetSchedulerState () {
+ index = queue.length = activatedChildren.length = 0
+ has = {}
+ if (process.env.NODE_ENV !== 'production') {
+ circular = {}
+ }
+ waiting = flushing = false
+}
+
+/**
+ * Flush both queues and run the watchers.
+ */
+function flushSchedulerQueue () {
+ flushing = true
+ let watcher, id
+
+ // Sort queue before flush.
+ // This ensures that:
+ // 1. Components are updated from parent to child. (because parent is always
+ // created before the child)
+ // 2. A component's user watchers are run before its render watcher (because
+ // user watchers are created before the render watcher)
+ // 3. If a component is destroyed during a parent component's watcher run,
+ // its watchers can be skipped.
+ queue.sort((a, b) => a.id - b.id)
+
+ // do not cache length because more watchers might be pushed
+ // as we run existing watchers
+ for (index = 0; index < queue.length; index++) {
+ watcher = queue[index]
+ id = watcher.id
+ has[id] = null
+ watcher.run()
+ // in dev build, check and stop circular updates.
+ if (process.env.NODE_ENV !== 'production' && has[id] != null) {
+ circular[id] = (circular[id] || 0) + 1
+ if (circular[id] > MAX_UPDATE_COUNT) {
+ warn(
+ 'You may have an infinite update loop ' + (
+ watcher.user
+ ? `in watcher with expression "${watcher.expression}"`
+ : `in a component render function.`
+ ),
+ watcher.vm
+ )
+ break
+ }
+ }
+ }
+
+ // keep copies of post queues before resetting state
+ const activatedQueue = activatedChildren.slice()
+ const updatedQueue = queue.slice()
+
+ resetSchedulerState()
+
+ // call component updated and activated hooks
+ callActivatedHooks(activatedQueue)
+ callUpdatedHooks(updatedQueue)
+
+ // devtool hook
+ /* istanbul ignore if */
+ if (devtools && config.devtools) {
+ devtools.emit('flush')
+ }
+}
+
+function callUpdatedHooks (queue) {
+ let i = queue.length
+ while (i--) {
+ const watcher = queue[i]
+ const vm = watcher.vm
+ if (vm._watcher === watcher && vm._isMounted) {
+ callHook(vm, 'updated')
+ }
+ }
+}
+
+/**
+ * Queue a kept-alive component that was activated during patch.
+ * The queue will be processed after the entire tree has been patched.
+ */
+export function queueActivatedComponent (vm: Component) {
+ // setting _inactive to false here so that a render function can
+ // rely on checking whether it's in an inactive tree (e.g. router-view)
+ vm._inactive = false
+ activatedChildren.push(vm)
+}
+
+function callActivatedHooks (queue) {
+ for (let i = 0; i < queue.length; i++) {
+ queue[i]._inactive = true
+ activateChildComponent(queue[i], true /* true */)
+ }
+}
+
+/**
+ * Push a watcher into the watcher queue.
+ * Jobs with duplicate IDs will be skipped unless it's
+ * pushed when the queue is being flushed.
+ */
+export function queueWatcher (watcher: Watcher) {
+ const id = watcher.id
+ if (has[id] == null) {
+ has[id] = true
+ if (!flushing) {
+ queue.push(watcher)
+ } else {
+ // if already flushing, splice the watcher based on its id
+ // if already past its id, it will be run next immediately.
+ let i = queue.length - 1
+ while (i > index && queue[i].id > watcher.id) {
+ i--
+ }
+ queue.splice(i + 1, 0, watcher)
+ }
+ // queue the flush
+ if (!waiting) {
+ waiting = true
+ nextTick(flushSchedulerQueue)
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/observer/traverse.js b/node_modules/vue/src/core/observer/traverse.js
new file mode 100644
index 00000000..6b26524a
--- /dev/null
+++ b/node_modules/vue/src/core/observer/traverse.js
@@ -0,0 +1,40 @@
+/* @flow */
+
+import { _Set as Set, isObject } from '../util/index'
+import type { SimpleSet } from '../util/index'
+import VNode from '../vdom/vnode'
+
+const seenObjects = new Set()
+
+/**
+ * Recursively traverse an object to evoke all converted
+ * getters, so that every nested property inside the object
+ * is collected as a "deep" dependency.
+ */
+export function traverse (val: any) {
+ _traverse(val, seenObjects)
+ seenObjects.clear()
+}
+
+function _traverse (val: any, seen: SimpleSet) {
+ let i, keys
+ const isA = Array.isArray(val)
+ if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) {
+ return
+ }
+ if (val.__ob__) {
+ const depId = val.__ob__.dep.id
+ if (seen.has(depId)) {
+ return
+ }
+ seen.add(depId)
+ }
+ if (isA) {
+ i = val.length
+ while (i--) _traverse(val[i], seen)
+ } else {
+ keys = Object.keys(val)
+ i = keys.length
+ while (i--) _traverse(val[keys[i]], seen)
+ }
+}
diff --git a/node_modules/vue/src/core/observer/watcher.js b/node_modules/vue/src/core/observer/watcher.js
new file mode 100644
index 00000000..48a2e612
--- /dev/null
+++ b/node_modules/vue/src/core/observer/watcher.js
@@ -0,0 +1,240 @@
+/* @flow */
+
+import {
+ warn,
+ remove,
+ isObject,
+ parsePath,
+ _Set as Set,
+ handleError
+} from '../util/index'
+
+import { traverse } from './traverse'
+import { queueWatcher } from './scheduler'
+import Dep, { pushTarget, popTarget } from './dep'
+
+import type { SimpleSet } from '../util/index'
+
+let 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.
+ */
+export default class Watcher {
+ vm: Component;
+ expression: string;
+ cb: Function;
+ id: number;
+ deep: boolean;
+ user: boolean;
+ lazy: boolean;
+ sync: boolean;
+ dirty: boolean;
+ active: boolean;
+ deps: Array<Dep>;
+ newDeps: Array<Dep>;
+ depIds: SimpleSet;
+ newDepIds: SimpleSet;
+ getter: Function;
+ value: any;
+
+ constructor (
+ vm: Component,
+ expOrFn: string | Function,
+ cb: Function,
+ options?: ?Object,
+ isRenderWatcher?: boolean
+ ) {
+ this.vm = vm
+ if (isRenderWatcher) {
+ vm._watcher = this
+ }
+ vm._watchers.push(this)
+ // options
+ if (options) {
+ this.deep = !!options.deep
+ this.user = !!options.user
+ this.lazy = !!options.lazy
+ this.sync = !!options.sync
+ } else {
+ this.deep = this.user = this.lazy = this.sync = false
+ }
+ this.cb = cb
+ this.id = ++uid // uid for batching
+ this.active = true
+ this.dirty = this.lazy // for lazy watchers
+ this.deps = []
+ this.newDeps = []
+ this.depIds = new Set()
+ this.newDepIds = new Set()
+ this.expression = process.env.NODE_ENV !== 'production'
+ ? expOrFn.toString()
+ : ''
+ // parse expression for getter
+ if (typeof expOrFn === 'function') {
+ this.getter = expOrFn
+ } else {
+ this.getter = parsePath(expOrFn)
+ if (!this.getter) {
+ this.getter = function () {}
+ process.env.NODE_ENV !== 'production' && warn(
+ `Failed watching path: "${expOrFn}" ` +
+ 'Watcher only accepts simple dot-delimited paths. ' +
+ 'For full control, use a function instead.',
+ vm
+ )
+ }
+ }
+ this.value = this.lazy
+ ? undefined
+ : this.get()
+ }
+
+ /**
+ * Evaluate the getter, and re-collect dependencies.
+ */
+ get () {
+ pushTarget(this)
+ let value
+ const vm = this.vm
+ try {
+ value = this.getter.call(vm, vm)
+ } catch (e) {
+ if (this.user) {
+ handleError(e, vm, `getter for watcher "${this.expression}"`)
+ } else {
+ throw e
+ }
+ } finally {
+ // "touch" every property so they are all tracked as
+ // dependencies for deep watching
+ if (this.deep) {
+ traverse(value)
+ }
+ popTarget()
+ this.cleanupDeps()
+ }
+ return value
+ }
+
+ /**
+ * Add a dependency to this directive.
+ */
+ addDep (dep: Dep) {
+ const id = dep.id
+ if (!this.newDepIds.has(id)) {
+ this.newDepIds.add(id)
+ this.newDeps.push(dep)
+ if (!this.depIds.has(id)) {
+ dep.addSub(this)
+ }
+ }
+ }
+
+ /**
+ * Clean up for dependency collection.
+ */
+ cleanupDeps () {
+ let i = this.deps.length
+ while (i--) {
+ const dep = this.deps[i]
+ if (!this.newDepIds.has(dep.id)) {
+ dep.removeSub(this)
+ }
+ }
+ let tmp = this.depIds
+ this.depIds = this.newDepIds
+ this.newDepIds = tmp
+ this.newDepIds.clear()
+ tmp = this.deps
+ this.deps = this.newDeps
+ this.newDeps = tmp
+ this.newDeps.length = 0
+ }
+
+ /**
+ * Subscriber interface.
+ * Will be called when a dependency changes.
+ */
+ update () {
+ /* istanbul ignore else */
+ if (this.lazy) {
+ this.dirty = true
+ } else if (this.sync) {
+ this.run()
+ } else {
+ queueWatcher(this)
+ }
+ }
+
+ /**
+ * Scheduler job interface.
+ * Will be called by the scheduler.
+ */
+ run () {
+ if (this.active) {
+ const value = this.get()
+ if (
+ value !== this.value ||
+ // Deep watchers and watchers on Object/Arrays should fire even
+ // when the value is the same, because the value may
+ // have mutated.
+ isObject(value) ||
+ this.deep
+ ) {
+ // set new value
+ const oldValue = this.value
+ this.value = value
+ if (this.user) {
+ try {
+ this.cb.call(this.vm, value, oldValue)
+ } catch (e) {
+ handleError(e, this.vm, `callback for watcher "${this.expression}"`)
+ }
+ } else {
+ this.cb.call(this.vm, value, oldValue)
+ }
+ }
+ }
+ }
+
+ /**
+ * Evaluate the value of the watcher.
+ * This only gets called for lazy watchers.
+ */
+ evaluate () {
+ this.value = this.get()
+ this.dirty = false
+ }
+
+ /**
+ * Depend on all deps collected by this watcher.
+ */
+ depend () {
+ let i = this.deps.length
+ while (i--) {
+ this.deps[i].depend()
+ }
+ }
+
+ /**
+ * Remove self from all dependencies' subscriber list.
+ */
+ teardown () {
+ if (this.active) {
+ // remove self from vm's watcher list
+ // this is a somewhat expensive operation so we skip it
+ // if the vm is being destroyed.
+ if (!this.vm._isBeingDestroyed) {
+ remove(this.vm._watchers, this)
+ }
+ let i = this.deps.length
+ while (i--) {
+ this.deps[i].removeSub(this)
+ }
+ this.active = false
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/util/debug.js b/node_modules/vue/src/core/util/debug.js
new file mode 100644
index 00000000..6b7315f4
--- /dev/null
+++ b/node_modules/vue/src/core/util/debug.js
@@ -0,0 +1,100 @@
+/* @flow */
+
+import config from '../config'
+import { noop } from 'shared/util'
+
+export let warn = noop
+export let tip = noop
+export let generateComponentTrace = (noop: any) // work around flow check
+export let formatComponentName = (noop: any)
+
+if (process.env.NODE_ENV !== 'production') {
+ const hasConsole = typeof console !== 'undefined'
+ const classifyRE = /(?:^|[-_])(\w)/g
+ const classify = str => str
+ .replace(classifyRE, c => c.toUpperCase())
+ .replace(/[-_]/g, '')
+
+ warn = (msg, vm) => {
+ const trace = vm ? generateComponentTrace(vm) : ''
+
+ if (config.warnHandler) {
+ config.warnHandler.call(null, msg, vm, trace)
+ } else if (hasConsole && (!config.silent)) {
+ console.error(`[Vue warn]: ${msg}${trace}`)
+ }
+ }
+
+ tip = (msg, vm) => {
+ if (hasConsole && (!config.silent)) {
+ console.warn(`[Vue tip]: ${msg}` + (
+ vm ? generateComponentTrace(vm) : ''
+ ))
+ }
+ }
+
+ formatComponentName = (vm, includeFile) => {
+ if (vm.$root === vm) {
+ return '<Root>'
+ }
+ const options = typeof vm === 'function' && vm.cid != null
+ ? vm.options
+ : vm._isVue
+ ? vm.$options || vm.constructor.options
+ : vm || {}
+ let name = options.name || options._componentTag
+ const file = options.__file
+ if (!name && file) {
+ const match = file.match(/([^/\\]+)\.vue$/)
+ name = match && match[1]
+ }
+
+ return (
+ (name ? `<${classify(name)}>` : `<Anonymous>`) +
+ (file && includeFile !== false ? ` at ${file}` : '')
+ )
+ }
+
+ const repeat = (str, n) => {
+ let res = ''
+ while (n) {
+ if (n % 2 === 1) res += str
+ if (n > 1) str += str
+ n >>= 1
+ }
+ return res
+ }
+
+ generateComponentTrace = vm => {
+ if (vm._isVue && vm.$parent) {
+ const tree = []
+ let currentRecursiveSequence = 0
+ while (vm) {
+ if (tree.length > 0) {
+ const last = tree[tree.length - 1]
+ if (last.constructor === vm.constructor) {
+ currentRecursiveSequence++
+ vm = vm.$parent
+ continue
+ } else if (currentRecursiveSequence > 0) {
+ tree[tree.length - 1] = [last, currentRecursiveSequence]
+ currentRecursiveSequence = 0
+ }
+ }
+ tree.push(vm)
+ vm = vm.$parent
+ }
+ return '\n\nfound in\n\n' + tree
+ .map((vm, i) => `${
+ i === 0 ? '---> ' : repeat(' ', 5 + i * 2)
+ }${
+ Array.isArray(vm)
+ ? `${formatComponentName(vm[0])}... (${vm[1]} recursive calls)`
+ : formatComponentName(vm)
+ }`)
+ .join('\n')
+ } else {
+ return `\n\n(found in ${formatComponentName(vm)})`
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/util/env.js b/node_modules/vue/src/core/util/env.js
new file mode 100644
index 00000000..07cadd9c
--- /dev/null
+++ b/node_modules/vue/src/core/util/env.js
@@ -0,0 +1,95 @@
+/* @flow */
+
+// can we use __proto__?
+export const hasProto = '__proto__' in {}
+
+// Browser environment sniffing
+export const inBrowser = typeof window !== 'undefined'
+export const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform
+export const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase()
+export const UA = inBrowser && window.navigator.userAgent.toLowerCase()
+export const isIE = UA && /msie|trident/.test(UA)
+export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
+export const isEdge = UA && UA.indexOf('edge/') > 0
+export const isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android')
+export const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios')
+export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
+
+// Firefox has a "watch" function on Object.prototype...
+export const nativeWatch = ({}).watch
+
+export let supportsPassive = false
+if (inBrowser) {
+ try {
+ const opts = {}
+ Object.defineProperty(opts, 'passive', ({
+ get () {
+ /* istanbul ignore next */
+ supportsPassive = true
+ }
+ }: Object)) // https://github.com/facebook/flow/issues/285
+ window.addEventListener('test-passive', null, opts)
+ } catch (e) {}
+}
+
+// this needs to be lazy-evaled because vue may be required before
+// vue-server-renderer can set VUE_ENV
+let _isServer
+export const isServerRendering = () => {
+ if (_isServer === undefined) {
+ /* istanbul ignore if */
+ if (!inBrowser && !inWeex && typeof global !== 'undefined') {
+ // detect presence of vue-server-renderer and avoid
+ // Webpack shimming the process
+ _isServer = global['process'].env.VUE_ENV === 'server'
+ } else {
+ _isServer = false
+ }
+ }
+ return _isServer
+}
+
+// detect devtools
+export const devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__
+
+/* istanbul ignore next */
+export function isNative (Ctor: any): boolean {
+ return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
+}
+
+export const hasSymbol =
+ typeof Symbol !== 'undefined' && isNative(Symbol) &&
+ typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys)
+
+let _Set
+/* istanbul ignore if */ // $flow-disable-line
+if (typeof Set !== 'undefined' && isNative(Set)) {
+ // use native Set when available.
+ _Set = Set
+} else {
+ // a non-standard Set polyfill that only works with primitive keys.
+ _Set = class Set implements SimpleSet {
+ set: Object;
+ constructor () {
+ this.set = Object.create(null)
+ }
+ has (key: string | number) {
+ return this.set[key] === true
+ }
+ add (key: string | number) {
+ this.set[key] = true
+ }
+ clear () {
+ this.set = Object.create(null)
+ }
+ }
+}
+
+interface SimpleSet {
+ has(key: string | number): boolean;
+ add(key: string | number): mixed;
+ clear(): void;
+}
+
+export { _Set }
+export type { SimpleSet }
diff --git a/node_modules/vue/src/core/util/error.js b/node_modules/vue/src/core/util/error.js
new file mode 100644
index 00000000..b7d05a6d
--- /dev/null
+++ b/node_modules/vue/src/core/util/error.js
@@ -0,0 +1,48 @@
+/* @flow */
+
+import config from '../config'
+import { warn } from './debug'
+import { inBrowser, inWeex } from './env'
+
+export function handleError (err: Error, vm: any, info: string) {
+ if (vm) {
+ let cur = vm
+ while ((cur = cur.$parent)) {
+ const hooks = cur.$options.errorCaptured
+ if (hooks) {
+ for (let i = 0; i < hooks.length; i++) {
+ try {
+ const capture = hooks[i].call(cur, err, vm, info) === false
+ if (capture) return
+ } catch (e) {
+ globalHandleError(e, cur, 'errorCaptured hook')
+ }
+ }
+ }
+ }
+ }
+ globalHandleError(err, vm, info)
+}
+
+function globalHandleError (err, vm, info) {
+ if (config.errorHandler) {
+ try {
+ return config.errorHandler.call(null, err, vm, info)
+ } catch (e) {
+ logError(e, null, 'config.errorHandler')
+ }
+ }
+ logError(err, vm, info)
+}
+
+function logError (err, vm, info) {
+ if (process.env.NODE_ENV !== 'production') {
+ warn(`Error in ${info}: "${err.toString()}"`, vm)
+ }
+ /* istanbul ignore else */
+ if ((inBrowser || inWeex) && typeof console !== 'undefined') {
+ console.error(err)
+ } else {
+ throw err
+ }
+}
diff --git a/node_modules/vue/src/core/util/index.js b/node_modules/vue/src/core/util/index.js
new file mode 100644
index 00000000..115d77cd
--- /dev/null
+++ b/node_modules/vue/src/core/util/index.js
@@ -0,0 +1,11 @@
+/* @flow */
+
+export * from 'shared/util'
+export * from './lang'
+export * from './env'
+export * from './options'
+export * from './debug'
+export * from './props'
+export * from './error'
+export * from './next-tick'
+export { defineReactive } from '../observer/index'
diff --git a/node_modules/vue/src/core/util/lang.js b/node_modules/vue/src/core/util/lang.js
new file mode 100644
index 00000000..96b8219a
--- /dev/null
+++ b/node_modules/vue/src/core/util/lang.js
@@ -0,0 +1,39 @@
+/* @flow */
+
+/**
+ * Check if a string starts with $ or _
+ */
+export function isReserved (str: string): boolean {
+ const c = (str + '').charCodeAt(0)
+ return c === 0x24 || c === 0x5F
+}
+
+/**
+ * Define a property.
+ */
+export function def (obj: Object, key: string, val: any, enumerable?: boolean) {
+ Object.defineProperty(obj, key, {
+ value: val,
+ enumerable: !!enumerable,
+ writable: true,
+ configurable: true
+ })
+}
+
+/**
+ * Parse simple path.
+ */
+const bailRE = /[^\w.$]/
+export function parsePath (path: string): any {
+ if (bailRE.test(path)) {
+ return
+ }
+ const segments = path.split('.')
+ return function (obj) {
+ for (let i = 0; i < segments.length; i++) {
+ if (!obj) return
+ obj = obj[segments[i]]
+ }
+ return obj
+ }
+}
diff --git a/node_modules/vue/src/core/util/next-tick.js b/node_modules/vue/src/core/util/next-tick.js
new file mode 100644
index 00000000..07a9e841
--- /dev/null
+++ b/node_modules/vue/src/core/util/next-tick.js
@@ -0,0 +1,117 @@
+/* @flow */
+/* globals MessageChannel */
+
+import { noop } from 'shared/util'
+import { handleError } from './error'
+import { isIOS, isNative } from './env'
+
+const callbacks = []
+let pending = false
+
+function flushCallbacks () {
+ pending = false
+ const copies = callbacks.slice(0)
+ callbacks.length = 0
+ for (let i = 0; i < copies.length; i++) {
+ copies[i]()
+ }
+}
+
+// Here we have async deferring wrappers using both microtasks and (macro) tasks.
+// In < 2.4 we used microtasks everywhere, but there are some scenarios where
+// microtasks have too high a priority and fire in between supposedly
+// sequential events (e.g. #4521, #6690) or even between bubbling of the same
+// event (#6566). However, using (macro) tasks everywhere also has subtle problems
+// when state is changed right before repaint (e.g. #6813, out-in transitions).
+// Here we use microtask by default, but expose a way to force (macro) task when
+// needed (e.g. in event handlers attached by v-on).
+let microTimerFunc
+let macroTimerFunc
+let useMacroTask = false
+
+// Determine (macro) task defer implementation.
+// Technically setImmediate should be the ideal choice, but it's only available
+// in IE. The only polyfill that consistently queues the callback after all DOM
+// events triggered in the same loop is by using MessageChannel.
+/* istanbul ignore if */
+if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
+ macroTimerFunc = () => {
+ setImmediate(flushCallbacks)
+ }
+} else if (typeof MessageChannel !== 'undefined' && (
+ isNative(MessageChannel) ||
+ // PhantomJS
+ MessageChannel.toString() === '[object MessageChannelConstructor]'
+)) {
+ const channel = new MessageChannel()
+ const port = channel.port2
+ channel.port1.onmessage = flushCallbacks
+ macroTimerFunc = () => {
+ port.postMessage(1)
+ }
+} else {
+ /* istanbul ignore next */
+ macroTimerFunc = () => {
+ setTimeout(flushCallbacks, 0)
+ }
+}
+
+// Determine microtask defer implementation.
+/* istanbul ignore next, $flow-disable-line */
+if (typeof Promise !== 'undefined' && isNative(Promise)) {
+ const p = Promise.resolve()
+ microTimerFunc = () => {
+ p.then(flushCallbacks)
+ // in problematic UIWebViews, Promise.then doesn't completely break, but
+ // it can get stuck in a weird state where callbacks are pushed into the
+ // microtask queue but the queue isn't being flushed, until the browser
+ // needs to do some other work, e.g. handle a timer. Therefore we can
+ // "force" the microtask queue to be flushed by adding an empty timer.
+ if (isIOS) setTimeout(noop)
+ }
+} else {
+ // fallback to macro
+ microTimerFunc = macroTimerFunc
+}
+
+/**
+ * Wrap a function so that if any code inside triggers state change,
+ * the changes are queued using a (macro) task instead of a microtask.
+ */
+export function withMacroTask (fn: Function): Function {
+ return fn._withTask || (fn._withTask = function () {
+ useMacroTask = true
+ const res = fn.apply(null, arguments)
+ useMacroTask = false
+ return res
+ })
+}
+
+export function nextTick (cb?: Function, ctx?: Object) {
+ let _resolve
+ callbacks.push(() => {
+ if (cb) {
+ try {
+ cb.call(ctx)
+ } catch (e) {
+ handleError(e, ctx, 'nextTick')
+ }
+ } else if (_resolve) {
+ _resolve(ctx)
+ }
+ })
+ if (!pending) {
+ pending = true
+ if (useMacroTask) {
+ macroTimerFunc()
+ } else {
+ microTimerFunc()
+ }
+ }
+ // $flow-disable-line
+ if (!cb && typeof Promise !== 'undefined') {
+ return new Promise(resolve => {
+ _resolve = resolve
+ })
+ }
+}
diff --git a/node_modules/vue/src/core/util/options.js b/node_modules/vue/src/core/util/options.js
new file mode 100644
index 00000000..5f0d10d3
--- /dev/null
+++ b/node_modules/vue/src/core/util/options.js
@@ -0,0 +1,438 @@
+/* @flow */
+
+import config from '../config'
+import { warn } from './debug'
+import { nativeWatch } from './env'
+import { set } from '../observer/index'
+
+import {
+ ASSET_TYPES,
+ LIFECYCLE_HOOKS
+} from 'shared/constants'
+
+import {
+ extend,
+ hasOwn,
+ camelize,
+ toRawType,
+ capitalize,
+ isBuiltInTag,
+ isPlainObject
+} from 'shared/util'
+
+/**
+ * Option overwriting strategies are functions that handle
+ * how to merge a parent option value and a child option
+ * value into the final value.
+ */
+const strats = config.optionMergeStrategies
+
+/**
+ * Options with restrictions
+ */
+if (process.env.NODE_ENV !== 'production') {
+ strats.el = strats.propsData = function (parent, child, vm, key) {
+ if (!vm) {
+ warn(
+ `option "${key}" can only be used during instance ` +
+ 'creation with the `new` keyword.'
+ )
+ }
+ return defaultStrat(parent, child)
+ }
+}
+
+/**
+ * Helper that recursively merges two data objects together.
+ */
+function mergeData (to: Object, from: ?Object): Object {
+ if (!from) return to
+ let key, toVal, fromVal
+ const keys = Object.keys(from)
+ for (let i = 0; i < keys.length; i++) {
+ key = keys[i]
+ toVal = to[key]
+ fromVal = from[key]
+ if (!hasOwn(to, key)) {
+ set(to, key, fromVal)
+ } else if (isPlainObject(toVal) && isPlainObject(fromVal)) {
+ mergeData(toVal, fromVal)
+ }
+ }
+ return to
+}
+
+/**
+ * Data
+ */
+export function mergeDataOrFn (
+ parentVal: any,
+ childVal: any,
+ vm?: Component
+): ?Function {
+ if (!vm) {
+ // in a Vue.extend merge, both should be functions
+ if (!childVal) {
+ return parentVal
+ }
+ if (!parentVal) {
+ return childVal
+ }
+ // when parentVal & childVal are both present,
+ // we need to return a function that returns the
+ // merged result of both functions... no need to
+ // check if parentVal is a function here because
+ // it has to be a function to pass previous merges.
+ return function mergedDataFn () {
+ return mergeData(
+ typeof childVal === 'function' ? childVal.call(this, this) : childVal,
+ typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal
+ )
+ }
+ } else {
+ return function mergedInstanceDataFn () {
+ // instance merge
+ const instanceData = typeof childVal === 'function'
+ ? childVal.call(vm, vm)
+ : childVal
+ const defaultData = typeof parentVal === 'function'
+ ? parentVal.call(vm, vm)
+ : parentVal
+ if (instanceData) {
+ return mergeData(instanceData, defaultData)
+ } else {
+ return defaultData
+ }
+ }
+ }
+}
+
+strats.data = function (
+ parentVal: any,
+ childVal: any,
+ vm?: Component
+): ?Function {
+ if (!vm) {
+ if (childVal && typeof childVal !== 'function') {
+ process.env.NODE_ENV !== 'production' && warn(
+ 'The "data" option should be a function ' +
+ 'that returns a per-instance value in component ' +
+ 'definitions.',
+ vm
+ )
+
+ return parentVal
+ }
+ return mergeDataOrFn(parentVal, childVal)
+ }
+
+ return mergeDataOrFn(parentVal, childVal, vm)
+}
+
+/**
+ * Hooks and props are merged as arrays.
+ */
+function mergeHook (
+ parentVal: ?Array<Function>,
+ childVal: ?Function | ?Array<Function>
+): ?Array<Function> {
+ return childVal
+ ? parentVal
+ ? parentVal.concat(childVal)
+ : Array.isArray(childVal)
+ ? childVal
+ : [childVal]
+ : parentVal
+}
+
+LIFECYCLE_HOOKS.forEach(hook => {
+ strats[hook] = mergeHook
+})
+
+/**
+ * Assets
+ *
+ * When a vm is present (instance creation), we need to do
+ * a three-way merge between constructor options, instance
+ * options and parent options.
+ */
+function mergeAssets (
+ parentVal: ?Object,
+ childVal: ?Object,
+ vm?: Component,
+ key: string
+): Object {
+ const res = Object.create(parentVal || null)
+ if (childVal) {
+ process.env.NODE_ENV !== 'production' && assertObjectType(key, childVal, vm)
+ return extend(res, childVal)
+ } else {
+ return res
+ }
+}
+
+ASSET_TYPES.forEach(function (type) {
+ strats[type + 's'] = mergeAssets
+})
+
+/**
+ * Watchers.
+ *
+ * Watchers hashes should not overwrite one
+ * another, so we merge them as arrays.
+ */
+strats.watch = function (
+ parentVal: ?Object,
+ childVal: ?Object,
+ vm?: Component,
+ key: string
+): ?Object {
+ // work around Firefox's Object.prototype.watch...
+ if (parentVal === nativeWatch) parentVal = undefined
+ if (childVal === nativeWatch) childVal = undefined
+ /* istanbul ignore if */
+ if (!childVal) return Object.create(parentVal || null)
+ if (process.env.NODE_ENV !== 'production') {
+ assertObjectType(key, childVal, vm)
+ }
+ if (!parentVal) return childVal
+ const ret = {}
+ extend(ret, parentVal)
+ for (const key in childVal) {
+ let parent = ret[key]
+ const child = childVal[key]
+ if (parent && !Array.isArray(parent)) {
+ parent = [parent]
+ }
+ ret[key] = parent
+ ? parent.concat(child)
+ : Array.isArray(child) ? child : [child]
+ }
+ return ret
+}
+
+/**
+ * Other object hashes.
+ */
+strats.props =
+strats.methods =
+strats.inject =
+strats.computed = function (
+ parentVal: ?Object,
+ childVal: ?Object,
+ vm?: Component,
+ key: string
+): ?Object {
+ if (childVal && process.env.NODE_ENV !== 'production') {
+ assertObjectType(key, childVal, vm)
+ }
+ if (!parentVal) return childVal
+ const ret = Object.create(null)
+ extend(ret, parentVal)
+ if (childVal) extend(ret, childVal)
+ return ret
+}
+strats.provide = mergeDataOrFn
+
+/**
+ * Default strategy.
+ */
+const defaultStrat = function (parentVal: any, childVal: any): any {
+ return childVal === undefined
+ ? parentVal
+ : childVal
+}
+
+/**
+ * Validate component names
+ */
+function checkComponents (options: Object) {
+ for (const key in options.components) {
+ validateComponentName(key)
+ }
+}
+
+export function validateComponentName (name: string) {
+ if (!/^[a-zA-Z][\w-]*$/.test(name)) {
+ warn(
+ 'Invalid component name: "' + name + '". Component names ' +
+ 'can only contain alphanumeric characters and the hyphen, ' +
+ 'and must start with a letter.'
+ )
+ }
+ if (isBuiltInTag(name) || config.isReservedTag(name)) {
+ warn(
+ 'Do not use built-in or reserved HTML elements as component ' +
+ 'id: ' + name
+ )
+ }
+}
+
+/**
+ * Ensure all props option syntax are normalized into the
+ * Object-based format.
+ */
+function normalizeProps (options: Object, vm: ?Component) {
+ const props = options.props
+ if (!props) return
+ const res = {}
+ let i, val, name
+ if (Array.isArray(props)) {
+ i = props.length
+ while (i--) {
+ val = props[i]
+ if (typeof val === 'string') {
+ name = camelize(val)
+ res[name] = { type: null }
+ } else if (process.env.NODE_ENV !== 'production') {
+ warn('props must be strings when using array syntax.')
+ }
+ }
+ } else if (isPlainObject(props)) {
+ for (const key in props) {
+ val = props[key]
+ name = camelize(key)
+ res[name] = isPlainObject(val)
+ ? val
+ : { type: val }
+ }
+ } else if (process.env.NODE_ENV !== 'production') {
+ warn(
+ `Invalid value for option "props": expected an Array or an Object, ` +
+ `but got ${toRawType(props)}.`,
+ vm
+ )
+ }
+ options.props = res
+}
+
+/**
+ * Normalize all injections into Object-based format
+ */
+function normalizeInject (options: Object, vm: ?Component) {
+ const inject = options.inject
+ if (!inject) return
+ const normalized = options.inject = {}
+ if (Array.isArray(inject)) {
+ for (let i = 0; i < inject.length; i++) {
+ normalized[inject[i]] = { from: inject[i] }
+ }
+ } else if (isPlainObject(inject)) {
+ for (const key in inject) {
+ const val = inject[key]
+ normalized[key] = isPlainObject(val)
+ ? extend({ from: key }, val)
+ : { from: val }
+ }
+ } else if (process.env.NODE_ENV !== 'production') {
+ warn(
+ `Invalid value for option "inject": expected an Array or an Object, ` +
+ `but got ${toRawType(inject)}.`,
+ vm
+ )
+ }
+}
+
+/**
+ * Normalize raw function directives into object format.
+ */
+function normalizeDirectives (options: Object) {
+ const dirs = options.directives
+ if (dirs) {
+ for (const key in dirs) {
+ const def = dirs[key]
+ if (typeof def === 'function') {
+ dirs[key] = { bind: def, update: def }
+ }
+ }
+ }
+}
+
+function assertObjectType (name: string, value: any, vm: ?Component) {
+ if (!isPlainObject(value)) {
+ warn(
+ `Invalid value for option "${name}": expected an Object, ` +
+ `but got ${toRawType(value)}.`,
+ vm
+ )
+ }
+}
+
+/**
+ * Merge two option objects into a new one.
+ * Core utility used in both instantiation and inheritance.
+ */
+export function mergeOptions (
+ parent: Object,
+ child: Object,
+ vm?: Component
+): Object {
+ if (process.env.NODE_ENV !== 'production') {
+ checkComponents(child)
+ }
+
+ if (typeof child === 'function') {
+ child = child.options
+ }
+
+ normalizeProps(child, vm)
+ normalizeInject(child, vm)
+ normalizeDirectives(child)
+ const extendsFrom = child.extends
+ if (extendsFrom) {
+ parent = mergeOptions(parent, extendsFrom, vm)
+ }
+ if (child.mixins) {
+ for (let i = 0, l = child.mixins.length; i < l; i++) {
+ parent = mergeOptions(parent, child.mixins[i], vm)
+ }
+ }
+ const options = {}
+ let key
+ for (key in parent) {
+ mergeField(key)
+ }
+ for (key in child) {
+ if (!hasOwn(parent, key)) {
+ mergeField(key)
+ }
+ }
+ function mergeField (key) {
+ const strat = strats[key] || defaultStrat
+ options[key] = strat(parent[key], child[key], vm, key)
+ }
+ return options
+}
+
+/**
+ * Resolve an asset.
+ * This function is used because child instances need access
+ * to assets defined in its ancestor chain.
+ */
+export function resolveAsset (
+ options: Object,
+ type: string,
+ id: string,
+ warnMissing?: boolean
+): any {
+ /* istanbul ignore if */
+ if (typeof id !== 'string') {
+ return
+ }
+ const assets = options[type]
+ // check local registration variations first
+ if (hasOwn(assets, id)) return assets[id]
+ const camelizedId = camelize(id)
+ if (hasOwn(assets, camelizedId)) return assets[camelizedId]
+ const PascalCaseId = capitalize(camelizedId)
+ if (hasOwn(assets, PascalCaseId)) return assets[PascalCaseId]
+ // fallback to prototype chain
+ const res = assets[id] || assets[camelizedId] || assets[PascalCaseId]
+ if (process.env.NODE_ENV !== 'production' && warnMissing && !res) {
+ warn(
+ 'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
+ options
+ )
+ }
+ return res
+}
diff --git a/node_modules/vue/src/core/util/perf.js b/node_modules/vue/src/core/util/perf.js
new file mode 100644
index 00000000..4a537b2d
--- /dev/null
+++ b/node_modules/vue/src/core/util/perf.js
@@ -0,0 +1,24 @@
+import { inBrowser } from './env'
+
+export let mark
+export let measure
+
+if (process.env.NODE_ENV !== 'production') {
+ const perf = inBrowser && window.performance
+ /* istanbul ignore if */
+ if (
+ perf &&
+ perf.mark &&
+ perf.measure &&
+ perf.clearMarks &&
+ perf.clearMeasures
+ ) {
+ mark = tag => perf.mark(tag)
+ measure = (name, startTag, endTag) => {
+ perf.measure(name, startTag, endTag)
+ perf.clearMarks(startTag)
+ perf.clearMarks(endTag)
+ perf.clearMeasures(name)
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/util/props.js b/node_modules/vue/src/core/util/props.js
new file mode 100644
index 00000000..a92643f9
--- /dev/null
+++ b/node_modules/vue/src/core/util/props.js
@@ -0,0 +1,202 @@
+/* @flow */
+
+import { warn } from './debug'
+import { observe, toggleObserving, shouldObserve } from '../observer/index'
+import {
+ hasOwn,
+ isObject,
+ toRawType,
+ hyphenate,
+ capitalize,
+ isPlainObject
+} from 'shared/util'
+
+type PropOptions = {
+ type: Function | Array<Function> | null,
+ default: any,
+ required: ?boolean,
+ validator: ?Function
+};
+
+export function validateProp (
+ key: string,
+ propOptions: Object,
+ propsData: Object,
+ vm?: Component
+): any {
+ const prop = propOptions[key]
+ const absent = !hasOwn(propsData, key)
+ let value = propsData[key]
+ // boolean casting
+ const booleanIndex = getTypeIndex(Boolean, prop.type)
+ if (booleanIndex > -1) {
+ if (absent && !hasOwn(prop, 'default')) {
+ value = false
+ } else if (value === '' || value === hyphenate(key)) {
+ // only cast empty string / same name to boolean if
+ // boolean has higher priority
+ const stringIndex = getTypeIndex(String, prop.type)
+ if (stringIndex < 0 || booleanIndex < stringIndex) {
+ value = true
+ }
+ }
+ }
+ // check default value
+ if (value === undefined) {
+ value = getPropDefaultValue(vm, prop, key)
+ // since the default value is a fresh copy,
+ // make sure to observe it.
+ const prevShouldObserve = shouldObserve
+ toggleObserving(true)
+ observe(value)
+ toggleObserving(prevShouldObserve)
+ }
+ if (
+ process.env.NODE_ENV !== 'production' &&
+ // skip validation for weex recycle-list child component props
+ !(__WEEX__ && isObject(value) && ('@binding' in value))
+ ) {
+ assertProp(prop, key, value, vm, absent)
+ }
+ return value
+}
+
+/**
+ * Get the default value of a prop.
+ */
+function getPropDefaultValue (vm: ?Component, prop: PropOptions, key: string): any {
+ // no default, return undefined
+ if (!hasOwn(prop, 'default')) {
+ return undefined
+ }
+ const def = prop.default
+ // warn against non-factory defaults for Object & Array
+ if (process.env.NODE_ENV !== 'production' && isObject(def)) {
+ warn(
+ 'Invalid default value for prop "' + key + '": ' +
+ 'Props with type Object/Array must use a factory function ' +
+ 'to return the default value.',
+ vm
+ )
+ }
+ // the raw prop value was also undefined from previous render,
+ // return previous default value to avoid unnecessary watcher trigger
+ if (vm && vm.$options.propsData &&
+ vm.$options.propsData[key] === undefined &&
+ vm._props[key] !== undefined
+ ) {
+ return vm._props[key]
+ }
+ // call factory function for non-Function types
+ // a value is Function if its prototype is function even across different execution context
+ return typeof def === 'function' && getType(prop.type) !== 'Function'
+ ? def.call(vm)
+ : def
+}
+
+/**
+ * Assert whether a prop is valid.
+ */
+function assertProp (
+ prop: PropOptions,
+ name: string,
+ value: any,
+ vm: ?Component,
+ absent: boolean
+) {
+ if (prop.required && absent) {
+ warn(
+ 'Missing required prop: "' + name + '"',
+ vm
+ )
+ return
+ }
+ if (value == null && !prop.required) {
+ return
+ }
+ let type = prop.type
+ let valid = !type || type === true
+ const expectedTypes = []
+ if (type) {
+ if (!Array.isArray(type)) {
+ type = [type]
+ }
+ for (let i = 0; i < type.length && !valid; i++) {
+ const assertedType = assertType(value, type[i])
+ expectedTypes.push(assertedType.expectedType || '')
+ valid = assertedType.valid
+ }
+ }
+ if (!valid) {
+ warn(
+ `Invalid prop: type check failed for prop "${name}".` +
+ ` Expected ${expectedTypes.map(capitalize).join(', ')}` +
+ `, got ${toRawType(value)}.`,
+ vm
+ )
+ return
+ }
+ const validator = prop.validator
+ if (validator) {
+ if (!validator(value)) {
+ warn(
+ 'Invalid prop: custom validator check failed for prop "' + name + '".',
+ vm
+ )
+ }
+ }
+}
+
+const simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/
+
+function assertType (value: any, type: Function): {
+ valid: boolean;
+ expectedType: string;
+} {
+ let valid
+ const expectedType = getType(type)
+ if (simpleCheckRE.test(expectedType)) {
+ const t = typeof value
+ valid = t === expectedType.toLowerCase()
+ // for primitive wrapper objects
+ if (!valid && t === 'object') {
+ valid = value instanceof type
+ }
+ } else if (expectedType === 'Object') {
+ valid = isPlainObject(value)
+ } else if (expectedType === 'Array') {
+ valid = Array.isArray(value)
+ } else {
+ valid = value instanceof type
+ }
+ return {
+ valid,
+ expectedType
+ }
+}
+
+/**
+ * Use function string name to check built-in types,
+ * because a simple equality check will fail when running
+ * across different vms / iframes.
+ */
+function getType (fn) {
+ const match = fn && fn.toString().match(/^\s*function (\w+)/)
+ return match ? match[1] : ''
+}
+
+function isSameType (a, b) {
+ return getType(a) === getType(b)
+}
+
+function getTypeIndex (type, expectedTypes): number {
+ if (!Array.isArray(expectedTypes)) {
+ return isSameType(expectedTypes, type) ? 0 : -1
+ }
+ for (let i = 0, len = expectedTypes.length; i < len; i++) {
+ if (isSameType(expectedTypes[i], type)) {
+ return i
+ }
+ }
+ return -1
+}
diff --git a/node_modules/vue/src/core/vdom/create-component.js b/node_modules/vue/src/core/vdom/create-component.js
new file mode 100644
index 00000000..89578224
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/create-component.js
@@ -0,0 +1,257 @@
+/* @flow */
+
+import VNode from './vnode'
+import { resolveConstructorOptions } from 'core/instance/init'
+import { queueActivatedComponent } from 'core/observer/scheduler'
+import { createFunctionalComponent } from './create-functional-component'
+
+import {
+ warn,
+ isDef,
+ isUndef,
+ isTrue,
+ isObject
+} from '../util/index'
+
+import {
+ resolveAsyncComponent,
+ createAsyncPlaceholder,
+ extractPropsFromVNodeData
+} from './helpers/index'
+
+import {
+ callHook,
+ activeInstance,
+ updateChildComponent,
+ activateChildComponent,
+ deactivateChildComponent
+} from '../instance/lifecycle'
+
+import {
+ isRecyclableComponent,
+ renderRecyclableComponentTemplate
+} from 'weex/runtime/recycle-list/render-component-template'
+
+// inline hooks to be invoked on component VNodes during patch
+const componentVNodeHooks = {
+ init (
+ vnode: VNodeWithData,
+ hydrating: boolean,
+ parentElm: ?Node,
+ refElm: ?Node
+ ): ?boolean {
+ if (
+ vnode.componentInstance &&
+ !vnode.componentInstance._isDestroyed &&
+ vnode.data.keepAlive
+ ) {
+ // kept-alive components, treat as a patch
+ const mountedNode: any = vnode // work around flow
+ componentVNodeHooks.prepatch(mountedNode, mountedNode)
+ } else {
+ const child = vnode.componentInstance = createComponentInstanceForVnode(
+ vnode,
+ activeInstance,
+ parentElm,
+ refElm
+ )
+ child.$mount(hydrating ? vnode.elm : undefined, hydrating)
+ }
+ },
+
+ prepatch (oldVnode: MountedComponentVNode, vnode: MountedComponentVNode) {
+ const options = vnode.componentOptions
+ const child = vnode.componentInstance = oldVnode.componentInstance
+ updateChildComponent(
+ child,
+ options.propsData, // updated props
+ options.listeners, // updated listeners
+ vnode, // new parent vnode
+ options.children // new children
+ )
+ },
+
+ insert (vnode: MountedComponentVNode) {
+ const { context, componentInstance } = vnode
+ if (!componentInstance._isMounted) {
+ componentInstance._isMounted = true
+ callHook(componentInstance, 'mounted')
+ }
+ if (vnode.data.keepAlive) {
+ if (context._isMounted) {
+ // vue-router#1212
+ // During updates, a kept-alive component's child components may
+ // change, so directly walking the tree here may call activated hooks
+ // on incorrect children. Instead we push them into a queue which will
+ // be processed after the whole patch process ended.
+ queueActivatedComponent(componentInstance)
+ } else {
+ activateChildComponent(componentInstance, true /* direct */)
+ }
+ }
+ },
+
+ destroy (vnode: MountedComponentVNode) {
+ const { componentInstance } = vnode
+ if (!componentInstance._isDestroyed) {
+ if (!vnode.data.keepAlive) {
+ componentInstance.$destroy()
+ } else {
+ deactivateChildComponent(componentInstance, true /* direct */)
+ }
+ }
+ }
+}
+
+const hooksToMerge = Object.keys(componentVNodeHooks)
+
+export function createComponent (
+ Ctor: Class<Component> | Function | Object | void,
+ data: ?VNodeData,
+ context: Component,
+ children: ?Array<VNode>,
+ tag?: string
+): VNode | Array<VNode> | void {
+ if (isUndef(Ctor)) {
+ return
+ }
+
+ const baseCtor = context.$options._base
+
+ // plain options object: turn it into a constructor
+ if (isObject(Ctor)) {
+ Ctor = baseCtor.extend(Ctor)
+ }
+
+ // if at this stage it's not a constructor or an async component factory,
+ // reject.
+ if (typeof Ctor !== 'function') {
+ if (process.env.NODE_ENV !== 'production') {
+ warn(`Invalid Component definition: ${String(Ctor)}`, context)
+ }
+ return
+ }
+
+ // async component
+ let asyncFactory
+ if (isUndef(Ctor.cid)) {
+ asyncFactory = Ctor
+ Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context)
+ if (Ctor === undefined) {
+ // return a placeholder node for async component, which is rendered
+ // as a comment node but preserves all the raw information for the node.
+ // the information will be used for async server-rendering and hydration.
+ return createAsyncPlaceholder(
+ asyncFactory,
+ data,
+ context,
+ children,
+ tag
+ )
+ }
+ }
+
+ data = data || {}
+
+ // resolve constructor options in case global mixins are applied after
+ // component constructor creation
+ resolveConstructorOptions(Ctor)
+
+ // transform component v-model data into props & events
+ if (isDef(data.model)) {
+ transformModel(Ctor.options, data)
+ }
+
+ // extract props
+ const propsData = extractPropsFromVNodeData(data, Ctor, tag)
+
+ // functional component
+ if (isTrue(Ctor.options.functional)) {
+ return createFunctionalComponent(Ctor, propsData, data, context, children)
+ }
+
+ // extract listeners, since these needs to be treated as
+ // child component listeners instead of DOM listeners
+ const listeners = data.on
+ // replace with listeners with .native modifier
+ // so it gets processed during parent component patch.
+ data.on = data.nativeOn
+
+ if (isTrue(Ctor.options.abstract)) {
+ // abstract components do not keep anything
+ // other than props & listeners & slot
+
+ // work around flow
+ const slot = data.slot
+ data = {}
+ if (slot) {
+ data.slot = slot
+ }
+ }
+
+ // install component management hooks onto the placeholder node
+ installComponentHooks(data)
+
+ // return a placeholder vnode
+ const name = Ctor.options.name || tag
+ const vnode = new VNode(
+ `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
+ data, undefined, undefined, undefined, context,
+ { Ctor, propsData, listeners, tag, children },
+ asyncFactory
+ )
+
+ // Weex specific: invoke recycle-list optimized @render function for
+ // extracting cell-slot template.
+ // https://github.com/Hanks10100/weex-native-directive/tree/master/component
+ /* istanbul ignore if */
+ if (__WEEX__ && isRecyclableComponent(vnode)) {
+ return renderRecyclableComponentTemplate(vnode)
+ }
+
+ return vnode
+}
+
+export function createComponentInstanceForVnode (
+ vnode: any, // we know it's MountedComponentVNode but flow doesn't
+ parent: any, // activeInstance in lifecycle state
+ parentElm?: ?Node,
+ refElm?: ?Node
+): Component {
+ const options: InternalComponentOptions = {
+ _isComponent: true,
+ parent,
+ _parentVnode: vnode,
+ _parentElm: parentElm || null,
+ _refElm: refElm || null
+ }
+ // check inline-template render functions
+ const inlineTemplate = vnode.data.inlineTemplate
+ if (isDef(inlineTemplate)) {
+ options.render = inlineTemplate.render
+ options.staticRenderFns = inlineTemplate.staticRenderFns
+ }
+ return new vnode.componentOptions.Ctor(options)
+}
+
+function installComponentHooks (data: VNodeData) {
+ const hooks = data.hook || (data.hook = {})
+ for (let i = 0; i < hooksToMerge.length; i++) {
+ const key = hooksToMerge[i]
+ hooks[key] = componentVNodeHooks[key]
+ }
+}
+
+// transform component v-model info (value and callback) into
+// prop and event handler respectively.
+function transformModel (options, data: any) {
+ const prop = (options.model && options.model.prop) || 'value'
+ const event = (options.model && options.model.event) || 'input'
+ ;(data.props || (data.props = {}))[prop] = data.model.value
+ const on = data.on || (data.on = {})
+ if (isDef(on[event])) {
+ on[event] = [data.model.callback].concat(on[event])
+ } else {
+ on[event] = data.model.callback
+ }
+}
diff --git a/node_modules/vue/src/core/vdom/create-element.js b/node_modules/vue/src/core/vdom/create-element.js
new file mode 100644
index 00000000..c5cde2c6
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/create-element.js
@@ -0,0 +1,160 @@
+/* @flow */
+
+import config from '../config'
+import VNode, { createEmptyVNode } from './vnode'
+import { createComponent } from './create-component'
+import { traverse } from '../observer/traverse'
+
+import {
+ warn,
+ isDef,
+ isUndef,
+ isTrue,
+ isObject,
+ isPrimitive,
+ resolveAsset
+} from '../util/index'
+
+import {
+ normalizeChildren,
+ simpleNormalizeChildren
+} from './helpers/index'
+
+const SIMPLE_NORMALIZE = 1
+const ALWAYS_NORMALIZE = 2
+
+// wrapper function for providing a more flexible interface
+// without getting yelled at by flow
+export function createElement (
+ context: Component,
+ tag: any,
+ data: any,
+ children: any,
+ normalizationType: any,
+ alwaysNormalize: boolean
+): VNode | Array<VNode> {
+ if (Array.isArray(data) || isPrimitive(data)) {
+ normalizationType = children
+ children = data
+ data = undefined
+ }
+ if (isTrue(alwaysNormalize)) {
+ normalizationType = ALWAYS_NORMALIZE
+ }
+ return _createElement(context, tag, data, children, normalizationType)
+}
+
+export function _createElement (
+ context: Component,
+ tag?: string | Class<Component> | Function | Object,
+ data?: VNodeData,
+ children?: any,
+ normalizationType?: number
+): VNode | Array<VNode> {
+ if (isDef(data) && isDef((data: any).__ob__)) {
+ process.env.NODE_ENV !== 'production' && warn(
+ `Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` +
+ 'Always create fresh vnode data objects in each render!',
+ context
+ )
+ return createEmptyVNode()
+ }
+ // object syntax in v-bind
+ if (isDef(data) && isDef(data.is)) {
+ tag = data.is
+ }
+ if (!tag) {
+ // in case of component :is set to falsy value
+ return createEmptyVNode()
+ }
+ // warn against non-primitive key
+ if (process.env.NODE_ENV !== 'production' &&
+ isDef(data) && isDef(data.key) && !isPrimitive(data.key)
+ ) {
+ if (!__WEEX__ || !('@binding' in data.key)) {
+ warn(
+ 'Avoid using non-primitive value as key, ' +
+ 'use string/number value instead.',
+ context
+ )
+ }
+ }
+ // support single function children as default scoped slot
+ if (Array.isArray(children) &&
+ typeof children[0] === 'function'
+ ) {
+ data = data || {}
+ data.scopedSlots = { default: children[0] }
+ children.length = 0
+ }
+ if (normalizationType === ALWAYS_NORMALIZE) {
+ children = normalizeChildren(children)
+ } else if (normalizationType === SIMPLE_NORMALIZE) {
+ children = simpleNormalizeChildren(children)
+ }
+ let vnode, ns
+ if (typeof tag === 'string') {
+ let Ctor
+ ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)
+ if (config.isReservedTag(tag)) {
+ // platform built-in elements
+ vnode = new VNode(
+ config.parsePlatformTagName(tag), data, children,
+ undefined, undefined, context
+ )
+ } else if (isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
+ // component
+ vnode = createComponent(Ctor, data, context, children, tag)
+ } else {
+ // unknown or unlisted namespaced elements
+ // check at runtime because it may get assigned a namespace when its
+ // parent normalizes children
+ vnode = new VNode(
+ tag, data, children,
+ undefined, undefined, context
+ )
+ }
+ } else {
+ // direct component options / constructor
+ vnode = createComponent(tag, data, context, children)
+ }
+ if (Array.isArray(vnode)) {
+ return vnode
+ } else if (isDef(vnode)) {
+ if (isDef(ns)) applyNS(vnode, ns)
+ if (isDef(data)) registerDeepBindings(data)
+ return vnode
+ } else {
+ return createEmptyVNode()
+ }
+}
+
+function applyNS (vnode, ns, force) {
+ vnode.ns = ns
+ if (vnode.tag === 'foreignObject') {
+ // use default namespace inside foreignObject
+ ns = undefined
+ force = true
+ }
+ if (isDef(vnode.children)) {
+ for (let i = 0, l = vnode.children.length; i < l; i++) {
+ const child = vnode.children[i]
+ if (isDef(child.tag) && (
+ isUndef(child.ns) || (isTrue(force) && child.tag !== 'svg'))) {
+ applyNS(child, ns, force)
+ }
+ }
+ }
+}
+
+// ref #5318
+// necessary to ensure parent re-render when deep bindings like :style and
+// :class are used on slot nodes
+function registerDeepBindings (data) {
+ if (isObject(data.style)) {
+ traverse(data.style)
+ }
+ if (isObject(data.class)) {
+ traverse(data.class)
+ }
+}
diff --git a/node_modules/vue/src/core/vdom/create-functional-component.js b/node_modules/vue/src/core/vdom/create-functional-component.js
new file mode 100644
index 00000000..efed801d
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/create-functional-component.js
@@ -0,0 +1,136 @@
+/* @flow */
+
+import VNode, { cloneVNode } from './vnode'
+import { createElement } from './create-element'
+import { resolveInject } from '../instance/inject'
+import { normalizeChildren } from '../vdom/helpers/normalize-children'
+import { resolveSlots } from '../instance/render-helpers/resolve-slots'
+import { installRenderHelpers } from '../instance/render-helpers/index'
+
+import {
+ isDef,
+ isTrue,
+ hasOwn,
+ camelize,
+ emptyObject,
+ validateProp
+} from '../util/index'
+
+export function FunctionalRenderContext (
+ data: VNodeData,
+ props: Object,
+ children: ?Array<VNode>,
+ parent: Component,
+ Ctor: Class<Component>
+) {
+ const options = Ctor.options
+ // ensure the createElement function in functional components
+ // gets a unique context - this is necessary for correct named slot check
+ let contextVm
+ if (hasOwn(parent, '_uid')) {
+ contextVm = Object.create(parent)
+ // $flow-disable-line
+ contextVm._original = parent
+ } else {
+ // the context vm passed in is a functional context as well.
+ // in this case we want to make sure we are able to get a hold to the
+ // real context instance.
+ contextVm = parent
+ // $flow-disable-line
+ parent = parent._original
+ }
+ const isCompiled = isTrue(options._compiled)
+ const needNormalization = !isCompiled
+
+ this.data = data
+ this.props = props
+ this.children = children
+ this.parent = parent
+ this.listeners = data.on || emptyObject
+ this.injections = resolveInject(options.inject, parent)
+ this.slots = () => resolveSlots(children, parent)
+
+ // support for compiled functional template
+ if (isCompiled) {
+ // exposing $options for renderStatic()
+ this.$options = options
+ // pre-resolve slots for renderSlot()
+ this.$slots = this.slots()
+ this.$scopedSlots = data.scopedSlots || emptyObject
+ }
+
+ if (options._scopeId) {
+ this._c = (a, b, c, d) => {
+ const vnode = createElement(contextVm, a, b, c, d, needNormalization)
+ if (vnode && !Array.isArray(vnode)) {
+ vnode.fnScopeId = options._scopeId
+ vnode.fnContext = parent
+ }
+ return vnode
+ }
+ } else {
+ this._c = (a, b, c, d) => createElement(contextVm, a, b, c, d, needNormalization)
+ }
+}
+
+installRenderHelpers(FunctionalRenderContext.prototype)
+
+export function createFunctionalComponent (
+ Ctor: Class<Component>,
+ propsData: ?Object,
+ data: VNodeData,
+ contextVm: Component,
+ children: ?Array<VNode>
+): VNode | Array<VNode> | void {
+ const options = Ctor.options
+ const props = {}
+ const propOptions = options.props
+ if (isDef(propOptions)) {
+ for (const key in propOptions) {
+ props[key] = validateProp(key, propOptions, propsData || emptyObject)
+ }
+ } else {
+ if (isDef(data.attrs)) mergeProps(props, data.attrs)
+ if (isDef(data.props)) mergeProps(props, data.props)
+ }
+
+ const renderContext = new FunctionalRenderContext(
+ data,
+ props,
+ children,
+ contextVm,
+ Ctor
+ )
+
+ const vnode = options.render.call(null, renderContext._c, renderContext)
+
+ if (vnode instanceof VNode) {
+ return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options)
+ } else if (Array.isArray(vnode)) {
+ const vnodes = normalizeChildren(vnode) || []
+ const res = new Array(vnodes.length)
+ for (let i = 0; i < vnodes.length; i++) {
+ res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options)
+ }
+ return res
+ }
+}
+
+function cloneAndMarkFunctionalResult (vnode, data, contextVm, options) {
+ // #7817 clone node before setting fnContext, otherwise if the node is reused
+ // (e.g. it was from a cached normal slot) the fnContext causes named slots
+ // that should not be matched to match.
+ const clone = cloneVNode(vnode)
+ clone.fnContext = contextVm
+ clone.fnOptions = options
+ if (data.slot) {
+ (clone.data || (clone.data = {})).slot = data.slot
+ }
+ return clone
+}
+
+function mergeProps (to, from) {
+ for (const key in from) {
+ to[camelize(key)] = from[key]
+ }
+}
diff --git a/node_modules/vue/src/core/vdom/helpers/extract-props.js b/node_modules/vue/src/core/vdom/helpers/extract-props.js
new file mode 100644
index 00000000..f2a41661
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/helpers/extract-props.js
@@ -0,0 +1,75 @@
+/* @flow */
+
+import {
+ tip,
+ hasOwn,
+ isDef,
+ isUndef,
+ hyphenate,
+ formatComponentName
+} from 'core/util/index'
+
+export function extractPropsFromVNodeData (
+ data: VNodeData,
+ Ctor: Class<Component>,
+ tag?: string
+): ?Object {
+ // we are only extracting raw values here.
+ // validation and default values are handled in the child
+ // component itself.
+ const propOptions = Ctor.options.props
+ if (isUndef(propOptions)) {
+ return
+ }
+ const res = {}
+ const { attrs, props } = data
+ if (isDef(attrs) || isDef(props)) {
+ for (const key in propOptions) {
+ const altKey = hyphenate(key)
+ if (process.env.NODE_ENV !== 'production') {
+ const keyInLowerCase = key.toLowerCase()
+ if (
+ key !== keyInLowerCase &&
+ attrs && hasOwn(attrs, keyInLowerCase)
+ ) {
+ tip(
+ `Prop "${keyInLowerCase}" is passed to component ` +
+ `${formatComponentName(tag || Ctor)}, but the declared prop name is` +
+ ` "${key}". ` +
+ `Note that HTML attributes are case-insensitive and camelCased ` +
+ `props need to use their kebab-case equivalents when using in-DOM ` +
+ `templates. You should probably use "${altKey}" instead of "${key}".`
+ )
+ }
+ }
+ checkProp(res, props, key, altKey, true) ||
+ checkProp(res, attrs, key, altKey, false)
+ }
+ }
+ return res
+}
+
+function checkProp (
+ res: Object,
+ hash: ?Object,
+ key: string,
+ altKey: string,
+ preserve: boolean
+): boolean {
+ if (isDef(hash)) {
+ if (hasOwn(hash, key)) {
+ res[key] = hash[key]
+ if (!preserve) {
+ delete hash[key]
+ }
+ return true
+ } else if (hasOwn(hash, altKey)) {
+ res[key] = hash[altKey]
+ if (!preserve) {
+ delete hash[altKey]
+ }
+ return true
+ }
+ }
+ return false
+}
diff --git a/node_modules/vue/src/core/vdom/helpers/get-first-component-child.js b/node_modules/vue/src/core/vdom/helpers/get-first-component-child.js
new file mode 100644
index 00000000..f8649dd8
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/helpers/get-first-component-child.js
@@ -0,0 +1,15 @@
+/* @flow */
+
+import { isDef } from 'shared/util'
+import { isAsyncPlaceholder } from './is-async-placeholder'
+
+export function getFirstComponentChild (children: ?Array<VNode>): ?VNode {
+ if (Array.isArray(children)) {
+ for (let i = 0; i < children.length; i++) {
+ const c = children[i]
+ if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
+ return c
+ }
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/vdom/helpers/index.js b/node_modules/vue/src/core/vdom/helpers/index.js
new file mode 100644
index 00000000..320cf4c4
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/helpers/index.js
@@ -0,0 +1,9 @@
+/* @flow */
+
+export * from './merge-hook'
+export * from './extract-props'
+export * from './update-listeners'
+export * from './normalize-children'
+export * from './resolve-async-component'
+export * from './get-first-component-child'
+export * from './is-async-placeholder'
diff --git a/node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js b/node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js
new file mode 100644
index 00000000..6c4a6596
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js
@@ -0,0 +1,5 @@
+/* @flow */
+
+export function isAsyncPlaceholder (node: VNode): boolean {
+ return node.isComment && node.asyncFactory
+}
diff --git a/node_modules/vue/src/core/vdom/helpers/merge-hook.js b/node_modules/vue/src/core/vdom/helpers/merge-hook.js
new file mode 100644
index 00000000..0bb96e8b
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/helpers/merge-hook.js
@@ -0,0 +1,38 @@
+/* @flow */
+
+import VNode from '../vnode'
+import { createFnInvoker } from './update-listeners'
+import { remove, isDef, isUndef, isTrue } from 'shared/util'
+
+export function mergeVNodeHook (def: Object, hookKey: string, hook: Function) {
+ if (def instanceof VNode) {
+ def = def.data.hook || (def.data.hook = {})
+ }
+ let invoker
+ const oldHook = def[hookKey]
+
+ function wrappedHook () {
+ hook.apply(this, arguments)
+ // important: remove merged hook to ensure it's called only once
+ // and prevent memory leak
+ remove(invoker.fns, wrappedHook)
+ }
+
+ if (isUndef(oldHook)) {
+ // no existing hook
+ invoker = createFnInvoker([wrappedHook])
+ } else {
+ /* istanbul ignore if */
+ if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {
+ // already a merged invoker
+ invoker = oldHook
+ invoker.fns.push(wrappedHook)
+ } else {
+ // existing plain hook
+ invoker = createFnInvoker([oldHook, wrappedHook])
+ }
+ }
+
+ invoker.merged = true
+ def[hookKey] = invoker
+}
diff --git a/node_modules/vue/src/core/vdom/helpers/normalize-children.js b/node_modules/vue/src/core/vdom/helpers/normalize-children.js
new file mode 100644
index 00000000..a4622ef4
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/helpers/normalize-children.js
@@ -0,0 +1,89 @@
+/* @flow */
+
+import VNode, { createTextVNode } from 'core/vdom/vnode'
+import { isFalse, isTrue, isDef, isUndef, isPrimitive } from 'shared/util'
+
+// The template compiler attempts to minimize the need for normalization by
+// statically analyzing the template at compile time.
+//
+// For plain HTML markup, normalization can be completely skipped because the
+// generated render function is guaranteed to return Array<VNode>. There are
+// two cases where extra normalization is needed:
+
+// 1. When the children contains components - because a functional component
+// may return an Array instead of a single root. In this case, just a simple
+// normalization is needed - if any child is an Array, we flatten the whole
+// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep
+// because functional components already normalize their own children.
+export function simpleNormalizeChildren (children: any) {
+ for (let i = 0; i < children.length; i++) {
+ if (Array.isArray(children[i])) {
+ return Array.prototype.concat.apply([], children)
+ }
+ }
+ return children
+}
+
+// 2. When the children contains constructs that always generated nested Arrays,
+// e.g. <template>, <slot>, v-for, or when the children is provided by user
+// with hand-written render functions / JSX. In such cases a full normalization
+// is needed to cater to all possible types of children values.
+export function normalizeChildren (children: any): ?Array<VNode> {
+ return isPrimitive(children)
+ ? [createTextVNode(children)]
+ : Array.isArray(children)
+ ? normalizeArrayChildren(children)
+ : undefined
+}
+
+function isTextNode (node): boolean {
+ return isDef(node) && isDef(node.text) && isFalse(node.isComment)
+}
+
+function normalizeArrayChildren (children: any, nestedIndex?: string): Array<VNode> {
+ const res = []
+ let i, c, lastIndex, last
+ for (i = 0; i < children.length; i++) {
+ c = children[i]
+ if (isUndef(c) || typeof c === 'boolean') continue
+ lastIndex = res.length - 1
+ last = res[lastIndex]
+ // nested
+ if (Array.isArray(c)) {
+ if (c.length > 0) {
+ c = normalizeArrayChildren(c, `${nestedIndex || ''}_${i}`)
+ // merge adjacent text nodes
+ if (isTextNode(c[0]) && isTextNode(last)) {
+ res[lastIndex] = createTextVNode(last.text + (c[0]: any).text)
+ c.shift()
+ }
+ res.push.apply(res, c)
+ }
+ } else if (isPrimitive(c)) {
+ if (isTextNode(last)) {
+ // merge adjacent text nodes
+ // this is necessary for SSR hydration because text nodes are
+ // essentially merged when rendered to HTML strings
+ res[lastIndex] = createTextVNode(last.text + c)
+ } else if (c !== '') {
+ // convert primitive to vnode
+ res.push(createTextVNode(c))
+ }
+ } else {
+ if (isTextNode(c) && isTextNode(last)) {
+ // merge adjacent text nodes
+ res[lastIndex] = createTextVNode(last.text + c.text)
+ } else {
+ // default key for nested array children (likely generated by v-for)
+ if (isTrue(children._isVList) &&
+ isDef(c.tag) &&
+ isUndef(c.key) &&
+ isDef(nestedIndex)) {
+ c.key = `__vlist${nestedIndex}_${i}__`
+ }
+ res.push(c)
+ }
+ }
+ }
+ return res
+}
diff --git a/node_modules/vue/src/core/vdom/helpers/resolve-async-component.js b/node_modules/vue/src/core/vdom/helpers/resolve-async-component.js
new file mode 100644
index 00000000..99ce5ce4
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/helpers/resolve-async-component.js
@@ -0,0 +1,140 @@
+/* @flow */
+
+import {
+ warn,
+ once,
+ isDef,
+ isUndef,
+ isTrue,
+ isObject,
+ hasSymbol
+} from 'core/util/index'
+
+import { createEmptyVNode } from 'core/vdom/vnode'
+
+function ensureCtor (comp: any, base) {
+ if (
+ comp.__esModule ||
+ (hasSymbol && comp[Symbol.toStringTag] === 'Module')
+ ) {
+ comp = comp.default
+ }
+ return isObject(comp)
+ ? base.extend(comp)
+ : comp
+}
+
+export function createAsyncPlaceholder (
+ factory: Function,
+ data: ?VNodeData,
+ context: Component,
+ children: ?Array<VNode>,
+ tag: ?string
+): VNode {
+ const node = createEmptyVNode()
+ node.asyncFactory = factory
+ node.asyncMeta = { data, context, children, tag }
+ return node
+}
+
+export function resolveAsyncComponent (
+ factory: Function,
+ baseCtor: Class<Component>,
+ context: Component
+): Class<Component> | void {
+ if (isTrue(factory.error) && isDef(factory.errorComp)) {
+ return factory.errorComp
+ }
+
+ if (isDef(factory.resolved)) {
+ return factory.resolved
+ }
+
+ if (isTrue(factory.loading) && isDef(factory.loadingComp)) {
+ return factory.loadingComp
+ }
+
+ if (isDef(factory.contexts)) {
+ // already pending
+ factory.contexts.push(context)
+ } else {
+ const contexts = factory.contexts = [context]
+ let sync = true
+
+ const forceRender = () => {
+ for (let i = 0, l = contexts.length; i < l; i++) {
+ contexts[i].$forceUpdate()
+ }
+ }
+
+ const resolve = once((res: Object | Class<Component>) => {
+ // cache resolved
+ factory.resolved = ensureCtor(res, baseCtor)
+ // invoke callbacks only if this is not a synchronous resolve
+ // (async resolves are shimmed as synchronous during SSR)
+ if (!sync) {
+ forceRender()
+ }
+ })
+
+ const reject = once(reason => {
+ process.env.NODE_ENV !== 'production' && warn(
+ `Failed to resolve async component: ${String(factory)}` +
+ (reason ? `\nReason: ${reason}` : '')
+ )
+ if (isDef(factory.errorComp)) {
+ factory.error = true
+ forceRender()
+ }
+ })
+
+ const res = factory(resolve, reject)
+
+ if (isObject(res)) {
+ if (typeof res.then === 'function') {
+ // () => Promise
+ if (isUndef(factory.resolved)) {
+ res.then(resolve, reject)
+ }
+ } else if (isDef(res.component) && typeof res.component.then === 'function') {
+ res.component.then(resolve, reject)
+
+ if (isDef(res.error)) {
+ factory.errorComp = ensureCtor(res.error, baseCtor)
+ }
+
+ if (isDef(res.loading)) {
+ factory.loadingComp = ensureCtor(res.loading, baseCtor)
+ if (res.delay === 0) {
+ factory.loading = true
+ } else {
+ setTimeout(() => {
+ if (isUndef(factory.resolved) && isUndef(factory.error)) {
+ factory.loading = true
+ forceRender()
+ }
+ }, res.delay || 200)
+ }
+ }
+
+ if (isDef(res.timeout)) {
+ setTimeout(() => {
+ if (isUndef(factory.resolved)) {
+ reject(
+ process.env.NODE_ENV !== 'production'
+ ? `timeout (${res.timeout}ms)`
+ : null
+ )
+ }
+ }, res.timeout)
+ }
+ }
+ }
+
+ sync = false
+ // return in case resolved synchronously
+ return factory.loading
+ ? factory.loadingComp
+ : factory.resolved
+ }
+}
diff --git a/node_modules/vue/src/core/vdom/helpers/update-listeners.js b/node_modules/vue/src/core/vdom/helpers/update-listeners.js
new file mode 100644
index 00000000..11c5a2cd
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/helpers/update-listeners.js
@@ -0,0 +1,83 @@
+/* @flow */
+
+import { warn } from 'core/util/index'
+import { cached, isUndef, isPlainObject } from 'shared/util'
+
+const normalizeEvent = cached((name: string): {
+ name: string,
+ once: boolean,
+ capture: boolean,
+ passive: boolean,
+ handler?: Function,
+ params?: Array<any>
+} => {
+ const passive = name.charAt(0) === '&'
+ name = passive ? name.slice(1) : name
+ const once = name.charAt(0) === '~' // Prefixed last, checked first
+ name = once ? name.slice(1) : name
+ const capture = name.charAt(0) === '!'
+ name = capture ? name.slice(1) : name
+ return {
+ name,
+ once,
+ capture,
+ passive
+ }
+})
+
+export function createFnInvoker (fns: Function | Array<Function>): Function {
+ function invoker () {
+ const fns = invoker.fns
+ if (Array.isArray(fns)) {
+ const cloned = fns.slice()
+ for (let i = 0; i < cloned.length; i++) {
+ cloned[i].apply(null, arguments)
+ }
+ } else {
+ // return handler return value for single handlers
+ return fns.apply(null, arguments)
+ }
+ }
+ invoker.fns = fns
+ return invoker
+}
+
+export function updateListeners (
+ on: Object,
+ oldOn: Object,
+ add: Function,
+ remove: Function,
+ vm: Component
+) {
+ let name, def, cur, old, event
+ for (name in on) {
+ def = cur = on[name]
+ old = oldOn[name]
+ event = normalizeEvent(name)
+ /* istanbul ignore if */
+ if (__WEEX__ && isPlainObject(def)) {
+ cur = def.handler
+ event.params = def.params
+ }
+ if (isUndef(cur)) {
+ process.env.NODE_ENV !== 'production' && warn(
+ `Invalid handler for event "${event.name}": got ` + String(cur),
+ vm
+ )
+ } else if (isUndef(old)) {
+ if (isUndef(cur.fns)) {
+ cur = on[name] = createFnInvoker(cur)
+ }
+ add(event.name, cur, event.once, event.capture, event.passive, event.params)
+ } else if (cur !== old) {
+ old.fns = cur
+ on[name] = old
+ }
+ }
+ for (name in oldOn) {
+ if (isUndef(on[name])) {
+ event = normalizeEvent(name)
+ remove(event.name, oldOn[name], event.capture)
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/vdom/modules/directives.js b/node_modules/vue/src/core/vdom/modules/directives.js
new file mode 100644
index 00000000..639982fa
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/modules/directives.js
@@ -0,0 +1,119 @@
+/* @flow */
+
+import { emptyNode } from 'core/vdom/patch'
+import { resolveAsset, handleError } from 'core/util/index'
+import { mergeVNodeHook } from 'core/vdom/helpers/index'
+
+export default {
+ create: updateDirectives,
+ update: updateDirectives,
+ destroy: function unbindDirectives (vnode: VNodeWithData) {
+ updateDirectives(vnode, emptyNode)
+ }
+}
+
+function updateDirectives (oldVnode: VNodeWithData, vnode: VNodeWithData) {
+ if (oldVnode.data.directives || vnode.data.directives) {
+ _update(oldVnode, vnode)
+ }
+}
+
+function _update (oldVnode, vnode) {
+ const isCreate = oldVnode === emptyNode
+ const isDestroy = vnode === emptyNode
+ const oldDirs = normalizeDirectives(oldVnode.data.directives, oldVnode.context)
+ const newDirs = normalizeDirectives(vnode.data.directives, vnode.context)
+
+ const dirsWithInsert = []
+ const dirsWithPostpatch = []
+
+ let key, oldDir, dir
+ for (key in newDirs) {
+ oldDir = oldDirs[key]
+ dir = newDirs[key]
+ if (!oldDir) {
+ // new directive, bind
+ callHook(dir, 'bind', vnode, oldVnode)
+ if (dir.def && dir.def.inserted) {
+ dirsWithInsert.push(dir)
+ }
+ } else {
+ // existing directive, update
+ dir.oldValue = oldDir.value
+ callHook(dir, 'update', vnode, oldVnode)
+ if (dir.def && dir.def.componentUpdated) {
+ dirsWithPostpatch.push(dir)
+ }
+ }
+ }
+
+ if (dirsWithInsert.length) {
+ const callInsert = () => {
+ for (let i = 0; i < dirsWithInsert.length; i++) {
+ callHook(dirsWithInsert[i], 'inserted', vnode, oldVnode)
+ }
+ }
+ if (isCreate) {
+ mergeVNodeHook(vnode, 'insert', callInsert)
+ } else {
+ callInsert()
+ }
+ }
+
+ if (dirsWithPostpatch.length) {
+ mergeVNodeHook(vnode, 'postpatch', () => {
+ for (let i = 0; i < dirsWithPostpatch.length; i++) {
+ callHook(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode)
+ }
+ })
+ }
+
+ if (!isCreate) {
+ for (key in oldDirs) {
+ if (!newDirs[key]) {
+ // no longer present, unbind
+ callHook(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy)
+ }
+ }
+ }
+}
+
+const emptyModifiers = Object.create(null)
+
+function normalizeDirectives (
+ dirs: ?Array<VNodeDirective>,
+ vm: Component
+): { [key: string]: VNodeDirective } {
+ const res = Object.create(null)
+ if (!dirs) {
+ // $flow-disable-line
+ return res
+ }
+ let i, dir
+ for (i = 0; i < dirs.length; i++) {
+ dir = dirs[i]
+ if (!dir.modifiers) {
+ // $flow-disable-line
+ dir.modifiers = emptyModifiers
+ }
+ res[getRawDirName(dir)] = dir
+ dir.def = resolveAsset(vm.$options, 'directives', dir.name, true)
+ }
+ // $flow-disable-line
+ return res
+}
+
+function getRawDirName (dir: VNodeDirective): string {
+ return dir.rawName || `${dir.name}.${Object.keys(dir.modifiers || {}).join('.')}`
+}
+
+function callHook (dir, hook, vnode, oldVnode, isDestroy) {
+ const fn = dir.def && dir.def[hook]
+ if (fn) {
+ try {
+ fn(vnode.elm, dir, vnode, oldVnode, isDestroy)
+ } catch (e) {
+ handleError(e, vnode.context, `directive ${dir.name} ${hook} hook`)
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/vdom/modules/index.js b/node_modules/vue/src/core/vdom/modules/index.js
new file mode 100644
index 00000000..727c8646
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/modules/index.js
@@ -0,0 +1,7 @@
+import directives from './directives'
+import ref from './ref'
+
+export default [
+ ref,
+ directives
+]
diff --git a/node_modules/vue/src/core/vdom/modules/ref.js b/node_modules/vue/src/core/vdom/modules/ref.js
new file mode 100644
index 00000000..aa9bdcfc
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/modules/ref.js
@@ -0,0 +1,45 @@
+/* @flow */
+
+import { remove, isDef } from 'shared/util'
+
+export default {
+ create (_: any, vnode: VNodeWithData) {
+ registerRef(vnode)
+ },
+ update (oldVnode: VNodeWithData, vnode: VNodeWithData) {
+ if (oldVnode.data.ref !== vnode.data.ref) {
+ registerRef(oldVnode, true)
+ registerRef(vnode)
+ }
+ },
+ destroy (vnode: VNodeWithData) {
+ registerRef(vnode, true)
+ }
+}
+
+export function registerRef (vnode: VNodeWithData, isRemoval: ?boolean) {
+ const key = vnode.data.ref
+ if (!isDef(key)) return
+
+ const vm = vnode.context
+ const ref = vnode.componentInstance || vnode.elm
+ const refs = vm.$refs
+ if (isRemoval) {
+ if (Array.isArray(refs[key])) {
+ remove(refs[key], ref)
+ } else if (refs[key] === ref) {
+ refs[key] = undefined
+ }
+ } else {
+ if (vnode.data.refInFor) {
+ if (!Array.isArray(refs[key])) {
+ refs[key] = [ref]
+ } else if (refs[key].indexOf(ref) < 0) {
+ // $flow-disable-line
+ refs[key].push(ref)
+ }
+ } else {
+ refs[key] = ref
+ }
+ }
+}
diff --git a/node_modules/vue/src/core/vdom/patch.js b/node_modules/vue/src/core/vdom/patch.js
new file mode 100644
index 00000000..9f3bcc65
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/patch.js
@@ -0,0 +1,787 @@
+/**
+ * Virtual DOM patching algorithm based on Snabbdom by
+ * Simon Friis Vindum (@paldepind)
+ * Licensed under the MIT License
+ * https://github.com/paldepind/snabbdom/blob/master/LICENSE
+ *
+ * modified by Evan You (@yyx990803)
+ *
+ * Not type-checking this because this file is perf-critical and the cost
+ * of making flow understand it is not worth it.
+ */
+
+import VNode, { cloneVNode } from './vnode'
+import config from '../config'
+import { SSR_ATTR } from 'shared/constants'
+import { registerRef } from './modules/ref'
+import { traverse } from '../observer/traverse'
+import { activeInstance } from '../instance/lifecycle'
+import { isTextInputType } from 'web/util/element'
+
+import {
+ warn,
+ isDef,
+ isUndef,
+ isTrue,
+ makeMap,
+ isRegExp,
+ isPrimitive
+} from '../util/index'
+
+export const emptyNode = new VNode('', {}, [])
+
+const hooks = ['create', 'activate', 'update', 'remove', 'destroy']
+
+function sameVnode (a, b) {
+ return (
+ a.key === b.key && (
+ (
+ a.tag === b.tag &&
+ a.isComment === b.isComment &&
+ isDef(a.data) === isDef(b.data) &&
+ sameInputType(a, b)
+ ) || (
+ isTrue(a.isAsyncPlaceholder) &&
+ a.asyncFactory === b.asyncFactory &&
+ isUndef(b.asyncFactory.error)
+ )
+ )
+ )
+}
+
+function sameInputType (a, b) {
+ if (a.tag !== 'input') return true
+ let i
+ const typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type
+ const typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type
+ return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)
+}
+
+function createKeyToOldIdx (children, beginIdx, endIdx) {
+ let i, key
+ const map = {}
+ for (i = beginIdx; i <= endIdx; ++i) {
+ key = children[i].key
+ if (isDef(key)) map[key] = i
+ }
+ return map
+}
+
+export function createPatchFunction (backend) {
+ let i, j
+ const cbs = {}
+
+ const { modules, nodeOps } = backend
+
+ for (i = 0; i < hooks.length; ++i) {
+ cbs[hooks[i]] = []
+ for (j = 0; j < modules.length; ++j) {
+ if (isDef(modules[j][hooks[i]])) {
+ cbs[hooks[i]].push(modules[j][hooks[i]])
+ }
+ }
+ }
+
+ function emptyNodeAt (elm) {
+ return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)
+ }
+
+ function createRmCb (childElm, listeners) {
+ function remove () {
+ if (--remove.listeners === 0) {
+ removeNode(childElm)
+ }
+ }
+ remove.listeners = listeners
+ return remove
+ }
+
+ function removeNode (el) {
+ const parent = nodeOps.parentNode(el)
+ // element may have already been removed due to v-html / v-text
+ if (isDef(parent)) {
+ nodeOps.removeChild(parent, el)
+ }
+ }
+
+ function isUnknownElement (vnode, inVPre) {
+ return (
+ !inVPre &&
+ !vnode.ns &&
+ !(
+ config.ignoredElements.length &&
+ config.ignoredElements.some(ignore => {
+ return isRegExp(ignore)
+ ? ignore.test(vnode.tag)
+ : ignore === vnode.tag
+ })
+ ) &&
+ config.isUnknownElement(vnode.tag)
+ )
+ }
+
+ let creatingElmInVPre = 0
+
+ function createElm (
+ vnode,
+ insertedVnodeQueue,
+ parentElm,
+ refElm,
+ nested,
+ ownerArray,
+ index
+ ) {
+ if (isDef(vnode.elm) && isDef(ownerArray)) {
+ // This vnode was used in a previous render!
+ // now it's used as a new node, overwriting its elm would cause
+ // potential patch errors down the road when it's used as an insertion
+ // reference node. Instead, we clone the node on-demand before creating
+ // associated DOM element for it.
+ vnode = ownerArray[index] = cloneVNode(vnode)
+ }
+
+ vnode.isRootInsert = !nested // for transition enter check
+ if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {
+ return
+ }
+
+ const data = vnode.data
+ const children = vnode.children
+ const tag = vnode.tag
+ if (isDef(tag)) {
+ if (process.env.NODE_ENV !== 'production') {
+ if (data && data.pre) {
+ creatingElmInVPre++
+ }
+ if (isUnknownElement(vnode, creatingElmInVPre)) {
+ warn(
+ 'Unknown custom element: <' + tag + '> - did you ' +
+ 'register the component correctly? For recursive components, ' +
+ 'make sure to provide the "name" option.',
+ vnode.context
+ )
+ }
+ }
+
+ vnode.elm = vnode.ns
+ ? nodeOps.createElementNS(vnode.ns, tag)
+ : nodeOps.createElement(tag, vnode)
+ setScope(vnode)
+
+ /* istanbul ignore if */
+ if (__WEEX__) {
+ // in Weex, the default insertion order is parent-first.
+ // List items can be optimized to use children-first insertion
+ // with append="tree".
+ const appendAsTree = isDef(data) && isTrue(data.appendAsTree)
+ if (!appendAsTree) {
+ if (isDef(data)) {
+ invokeCreateHooks(vnode, insertedVnodeQueue)
+ }
+ insert(parentElm, vnode.elm, refElm)
+ }
+ createChildren(vnode, children, insertedVnodeQueue)
+ if (appendAsTree) {
+ if (isDef(data)) {
+ invokeCreateHooks(vnode, insertedVnodeQueue)
+ }
+ insert(parentElm, vnode.elm, refElm)
+ }
+ } else {
+ createChildren(vnode, children, insertedVnodeQueue)
+ if (isDef(data)) {
+ invokeCreateHooks(vnode, insertedVnodeQueue)
+ }
+ insert(parentElm, vnode.elm, refElm)
+ }
+
+ if (process.env.NODE_ENV !== 'production' && data && data.pre) {
+ creatingElmInVPre--
+ }
+ } else if (isTrue(vnode.isComment)) {
+ vnode.elm = nodeOps.createComment(vnode.text)
+ insert(parentElm, vnode.elm, refElm)
+ } else {
+ vnode.elm = nodeOps.createTextNode(vnode.text)
+ insert(parentElm, vnode.elm, refElm)
+ }
+ }
+
+ function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
+ let i = vnode.data
+ if (isDef(i)) {
+ const isReactivated = isDef(vnode.componentInstance) && i.keepAlive
+ if (isDef(i = i.hook) && isDef(i = i.init)) {
+ i(vnode, false /* hydrating */, parentElm, refElm)
+ }
+ // after calling the init hook, if the vnode is a child component
+ // it should've created a child instance and mounted it. the child
+ // component also has set the placeholder vnode's elm.
+ // in that case we can just return the element and be done.
+ if (isDef(vnode.componentInstance)) {
+ initComponent(vnode, insertedVnodeQueue)
+ if (isTrue(isReactivated)) {
+ reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm)
+ }
+ return true
+ }
+ }
+ }
+
+ function initComponent (vnode, insertedVnodeQueue) {
+ if (isDef(vnode.data.pendingInsert)) {
+ insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert)
+ vnode.data.pendingInsert = null
+ }
+ vnode.elm = vnode.componentInstance.$el
+ if (isPatchable(vnode)) {
+ invokeCreateHooks(vnode, insertedVnodeQueue)
+ setScope(vnode)
+ } else {
+ // empty component root.
+ // skip all element-related modules except for ref (#3455)
+ registerRef(vnode)
+ // make sure to invoke the insert hook
+ insertedVnodeQueue.push(vnode)
+ }
+ }
+
+ function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
+ let i
+ // hack for #4339: a reactivated component with inner transition
+ // does not trigger because the inner node's created hooks are not called
+ // again. It's not ideal to involve module-specific logic in here but
+ // there doesn't seem to be a better way to do it.
+ let innerNode = vnode
+ while (innerNode.componentInstance) {
+ innerNode = innerNode.componentInstance._vnode
+ if (isDef(i = innerNode.data) && isDef(i = i.transition)) {
+ for (i = 0; i < cbs.activate.length; ++i) {
+ cbs.activate[i](emptyNode, innerNode)
+ }
+ insertedVnodeQueue.push(innerNode)
+ break
+ }
+ }
+ // unlike a newly created component,
+ // a reactivated keep-alive component doesn't insert itself
+ insert(parentElm, vnode.elm, refElm)
+ }
+
+ function insert (parent, elm, ref) {
+ if (isDef(parent)) {
+ if (isDef(ref)) {
+ if (ref.parentNode === parent) {
+ nodeOps.insertBefore(parent, elm, ref)
+ }
+ } else {
+ nodeOps.appendChild(parent, elm)
+ }
+ }
+ }
+
+ function createChildren (vnode, children, insertedVnodeQueue) {
+ if (Array.isArray(children)) {
+ if (process.env.NODE_ENV !== 'production') {
+ checkDuplicateKeys(children)
+ }
+ for (let i = 0; i < children.length; ++i) {
+ createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i)
+ }
+ } else if (isPrimitive(vnode.text)) {
+ nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)))
+ }
+ }
+
+ function isPatchable (vnode) {
+ while (vnode.componentInstance) {
+ vnode = vnode.componentInstance._vnode
+ }
+ return isDef(vnode.tag)
+ }
+
+ function invokeCreateHooks (vnode, insertedVnodeQueue) {
+ for (let i = 0; i < cbs.create.length; ++i) {
+ cbs.create[i](emptyNode, vnode)
+ }
+ i = vnode.data.hook // Reuse variable
+ if (isDef(i)) {
+ if (isDef(i.create)) i.create(emptyNode, vnode)
+ if (isDef(i.insert)) insertedVnodeQueue.push(vnode)
+ }
+ }
+
+ // set scope id attribute for scoped CSS.
+ // this is implemented as a special case to avoid the overhead
+ // of going through the normal attribute patching process.
+ function setScope (vnode) {
+ let i
+ if (isDef(i = vnode.fnScopeId)) {
+ nodeOps.setStyleScope(vnode.elm, i)
+ } else {
+ let ancestor = vnode
+ while (ancestor) {
+ if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) {
+ nodeOps.setStyleScope(vnode.elm, i)
+ }
+ ancestor = ancestor.parent
+ }
+ }
+ // for slot content they should also get the scopeId from the host instance.
+ if (isDef(i = activeInstance) &&
+ i !== vnode.context &&
+ i !== vnode.fnContext &&
+ isDef(i = i.$options._scopeId)
+ ) {
+ nodeOps.setStyleScope(vnode.elm, i)
+ }
+ }
+
+ function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) {
+ for (; startIdx <= endIdx; ++startIdx) {
+ createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm, false, vnodes, startIdx)
+ }
+ }
+
+ function invokeDestroyHook (vnode) {
+ let i, j
+ const data = vnode.data
+ if (isDef(data)) {
+ if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode)
+ for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode)
+ }
+ if (isDef(i = vnode.children)) {
+ for (j = 0; j < vnode.children.length; ++j) {
+ invokeDestroyHook(vnode.children[j])
+ }
+ }
+ }
+
+ function removeVnodes (parentElm, vnodes, startIdx, endIdx) {
+ for (; startIdx <= endIdx; ++startIdx) {
+ const ch = vnodes[startIdx]
+ if (isDef(ch)) {
+ if (isDef(ch.tag)) {
+ removeAndInvokeRemoveHook(ch)
+ invokeDestroyHook(ch)
+ } else { // Text node
+ removeNode(ch.elm)
+ }
+ }
+ }
+ }
+
+ function removeAndInvokeRemoveHook (vnode, rm) {
+ if (isDef(rm) || isDef(vnode.data)) {
+ let i
+ const listeners = cbs.remove.length + 1
+ if (isDef(rm)) {
+ // we have a recursively passed down rm callback
+ // increase the listeners count
+ rm.listeners += listeners
+ } else {
+ // directly removing
+ rm = createRmCb(vnode.elm, listeners)
+ }
+ // recursively invoke hooks on child component root node
+ if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) {
+ removeAndInvokeRemoveHook(i, rm)
+ }
+ for (i = 0; i < cbs.remove.length; ++i) {
+ cbs.remove[i](vnode, rm)
+ }
+ if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {
+ i(vnode, rm)
+ } else {
+ rm()
+ }
+ } else {
+ removeNode(vnode.elm)
+ }
+ }
+
+ function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
+ let oldStartIdx = 0
+ let newStartIdx = 0
+ let oldEndIdx = oldCh.length - 1
+ let oldStartVnode = oldCh[0]
+ let oldEndVnode = oldCh[oldEndIdx]
+ let newEndIdx = newCh.length - 1
+ let newStartVnode = newCh[0]
+ let newEndVnode = newCh[newEndIdx]
+ let oldKeyToIdx, idxInOld, vnodeToMove, refElm
+
+ // removeOnly is a special flag used only by <transition-group>
+ // to ensure removed elements stay in correct relative positions
+ // during leaving transitions
+ const canMove = !removeOnly
+
+ if (process.env.NODE_ENV !== 'production') {
+ checkDuplicateKeys(newCh)
+ }
+
+ while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
+ if (isUndef(oldStartVnode)) {
+ oldStartVnode = oldCh[++oldStartIdx] // Vnode has been moved left
+ } else if (isUndef(oldEndVnode)) {
+ oldEndVnode = oldCh[--oldEndIdx]
+ } else if (sameVnode(oldStartVnode, newStartVnode)) {
+ patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue)
+ oldStartVnode = oldCh[++oldStartIdx]
+ newStartVnode = newCh[++newStartIdx]
+ } else if (sameVnode(oldEndVnode, newEndVnode)) {
+ patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue)
+ oldEndVnode = oldCh[--oldEndIdx]
+ newEndVnode = newCh[--newEndIdx]
+ } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
+ patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue)
+ canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm))
+ oldStartVnode = oldCh[++oldStartIdx]
+ newEndVnode = newCh[--newEndIdx]
+ } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
+ patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue)
+ canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)
+ oldEndVnode = oldCh[--oldEndIdx]
+ newStartVnode = newCh[++newStartIdx]
+ } else {
+ if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
+ idxInOld = isDef(newStartVnode.key)
+ ? oldKeyToIdx[newStartVnode.key]
+ : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)
+ if (isUndef(idxInOld)) { // New element
+ createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
+ } else {
+ vnodeToMove = oldCh[idxInOld]
+ if (sameVnode(vnodeToMove, newStartVnode)) {
+ patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue)
+ oldCh[idxInOld] = undefined
+ canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)
+ } else {
+ // same key but different element. treat as new element
+ createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
+ }
+ }
+ newStartVnode = newCh[++newStartIdx]
+ }
+ }
+ if (oldStartIdx > oldEndIdx) {
+ refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm
+ addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)
+ } else if (newStartIdx > newEndIdx) {
+ removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)
+ }
+ }
+
+ function checkDuplicateKeys (children) {
+ const seenKeys = {}
+ for (let i = 0; i < children.length; i++) {
+ const vnode = children[i]
+ const key = vnode.key
+ if (isDef(key)) {
+ if (seenKeys[key]) {
+ warn(
+ `Duplicate keys detected: '${key}'. This may cause an update error.`,
+ vnode.context
+ )
+ } else {
+ seenKeys[key] = true
+ }
+ }
+ }
+ }
+
+ function findIdxInOld (node, oldCh, start, end) {
+ for (let i = start; i < end; i++) {
+ const c = oldCh[i]
+ if (isDef(c) && sameVnode(node, c)) return i
+ }
+ }
+
+ function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) {
+ if (oldVnode === vnode) {
+ return
+ }
+
+ const elm = vnode.elm = oldVnode.elm
+
+ if (isTrue(oldVnode.isAsyncPlaceholder)) {
+ if (isDef(vnode.asyncFactory.resolved)) {
+ hydrate(oldVnode.elm, vnode, insertedVnodeQueue)
+ } else {
+ vnode.isAsyncPlaceholder = true
+ }
+ return
+ }
+
+ // reuse element for static trees.
+ // note we only do this if the vnode is cloned -
+ // if the new node is not cloned it means the render functions have been
+ // reset by the hot-reload-api and we need to do a proper re-render.
+ if (isTrue(vnode.isStatic) &&
+ isTrue(oldVnode.isStatic) &&
+ vnode.key === oldVnode.key &&
+ (isTrue(vnode.isCloned) || isTrue(vnode.isOnce))
+ ) {
+ vnode.componentInstance = oldVnode.componentInstance
+ return
+ }
+
+ let i
+ const data = vnode.data
+ if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {
+ i(oldVnode, vnode)
+ }
+
+ const oldCh = oldVnode.children
+ const ch = vnode.children
+ if (isDef(data) && isPatchable(vnode)) {
+ for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode)
+ if (isDef(i = data.hook) && isDef(i = i.update)) i(oldVnode, vnode)
+ }
+ if (isUndef(vnode.text)) {
+ if (isDef(oldCh) && isDef(ch)) {
+ if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly)
+ } else if (isDef(ch)) {
+ if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, '')
+ addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue)
+ } else if (isDef(oldCh)) {
+ removeVnodes(elm, oldCh, 0, oldCh.length - 1)
+ } else if (isDef(oldVnode.text)) {
+ nodeOps.setTextContent(elm, '')
+ }
+ } else if (oldVnode.text !== vnode.text) {
+ nodeOps.setTextContent(elm, vnode.text)
+ }
+ if (isDef(data)) {
+ if (isDef(i = data.hook) && isDef(i = i.postpatch)) i(oldVnode, vnode)
+ }
+ }
+
+ function invokeInsertHook (vnode, queue, initial) {
+ // delay insert hooks for component root nodes, invoke them after the
+ // element is really inserted
+ if (isTrue(initial) && isDef(vnode.parent)) {
+ vnode.parent.data.pendingInsert = queue
+ } else {
+ for (let i = 0; i < queue.length; ++i) {
+ queue[i].data.hook.insert(queue[i])
+ }
+ }
+ }
+
+ let hydrationBailed = false
+ // list of modules that can skip create hook during hydration because they
+ // are already rendered on the client or has no need for initialization
+ // Note: style is excluded because it relies on initial clone for future
+ // deep updates (#7063).
+ const isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key')
+
+ // Note: this is a browser-only function so we can assume elms are DOM nodes.
+ function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {
+ let i
+ const { tag, data, children } = vnode
+ inVPre = inVPre || (data && data.pre)
+ vnode.elm = elm
+
+ if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {
+ vnode.isAsyncPlaceholder = true
+ return true
+ }
+ // assert node match
+ if (process.env.NODE_ENV !== 'production') {
+ if (!assertNodeMatch(elm, vnode, inVPre)) {
+ return false
+ }
+ }
+ if (isDef(data)) {
+ if (isDef(i = data.hook) && isDef(i = i.init)) i(vnode, true /* hydrating */)
+ if (isDef(i = vnode.componentInstance)) {
+ // child component. it should have hydrated its own tree.
+ initComponent(vnode, insertedVnodeQueue)
+ return true
+ }
+ }
+ if (isDef(tag)) {
+ if (isDef(children)) {
+ // empty element, allow client to pick up and populate children
+ if (!elm.hasChildNodes()) {
+ createChildren(vnode, children, insertedVnodeQueue)
+ } else {
+ // v-html and domProps: innerHTML
+ if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {
+ if (i !== elm.innerHTML) {
+ /* istanbul ignore if */
+ if (process.env.NODE_ENV !== 'production' &&
+ typeof console !== 'undefined' &&
+ !hydrationBailed
+ ) {
+ hydrationBailed = true
+ console.warn('Parent: ', elm)
+ console.warn('server innerHTML: ', i)
+ console.warn('client innerHTML: ', elm.innerHTML)
+ }
+ return false
+ }
+ } else {
+ // iterate and compare children lists
+ let childrenMatch = true
+ let childNode = elm.firstChild
+ for (let i = 0; i < children.length; i++) {
+ if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue, inVPre)) {
+ childrenMatch = false
+ break
+ }
+ childNode = childNode.nextSibling
+ }
+ // if childNode is not null, it means the actual childNodes list is
+ // longer than the virtual children list.
+ if (!childrenMatch || childNode) {
+ /* istanbul ignore if */
+ if (process.env.NODE_ENV !== 'production' &&
+ typeof console !== 'undefined' &&
+ !hydrationBailed
+ ) {
+ hydrationBailed = true
+ console.warn('Parent: ', elm)
+ console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children)
+ }
+ return false
+ }
+ }
+ }
+ }
+ if (isDef(data)) {
+ let fullInvoke = false
+ for (const key in data) {
+ if (!isRenderedModule(key)) {
+ fullInvoke = true
+ invokeCreateHooks(vnode, insertedVnodeQueue)
+ break
+ }
+ }
+ if (!fullInvoke && data['class']) {
+ // ensure collecting deps for deep class bindings for future updates
+ traverse(data['class'])
+ }
+ }
+ } else if (elm.data !== vnode.text) {
+ elm.data = vnode.text
+ }
+ return true
+ }
+
+ function assertNodeMatch (node, vnode, inVPre) {
+ if (isDef(vnode.tag)) {
+ return vnode.tag.indexOf('vue-component') === 0 || (
+ !isUnknownElement(vnode, inVPre) &&
+ vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase())
+ )
+ } else {
+ return node.nodeType === (vnode.isComment ? 8 : 3)
+ }
+ }
+
+ return function patch (oldVnode, vnode, hydrating, removeOnly, parentElm, refElm) {
+ if (isUndef(vnode)) {
+ if (isDef(oldVnode)) invokeDestroyHook(oldVnode)
+ return
+ }
+
+ let isInitialPatch = false
+ const insertedVnodeQueue = []
+
+ if (isUndef(oldVnode)) {
+ // empty mount (likely as component), create new root element
+ isInitialPatch = true
+ createElm(vnode, insertedVnodeQueue, parentElm, refElm)
+ } else {
+ const isRealElement = isDef(oldVnode.nodeType)
+ if (!isRealElement && sameVnode(oldVnode, vnode)) {
+ // patch existing root node
+ patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly)
+ } else {
+ if (isRealElement) {
+ // mounting to a real element
+ // check if this is server-rendered content and if we can perform
+ // a successful hydration.
+ if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {
+ oldVnode.removeAttribute(SSR_ATTR)
+ hydrating = true
+ }
+ if (isTrue(hydrating)) {
+ if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {
+ invokeInsertHook(vnode, insertedVnodeQueue, true)
+ return oldVnode
+ } else if (process.env.NODE_ENV !== 'production') {
+ warn(
+ 'The client-side rendered virtual DOM tree is not matching ' +
+ 'server-rendered content. This is likely caused by incorrect ' +
+ 'HTML markup, for example nesting block-level elements inside ' +
+ '<p>, or missing <tbody>. Bailing hydration and performing ' +
+ 'full client-side render.'
+ )
+ }
+ }
+ // either not server-rendered, or hydration failed.
+ // create an empty node and replace it
+ oldVnode = emptyNodeAt(oldVnode)
+ }
+
+ // replacing existing element
+ const oldElm = oldVnode.elm
+ const parentElm = nodeOps.parentNode(oldElm)
+
+ // create new node
+ createElm(
+ vnode,
+ insertedVnodeQueue,
+ // extremely rare edge case: do not insert if old element is in a
+ // leaving transition. Only happens when combining transition +
+ // keep-alive + HOCs. (#4590)
+ oldElm._leaveCb ? null : parentElm,
+ nodeOps.nextSibling(oldElm)
+ )
+
+ // update parent placeholder node element, recursively
+ if (isDef(vnode.parent)) {
+ let ancestor = vnode.parent
+ const patchable = isPatchable(vnode)
+ while (ancestor) {
+ for (let i = 0; i < cbs.destroy.length; ++i) {
+ cbs.destroy[i](ancestor)
+ }
+ ancestor.elm = vnode.elm
+ if (patchable) {
+ for (let i = 0; i < cbs.create.length; ++i) {
+ cbs.create[i](emptyNode, ancestor)
+ }
+ // #6513
+ // invoke insert hooks that may have been merged by create hooks.
+ // e.g. for directives that uses the "inserted" hook.
+ const insert = ancestor.data.hook.insert
+ if (insert.merged) {
+ // start at index 1 to avoid re-invoking component mounted hook
+ for (let i = 1; i < insert.fns.length; i++) {
+ insert.fns[i]()
+ }
+ }
+ } else {
+ registerRef(ancestor)
+ }
+ ancestor = ancestor.parent
+ }
+ }
+
+ // destroy old node
+ if (isDef(parentElm)) {
+ removeVnodes(parentElm, [oldVnode], 0, 0)
+ } else if (isDef(oldVnode.tag)) {
+ invokeDestroyHook(oldVnode)
+ }
+ }
+ }
+
+ invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch)
+ return vnode.elm
+ }
+}
diff --git a/node_modules/vue/src/core/vdom/vnode.js b/node_modules/vue/src/core/vdom/vnode.js
new file mode 100644
index 00000000..88e80cec
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/vnode.js
@@ -0,0 +1,108 @@
+/* @flow */
+
+export default class VNode {
+ tag: string | void;
+ data: VNodeData | void;
+ children: ?Array<VNode>;
+ text: string | void;
+ elm: Node | void;
+ ns: string | void;
+ context: Component | void; // rendered in this component's scope
+ key: string | number | void;
+ componentOptions: VNodeComponentOptions | void;
+ componentInstance: Component | void; // component instance
+ parent: VNode | void; // component placeholder node
+
+ // strictly internal
+ raw: boolean; // contains raw HTML? (server only)
+ isStatic: boolean; // hoisted static node
+ isRootInsert: boolean; // necessary for enter transition check
+ isComment: boolean; // empty comment placeholder?
+ isCloned: boolean; // is a cloned node?
+ isOnce: boolean; // is a v-once node?
+ asyncFactory: Function | void; // async component factory function
+ asyncMeta: Object | void;
+ isAsyncPlaceholder: boolean;
+ ssrContext: Object | void;
+ fnContext: Component | void; // real context vm for functional nodes
+ fnOptions: ?ComponentOptions; // for SSR caching
+ fnScopeId: ?string; // functional scope id support
+
+ constructor (
+ tag?: string,
+ data?: VNodeData,
+ children?: ?Array<VNode>,
+ text?: string,
+ elm?: Node,
+ context?: Component,
+ componentOptions?: VNodeComponentOptions,
+ asyncFactory?: Function
+ ) {
+ this.tag = tag
+ this.data = data
+ this.children = children
+ this.text = text
+ this.elm = elm
+ this.ns = undefined
+ this.context = context
+ this.fnContext = undefined
+ this.fnOptions = undefined
+ this.fnScopeId = undefined
+ this.key = data && data.key
+ this.componentOptions = componentOptions
+ this.componentInstance = undefined
+ this.parent = undefined
+ this.raw = false
+ this.isStatic = false
+ this.isRootInsert = true
+ this.isComment = false
+ this.isCloned = false
+ this.isOnce = false
+ this.asyncFactory = asyncFactory
+ this.asyncMeta = undefined
+ this.isAsyncPlaceholder = false
+ }
+
+ // DEPRECATED: alias for componentInstance for backwards compat.
+ /* istanbul ignore next */
+ get child (): Component | void {
+ return this.componentInstance
+ }
+}
+
+export const createEmptyVNode = (text: string = '') => {
+ const node = new VNode()
+ node.text = text
+ node.isComment = true
+ return node
+}
+
+export function createTextVNode (val: string | number) {
+ return new VNode(undefined, undefined, undefined, String(val))
+}
+
+// optimized shallow clone
+// used for static nodes and slot nodes because they may be reused across
+// multiple renders, cloning them avoids errors when DOM manipulations rely
+// on their elm reference.
+export function cloneVNode (vnode: VNode): VNode {
+ const cloned = new VNode(
+ vnode.tag,
+ vnode.data,
+ vnode.children,
+ vnode.text,
+ vnode.elm,
+ vnode.context,
+ vnode.componentOptions,
+ vnode.asyncFactory
+ )
+ cloned.ns = vnode.ns
+ cloned.isStatic = vnode.isStatic
+ cloned.key = vnode.key
+ cloned.isComment = vnode.isComment
+ cloned.fnContext = vnode.fnContext
+ cloned.fnOptions = vnode.fnOptions
+ cloned.fnScopeId = vnode.fnScopeId
+ cloned.isCloned = true
+ return cloned
+}