vuejs-rails 2.1.6 → 2.1.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16478f016f5826347b878c367ff26308f302f743
4
- data.tar.gz: 4da439179cae0bb30c41b0c2524c6e36ab82fe54
3
+ metadata.gz: 63a1fb4611036313e14b23641b6337f3295d5dd1
4
+ data.tar.gz: ab19dffe34a1a4e6d84567bf46bb8f4a2e7ee8df
5
5
  SHA512:
6
- metadata.gz: f12ffd66a5d7f826495d25a6f04ea8c9611af8cd6189a2cc9bae9b0a04a124eee2e1fee20199464f074d69202e925db16b319ef49e66382396cd2c3cba9e743d
7
- data.tar.gz: 2bef31553724fba5407941397c6976f98fe0ff00873ab1d70fe600d85d19cdf7832adf36cfb6b8e577b13f1a478faaf7bb0f0c2b5aadfeb1259002d54609ef24
6
+ metadata.gz: 2c80fd0c139d28940a33e52a6fc8ece568250e2c174cf965d54ad41c2bf945b5762e1e09be8d4753f13344ab3a122d40ba9968ddc72292d50e506cd0228a1717
7
+ data.tar.gz: f5a6727c0bcb80a6d08321198b08f4802e2020fcfa7a635bb6394325ff64f1c51496d435a443c394b48b2fc5f14fb59b39a95deb1f28154287517c5d297dc0ff
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2013 - 2016 Adam Butler
3
+ Copyright (c) 2013 - 2017 Adam Butler
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/Readme.md CHANGED
@@ -9,8 +9,8 @@ Rails 3.1+ asset-pipeline gem to provide Vue.js
9
9
 
10
10
  ### Package Versions
11
11
 
12
- - vue v2.1.6
13
- - vue-router v2.1.1
12
+ - vue v2.1.10
13
+ - vue-router v2.2.0
14
14
  - vue-resource v1.0.3
15
15
 
16
16
  ### Setup
@@ -35,7 +35,7 @@ In `app/views/layouts/application.html.erb`, move this line from the head of the
35
35
 
36
36
  ```html
37
37
  <%= javascript_include_tag 'application' %>
38
- ```
38
+ ```
39
39
 
40
40
  You may write your Vue.js code directly in your views using `<script>` tags, or in a separate Javascript file (recommended).
41
41
 
@@ -1,5 +1,5 @@
1
1
  module Vue
2
2
  module Rails
3
- VERSION = '2.1.6'
3
+ VERSION = '2.1.10'
4
4
  end
5
5
  end
@@ -1,14 +1,28 @@
1
1
  /**
2
- * vue-router v2.1.1
3
- * (c) 2016 Evan You
2
+ * vue-router v2.2.0
3
+ * (c) 2017 Evan You
4
4
  * @license MIT
5
5
  */
6
6
  (function (global, factory) {
7
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8
- typeof define === 'function' && define.amd ? define(factory) :
9
- (global.VueRouter = factory());
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8
+ typeof define === 'function' && define.amd ? define(factory) :
9
+ (global.VueRouter = factory());
10
10
  }(this, (function () { 'use strict';
11
11
 
12
+ /* */
13
+
14
+ function assert (condition, message) {
15
+ if (!condition) {
16
+ throw new Error(("[vue-router] " + message))
17
+ }
18
+ }
19
+
20
+ function warn (condition, message) {
21
+ if (!condition) {
22
+ typeof console !== 'undefined' && console.warn(("[vue-router] " + message));
23
+ }
24
+ }
25
+
12
26
  var View = {
13
27
  name: 'router-view',
14
28
  functional: true,
@@ -24,71 +38,91 @@ var View = {
24
38
  var parent = ref.parent;
25
39
  var data = ref.data;
26
40
 
27
- data.routerView = true
41
+ data.routerView = true;
28
42
 
29
- var route = parent.$route
30
- var cache = parent._routerViewCache || (parent._routerViewCache = {})
31
- var depth = 0
32
- var inactive = false
43
+ var name = props.name;
44
+ var route = parent.$route;
45
+ var cache = parent._routerViewCache || (parent._routerViewCache = {});
33
46
 
47
+ // determine current view depth, also check to see if the tree
48
+ // has been toggled inactive but kept-alive.
49
+ var depth = 0;
50
+ var inactive = false;
34
51
  while (parent) {
35
52
  if (parent.$vnode && parent.$vnode.data.routerView) {
36
- depth++
53
+ depth++;
37
54
  }
38
55
  if (parent._inactive) {
39
- inactive = true
56
+ inactive = true;
40
57
  }
41
- parent = parent.$parent
58
+ parent = parent.$parent;
42
59
  }
60
+ data.routerViewDepth = depth;
43
61
 
44
- data.routerViewDepth = depth
45
- var matched = route.matched[depth]
62
+ // render previous view if the tree is inactive and kept-alive
63
+ if (inactive) {
64
+ return h(cache[name], data, children)
65
+ }
66
+
67
+ var matched = route.matched[depth];
68
+ // render empty node if no matched route
46
69
  if (!matched) {
70
+ cache[name] = null;
47
71
  return h()
48
72
  }
49
73
 
50
- var name = props.name
51
- var component = inactive
52
- ? cache[name]
53
- : (cache[name] = matched.components[name])
54
-
55
- if (!inactive) {
56
- var hooks = data.hook || (data.hook = {})
57
- hooks.init = function (vnode) {
58
- matched.instances[name] = vnode.child
59
- }
60
- hooks.prepatch = function (oldVnode, vnode) {
61
- matched.instances[name] = vnode.child
62
- }
63
- hooks.destroy = function (vnode) {
64
- if (matched.instances[name] === vnode.child) {
65
- matched.instances[name] = undefined
66
- }
74
+ var component = cache[name] = matched.components[name];
75
+
76
+ // inject instance registration hooks
77
+ var hooks = data.hook || (data.hook = {});
78
+ hooks.init = function (vnode) {
79
+ matched.instances[name] = vnode.child;
80
+ };
81
+ hooks.prepatch = function (oldVnode, vnode) {
82
+ matched.instances[name] = vnode.child;
83
+ };
84
+ hooks.destroy = function (vnode) {
85
+ if (matched.instances[name] === vnode.child) {
86
+ matched.instances[name] = undefined;
67
87
  }
68
- }
88
+ };
69
89
 
70
- return h(component, data, children)
71
- }
72
- }
90
+ // resolve props
91
+ data.props = resolveProps(route, matched.props && matched.props[name]);
73
92
 
74
- /* */
75
-
76
- function assert (condition, message) {
77
- if (!condition) {
78
- throw new Error(("[vue-router] " + message))
93
+ return h(component, data, children)
79
94
  }
80
- }
95
+ };
81
96
 
82
- function warn (condition, message) {
83
- if (!condition) {
84
- typeof console !== 'undefined' && console.warn(("[vue-router] " + message))
97
+ function resolveProps (route, config) {
98
+ switch (typeof config) {
99
+ case 'undefined':
100
+ return
101
+ case 'object':
102
+ return config
103
+ case 'function':
104
+ return config(route)
105
+ case 'boolean':
106
+ return config ? route.params : undefined
107
+ default:
108
+ warn(false, ("props in \"" + (route.path) + "\" is a " + (typeof config) + ", expecting an object, function or boolean."));
85
109
  }
86
110
  }
87
111
 
88
112
  /* */
89
113
 
90
- var encode = encodeURIComponent
91
- var decode = decodeURIComponent
114
+ var encodeReserveRE = /[!'()*]/g;
115
+ var encodeReserveReplacer = function (c) { return '%' + c.charCodeAt(0).toString(16); };
116
+ var commaRE = /%2C/g;
117
+
118
+ // fixed encodeURIComponent which is more comformant to RFC3986:
119
+ // - escapes [!'()*]
120
+ // - preserve commas
121
+ var encode = function (str) { return encodeURIComponent(str)
122
+ .replace(encodeReserveRE, encodeReserveReplacer)
123
+ .replace(commaRE, ','); };
124
+
125
+ var decode = decodeURIComponent;
92
126
 
93
127
  function resolveQuery (
94
128
  query,
@@ -97,15 +131,15 @@ function resolveQuery (
97
131
  if ( extraQuery === void 0 ) extraQuery = {};
98
132
 
99
133
  if (query) {
100
- var parsedQuery
134
+ var parsedQuery;
101
135
  try {
102
- parsedQuery = parseQuery(query)
136
+ parsedQuery = parseQuery(query);
103
137
  } catch (e) {
104
- "development" !== 'production' && warn(false, e.message)
105
- parsedQuery = {}
138
+ "development" !== 'production' && warn(false, e.message);
139
+ parsedQuery = {};
106
140
  }
107
141
  for (var key in extraQuery) {
108
- parsedQuery[key] = extraQuery[key]
142
+ parsedQuery[key] = extraQuery[key];
109
143
  }
110
144
  return parsedQuery
111
145
  } else {
@@ -114,36 +148,36 @@ function resolveQuery (
114
148
  }
115
149
 
116
150
  function parseQuery (query) {
117
- var res = {}
151
+ var res = {};
118
152
 
119
- query = query.trim().replace(/^(\?|#|&)/, '')
153
+ query = query.trim().replace(/^(\?|#|&)/, '');
120
154
 
121
155
  if (!query) {
122
156
  return res
123
157
  }
124
158
 
125
159
  query.split('&').forEach(function (param) {
126
- var parts = param.replace(/\+/g, ' ').split('=')
127
- var key = decode(parts.shift())
160
+ var parts = param.replace(/\+/g, ' ').split('=');
161
+ var key = decode(parts.shift());
128
162
  var val = parts.length > 0
129
163
  ? decode(parts.join('='))
130
- : null
164
+ : null;
131
165
 
132
166
  if (res[key] === undefined) {
133
- res[key] = val
167
+ res[key] = val;
134
168
  } else if (Array.isArray(res[key])) {
135
- res[key].push(val)
169
+ res[key].push(val);
136
170
  } else {
137
- res[key] = [res[key], val]
171
+ res[key] = [res[key], val];
138
172
  }
139
- })
173
+ });
140
174
 
141
175
  return res
142
176
  }
143
177
 
144
178
  function stringifyQuery (obj) {
145
179
  var res = obj ? Object.keys(obj).map(function (key) {
146
- var val = obj[key]
180
+ var val = obj[key];
147
181
 
148
182
  if (val === undefined) {
149
183
  return ''
@@ -154,27 +188,29 @@ function stringifyQuery (obj) {
154
188
  }
155
189
 
156
190
  if (Array.isArray(val)) {
157
- var result = []
191
+ var result = [];
158
192
  val.slice().forEach(function (val2) {
159
193
  if (val2 === undefined) {
160
194
  return
161
195
  }
162
196
  if (val2 === null) {
163
- result.push(encode(key))
197
+ result.push(encode(key));
164
198
  } else {
165
- result.push(encode(key) + '=' + encode(val2))
199
+ result.push(encode(key) + '=' + encode(val2));
166
200
  }
167
- })
201
+ });
168
202
  return result.join('&')
169
203
  }
170
204
 
171
205
  return encode(key) + '=' + encode(val)
172
- }).filter(function (x) { return x.length > 0; }).join('&') : null
206
+ }).filter(function (x) { return x.length > 0; }).join('&') : null;
173
207
  return res ? ("?" + res) : ''
174
208
  }
175
209
 
176
210
  /* */
177
211
 
212
+ var trailingSlashRE = /\/?$/;
213
+
178
214
  function createRoute (
179
215
  record,
180
216
  location,
@@ -189,9 +225,9 @@ function createRoute (
189
225
  params: location.params || {},
190
226
  fullPath: getFullPath(location),
191
227
  matched: record ? formatMatch(record) : []
192
- }
228
+ };
193
229
  if (redirectedFrom) {
194
- route.redirectedFrom = getFullPath(redirectedFrom)
230
+ route.redirectedFrom = getFullPath(redirectedFrom);
195
231
  }
196
232
  return Object.freeze(route)
197
233
  }
@@ -199,13 +235,13 @@ function createRoute (
199
235
  // the starting route that represents the initial state
200
236
  var START = createRoute(null, {
201
237
  path: '/'
202
- })
238
+ });
203
239
 
204
240
  function formatMatch (record) {
205
- var res = []
241
+ var res = [];
206
242
  while (record) {
207
- res.unshift(record)
208
- record = record.parent
243
+ res.unshift(record);
244
+ record = record.parent;
209
245
  }
210
246
  return res
211
247
  }
@@ -218,7 +254,6 @@ function getFullPath (ref) {
218
254
  return (path || '/') + stringifyQuery(query) + hash
219
255
  }
220
256
 
221
- var trailingSlashRE = /\/$/
222
257
  function isSameRoute (a, b) {
223
258
  if (b === START) {
224
259
  return a === b
@@ -246,8 +281,8 @@ function isObjectEqual (a, b) {
246
281
  if ( a === void 0 ) a = {};
247
282
  if ( b === void 0 ) b = {};
248
283
 
249
- var aKeys = Object.keys(a)
250
- var bKeys = Object.keys(b)
284
+ var aKeys = Object.keys(a);
285
+ var bKeys = Object.keys(b);
251
286
  if (aKeys.length !== bKeys.length) {
252
287
  return false
253
288
  }
@@ -256,7 +291,9 @@ function isObjectEqual (a, b) {
256
291
 
257
292
  function isIncludedRoute (current, target) {
258
293
  return (
259
- current.path.indexOf(target.path.replace(/\/$/, '')) === 0 &&
294
+ current.path.replace(trailingSlashRE, '/').indexOf(
295
+ target.path.replace(trailingSlashRE, '/')
296
+ ) === 0 &&
260
297
  (!target.hash || current.hash === target.hash) &&
261
298
  queryIncludes(current.query, target.query)
262
299
  )
@@ -274,7 +311,8 @@ function queryIncludes (current, target) {
274
311
  /* */
275
312
 
276
313
  // work around weird flow bug
277
- var toTypes = [String, Object]
314
+ var toTypes = [String, Object];
315
+ var eventTypes = [String, Array];
278
316
 
279
317
  var Link = {
280
318
  name: 'router-link',
@@ -292,95 +330,95 @@ var Link = {
292
330
  replace: Boolean,
293
331
  activeClass: String,
294
332
  event: {
295
- type: [String, Array],
333
+ type: eventTypes,
296
334
  default: 'click'
297
335
  }
298
336
  },
299
337
  render: function render (h) {
300
338
  var this$1 = this;
301
339
 
302
- var router = this.$router
303
- var current = this.$route
340
+ var router = this.$router;
341
+ var current = this.$route;
304
342
  var ref = router.resolve(this.to, current, this.append);
305
- var normalizedTo = ref.normalizedTo;
306
- var resolved = ref.resolved;
343
+ var location = ref.location;
344
+ var route = ref.route;
307
345
  var href = ref.href;
308
- var classes = {}
309
- var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active'
310
- var compareTarget = normalizedTo.path ? createRoute(null, normalizedTo) : resolved
346
+ var classes = {};
347
+ var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active';
348
+ var compareTarget = location.path ? createRoute(null, location) : route;
311
349
  classes[activeClass] = this.exact
312
350
  ? isSameRoute(current, compareTarget)
313
- : isIncludedRoute(current, compareTarget)
351
+ : isIncludedRoute(current, compareTarget);
314
352
 
315
353
  var handler = function (e) {
316
354
  if (guardEvent(e)) {
317
355
  if (this$1.replace) {
318
- router.replace(normalizedTo)
356
+ router.replace(location);
319
357
  } else {
320
- router.push(normalizedTo)
358
+ router.push(location);
321
359
  }
322
360
  }
323
- }
361
+ };
324
362
 
325
- var on = { click: guardEvent }
363
+ var on = { click: guardEvent };
326
364
  if (Array.isArray(this.event)) {
327
- this.event.forEach(function (e) { on[e] = handler })
365
+ this.event.forEach(function (e) { on[e] = handler; });
328
366
  } else {
329
- on[this.event] = handler
367
+ on[this.event] = handler;
330
368
  }
331
369
 
332
370
  var data = {
333
371
  class: classes
334
- }
372
+ };
335
373
 
336
374
  if (this.tag === 'a') {
337
- data.on = on
338
- data.attrs = { href: href }
375
+ data.on = on;
376
+ data.attrs = { href: href };
339
377
  } else {
340
378
  // find the first <a> child and apply listener and href
341
- var a = findAnchor(this.$slots.default)
379
+ var a = findAnchor(this.$slots.default);
342
380
  if (a) {
343
381
  // in case the <a> is a static node
344
- a.isStatic = false
345
- var extend = _Vue.util.extend
346
- var aData = a.data = extend({}, a.data)
347
- aData.on = on
348
- var aAttrs = a.data.attrs = extend({}, a.data.attrs)
349
- aAttrs.href = href
382
+ a.isStatic = false;
383
+ var extend = _Vue.util.extend;
384
+ var aData = a.data = extend({}, a.data);
385
+ aData.on = on;
386
+ var aAttrs = a.data.attrs = extend({}, a.data.attrs);
387
+ aAttrs.href = href;
350
388
  } else {
351
389
  // doesn't have <a> child, apply listener to self
352
- data.on = on
390
+ data.on = on;
353
391
  }
354
392
  }
355
393
 
356
394
  return h(this.tag, data, this.$slots.default)
357
395
  }
358
- }
396
+ };
359
397
 
360
398
  function guardEvent (e) {
361
399
  // don't redirect with control keys
362
- /* istanbul ignore if */
363
400
  if (e.metaKey || e.ctrlKey || e.shiftKey) { return }
364
401
  // don't redirect when preventDefault called
365
- /* istanbul ignore if */
366
402
  if (e.defaultPrevented) { return }
367
403
  // don't redirect on right click
368
- /* istanbul ignore if */
369
- if (e.button !== 0) { return }
404
+ if (e.button !== undefined && e.button !== 0) { return }
370
405
  // don't redirect if `target="_blank"`
371
- /* istanbul ignore if */
372
- var target = e.target.getAttribute('target')
373
- if (/\b_blank\b/i.test(target)) { return }
374
-
375
- e.preventDefault()
406
+ if (e.target && e.target.getAttribute) {
407
+ var target = e.target.getAttribute('target');
408
+ if (/\b_blank\b/i.test(target)) { return }
409
+ }
410
+ // this may be a Weex event which doesn't have this method
411
+ if (e.preventDefault) {
412
+ e.preventDefault();
413
+ }
376
414
  return true
377
415
  }
378
416
 
379
417
  function findAnchor (children) {
380
418
  if (children) {
381
- var child
419
+ var child;
382
420
  for (var i = 0; i < children.length; i++) {
383
- child = children[i]
421
+ child = children[i];
384
422
  if (child.tag === 'a') {
385
423
  return child
386
424
  }
@@ -391,42 +429,46 @@ function findAnchor (children) {
391
429
  }
392
430
  }
393
431
 
394
- var _Vue
432
+ var _Vue;
395
433
 
396
434
  function install (Vue) {
397
435
  if (install.installed) { return }
398
- install.installed = true
436
+ install.installed = true;
399
437
 
400
- _Vue = Vue
438
+ _Vue = Vue;
401
439
 
402
440
  Object.defineProperty(Vue.prototype, '$router', {
403
441
  get: function get () { return this.$root._router }
404
- })
442
+ });
405
443
 
406
444
  Object.defineProperty(Vue.prototype, '$route', {
407
- get: function get$1 () { return this.$root._route }
408
- })
445
+ get: function get () { return this.$root._route }
446
+ });
409
447
 
410
448
  Vue.mixin({
411
449
  beforeCreate: function beforeCreate () {
412
450
  if (this.$options.router) {
413
- this._router = this.$options.router
414
- this._router.init(this)
415
- Vue.util.defineReactive(this, '_route', this._router.history.current)
451
+ this._router = this.$options.router;
452
+ this._router.init(this);
453
+ Vue.util.defineReactive(this, '_route', this._router.history.current);
416
454
  }
417
455
  }
418
- })
456
+ });
419
457
 
420
- Vue.component('router-view', View)
421
- Vue.component('router-link', Link)
458
+ Vue.component('router-view', View);
459
+ Vue.component('router-link', Link);
422
460
 
423
- var strats = Vue.config.optionMergeStrategies
461
+ var strats = Vue.config.optionMergeStrategies;
424
462
  // use the same hook merging strategy for route hooks
425
- strats.beforeRouteEnter = strats.beforeRouteLeave = strats.created
463
+ strats.beforeRouteEnter = strats.beforeRouteLeave = strats.created;
426
464
  }
427
465
 
428
466
  /* */
429
467
 
468
+ var inBrowser = typeof window !== 'undefined';
469
+
470
+ /* */
471
+
430
472
  function resolvePath (
431
473
  relative,
432
474
  base,
@@ -440,50 +482,50 @@ function resolvePath (
440
482
  return base + relative
441
483
  }
442
484
 
443
- var stack = base.split('/')
485
+ var stack = base.split('/');
444
486
 
445
487
  // remove trailing segment if:
446
488
  // - not appending
447
489
  // - appending to trailing slash (last segment is empty)
448
490
  if (!append || !stack[stack.length - 1]) {
449
- stack.pop()
491
+ stack.pop();
450
492
  }
451
493
 
452
494
  // resolve relative path
453
- var segments = relative.replace(/^\//, '').split('/')
495
+ var segments = relative.replace(/^\//, '').split('/');
454
496
  for (var i = 0; i < segments.length; i++) {
455
- var segment = segments[i]
497
+ var segment = segments[i];
456
498
  if (segment === '.') {
457
499
  continue
458
500
  } else if (segment === '..') {
459
- stack.pop()
501
+ stack.pop();
460
502
  } else {
461
- stack.push(segment)
503
+ stack.push(segment);
462
504
  }
463
505
  }
464
506
 
465
507
  // ensure leading slash
466
508
  if (stack[0] !== '') {
467
- stack.unshift('')
509
+ stack.unshift('');
468
510
  }
469
511
 
470
512
  return stack.join('/')
471
513
  }
472
514
 
473
515
  function parsePath (path) {
474
- var hash = ''
475
- var query = ''
516
+ var hash = '';
517
+ var query = '';
476
518
 
477
- var hashIndex = path.indexOf('#')
519
+ var hashIndex = path.indexOf('#');
478
520
  if (hashIndex >= 0) {
479
- hash = path.slice(hashIndex)
480
- path = path.slice(0, hashIndex)
521
+ hash = path.slice(hashIndex);
522
+ path = path.slice(0, hashIndex);
481
523
  }
482
524
 
483
- var queryIndex = path.indexOf('?')
525
+ var queryIndex = path.indexOf('?');
484
526
  if (queryIndex >= 0) {
485
- query = path.slice(queryIndex + 1)
486
- path = path.slice(0, queryIndex)
527
+ query = path.slice(queryIndex + 1);
528
+ path = path.slice(0, queryIndex);
487
529
  }
488
530
 
489
531
  return {
@@ -499,13 +541,17 @@ function cleanPath (path) {
499
541
 
500
542
  /* */
501
543
 
502
- function createRouteMap (routes) {
503
- var pathMap = Object.create(null)
504
- var nameMap = Object.create(null)
544
+ function createRouteMap (
545
+ routes,
546
+ oldPathMap,
547
+ oldNameMap
548
+ ) {
549
+ var pathMap = oldPathMap || Object.create(null);
550
+ var nameMap = oldNameMap || Object.create(null);
505
551
 
506
552
  routes.forEach(function (route) {
507
- addRouteRecord(pathMap, nameMap, route)
508
- })
553
+ addRouteRecord(pathMap, nameMap, route);
554
+ });
509
555
 
510
556
  return {
511
557
  pathMap: pathMap,
@@ -522,13 +568,13 @@ function addRouteRecord (
522
568
  ) {
523
569
  var path = route.path;
524
570
  var name = route.name;
525
- if ("development" !== 'production') {
526
- assert(path != null, "\"path\" is required in a route configuration.")
571
+ {
572
+ assert(path != null, "\"path\" is required in a route configuration.");
527
573
  assert(
528
574
  typeof route.component !== 'string',
529
575
  "route config \"component\" for path: " + (String(path || name)) + " cannot be a " +
530
576
  "string id. Use an actual component instead."
531
- )
577
+ );
532
578
  }
533
579
 
534
580
  var record = {
@@ -540,67 +586,94 @@ function addRouteRecord (
540
586
  matchAs: matchAs,
541
587
  redirect: route.redirect,
542
588
  beforeEnter: route.beforeEnter,
543
- meta: route.meta || {}
544
- }
589
+ meta: route.meta || {},
590
+ props: route.props == null
591
+ ? {}
592
+ : route.components
593
+ ? route.props
594
+ : { default: route.props }
595
+ };
545
596
 
546
597
  if (route.children) {
547
598
  // Warn if route is named and has a default child route.
548
599
  // If users navigate to this route by name, the default child will
549
600
  // not be rendered (GH Issue #629)
550
- if ("development" !== 'production') {
601
+ {
551
602
  if (route.name && route.children.some(function (child) { return /^\/?$/.test(child.path); })) {
552
- warn(false, ("Named Route '" + (route.name) + "' has a default child route.\n When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), the default child route will not be rendered.\n Remove the name from this route and use the name of the default child route for named links instead.")
553
- )
603
+ warn(
604
+ false,
605
+ "Named Route '" + (route.name) + "' has a default child route. " +
606
+ "When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), " +
607
+ "the default child route will not be rendered. Remove the name from " +
608
+ "this route and use the name of the default child route for named " +
609
+ "links instead."
610
+ );
554
611
  }
555
612
  }
556
613
  route.children.forEach(function (child) {
557
- addRouteRecord(pathMap, nameMap, child, record)
558
- })
614
+ var childMatchAs = matchAs
615
+ ? cleanPath((matchAs + "/" + (child.path)))
616
+ : undefined;
617
+ addRouteRecord(pathMap, nameMap, child, record, childMatchAs);
618
+ });
559
619
  }
560
620
 
561
621
  if (route.alias !== undefined) {
562
622
  if (Array.isArray(route.alias)) {
563
623
  route.alias.forEach(function (alias) {
564
- addRouteRecord(pathMap, nameMap, { path: alias }, parent, record.path)
565
- })
624
+ var aliasRoute = {
625
+ path: alias,
626
+ children: route.children
627
+ };
628
+ addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path);
629
+ });
566
630
  } else {
567
- addRouteRecord(pathMap, nameMap, { path: route.alias }, parent, record.path)
631
+ var aliasRoute = {
632
+ path: route.alias,
633
+ children: route.children
634
+ };
635
+ addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path);
568
636
  }
569
637
  }
570
638
 
571
639
  if (!pathMap[record.path]) {
572
- pathMap[record.path] = record
640
+ pathMap[record.path] = record;
573
641
  }
642
+
574
643
  if (name) {
575
644
  if (!nameMap[name]) {
576
- nameMap[name] = record
577
- } else if ("development" !== 'production') {
578
- warn(false, ("Duplicate named routes definition: { name: \"" + name + "\", path: \"" + (record.path) + "\" }"))
645
+ nameMap[name] = record;
646
+ } else if ("development" !== 'production' && !matchAs) {
647
+ warn(
648
+ false,
649
+ "Duplicate named routes definition: " +
650
+ "{ name: \"" + name + "\", path: \"" + (record.path) + "\" }"
651
+ );
579
652
  }
580
653
  }
581
654
  }
582
655
 
583
656
  function normalizePath (path, parent) {
584
- path = path.replace(/\/$/, '')
657
+ path = path.replace(/\/$/, '');
585
658
  if (path[0] === '/') { return path }
586
659
  if (parent == null) { return path }
587
660
  return cleanPath(((parent.path) + "/" + path))
588
661
  }
589
662
 
590
- var __moduleExports = Array.isArray || function (arr) {
663
+ var index$1 = Array.isArray || function (arr) {
591
664
  return Object.prototype.toString.call(arr) == '[object Array]';
592
665
  };
593
666
 
594
- var isarray = __moduleExports
667
+ var isarray = index$1;
595
668
 
596
669
  /**
597
670
  * Expose `pathToRegexp`.
598
671
  */
599
- var index = pathToRegexp
600
- var parse_1 = parse
601
- var compile_1 = compile
602
- var tokensToFunction_1 = tokensToFunction
603
- var tokensToRegExp_1 = tokensToRegExp
672
+ var index = pathToRegexp;
673
+ var parse_1 = parse;
674
+ var compile_1 = compile;
675
+ var tokensToFunction_1 = tokensToFunction;
676
+ var tokensToRegExp_1 = tokensToRegExp;
604
677
 
605
678
  /**
606
679
  * The main path matching regexp utility.
@@ -618,7 +691,7 @@ var PATH_REGEXP = new RegExp([
618
691
  // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined]
619
692
  // "/*" => ["/", undefined, undefined, undefined, undefined, "*"]
620
693
  '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))'
621
- ].join('|'), 'g')
694
+ ].join('|'), 'g');
622
695
 
623
696
  /**
624
697
  * Parse a string for the raw tokens.
@@ -628,45 +701,45 @@ var PATH_REGEXP = new RegExp([
628
701
  * @return {!Array}
629
702
  */
630
703
  function parse (str, options) {
631
- var tokens = []
632
- var key = 0
633
- var index = 0
634
- var path = ''
635
- var defaultDelimiter = options && options.delimiter || '/'
636
- var res
704
+ var tokens = [];
705
+ var key = 0;
706
+ var index = 0;
707
+ var path = '';
708
+ var defaultDelimiter = options && options.delimiter || '/';
709
+ var res;
637
710
 
638
711
  while ((res = PATH_REGEXP.exec(str)) != null) {
639
- var m = res[0]
640
- var escaped = res[1]
641
- var offset = res.index
642
- path += str.slice(index, offset)
643
- index = offset + m.length
712
+ var m = res[0];
713
+ var escaped = res[1];
714
+ var offset = res.index;
715
+ path += str.slice(index, offset);
716
+ index = offset + m.length;
644
717
 
645
718
  // Ignore already escaped sequences.
646
719
  if (escaped) {
647
- path += escaped[1]
720
+ path += escaped[1];
648
721
  continue
649
722
  }
650
723
 
651
- var next = str[index]
652
- var prefix = res[2]
653
- var name = res[3]
654
- var capture = res[4]
655
- var group = res[5]
656
- var modifier = res[6]
657
- var asterisk = res[7]
724
+ var next = str[index];
725
+ var prefix = res[2];
726
+ var name = res[3];
727
+ var capture = res[4];
728
+ var group = res[5];
729
+ var modifier = res[6];
730
+ var asterisk = res[7];
658
731
 
659
732
  // Push the current path onto the tokens.
660
733
  if (path) {
661
- tokens.push(path)
662
- path = ''
734
+ tokens.push(path);
735
+ path = '';
663
736
  }
664
737
 
665
- var partial = prefix != null && next != null && next !== prefix
666
- var repeat = modifier === '+' || modifier === '*'
667
- var optional = modifier === '?' || modifier === '*'
668
- var delimiter = res[2] || defaultDelimiter
669
- var pattern = capture || group
738
+ var partial = prefix != null && next != null && next !== prefix;
739
+ var repeat = modifier === '+' || modifier === '*';
740
+ var optional = modifier === '?' || modifier === '*';
741
+ var delimiter = res[2] || defaultDelimiter;
742
+ var pattern = capture || group;
670
743
 
671
744
  tokens.push({
672
745
  name: name || key++,
@@ -677,17 +750,17 @@ function parse (str, options) {
677
750
  partial: partial,
678
751
  asterisk: !!asterisk,
679
752
  pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')
680
- })
753
+ });
681
754
  }
682
755
 
683
756
  // Match any characters still remaining.
684
757
  if (index < str.length) {
685
- path += str.substr(index)
758
+ path += str.substr(index);
686
759
  }
687
760
 
688
761
  // If the path exists, push it onto the end.
689
762
  if (path) {
690
- tokens.push(path)
763
+ tokens.push(path);
691
764
  }
692
765
 
693
766
  return tokens
@@ -733,38 +806,38 @@ function encodeAsterisk (str) {
733
806
  */
734
807
  function tokensToFunction (tokens) {
735
808
  // Compile all the tokens into regexps.
736
- var matches = new Array(tokens.length)
809
+ var matches = new Array(tokens.length);
737
810
 
738
811
  // Compile all the patterns before compilation.
739
812
  for (var i = 0; i < tokens.length; i++) {
740
813
  if (typeof tokens[i] === 'object') {
741
- matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$')
814
+ matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$');
742
815
  }
743
816
  }
744
817
 
745
818
  return function (obj, opts) {
746
- var path = ''
747
- var data = obj || {}
748
- var options = opts || {}
749
- var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent
819
+ var path = '';
820
+ var data = obj || {};
821
+ var options = opts || {};
822
+ var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent;
750
823
 
751
824
  for (var i = 0; i < tokens.length; i++) {
752
- var token = tokens[i]
825
+ var token = tokens[i];
753
826
 
754
827
  if (typeof token === 'string') {
755
- path += token
828
+ path += token;
756
829
 
757
830
  continue
758
831
  }
759
832
 
760
- var value = data[token.name]
761
- var segment
833
+ var value = data[token.name];
834
+ var segment;
762
835
 
763
836
  if (value == null) {
764
837
  if (token.optional) {
765
838
  // Prepend partial segment prefixes.
766
839
  if (token.partial) {
767
- path += token.prefix
840
+ path += token.prefix;
768
841
  }
769
842
 
770
843
  continue
@@ -787,25 +860,25 @@ function tokensToFunction (tokens) {
787
860
  }
788
861
 
789
862
  for (var j = 0; j < value.length; j++) {
790
- segment = encode(value[j])
863
+ segment = encode(value[j]);
791
864
 
792
865
  if (!matches[i].test(segment)) {
793
866
  throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`')
794
867
  }
795
868
 
796
- path += (j === 0 ? token.prefix : token.delimiter) + segment
869
+ path += (j === 0 ? token.prefix : token.delimiter) + segment;
797
870
  }
798
871
 
799
872
  continue
800
873
  }
801
874
 
802
- segment = token.asterisk ? encodeAsterisk(value) : encode(value)
875
+ segment = token.asterisk ? encodeAsterisk(value) : encode(value);
803
876
 
804
877
  if (!matches[i].test(segment)) {
805
878
  throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
806
879
  }
807
880
 
808
- path += token.prefix + segment
881
+ path += token.prefix + segment;
809
882
  }
810
883
 
811
884
  return path
@@ -840,7 +913,7 @@ function escapeGroup (group) {
840
913
  * @return {!RegExp}
841
914
  */
842
915
  function attachKeys (re, keys) {
843
- re.keys = keys
916
+ re.keys = keys;
844
917
  return re
845
918
  }
846
919
 
@@ -863,7 +936,7 @@ function flags (options) {
863
936
  */
864
937
  function regexpToRegexp (path, keys) {
865
938
  // Use a negative lookahead to match only capturing groups.
866
- var groups = path.source.match(/\((?!\?)/g)
939
+ var groups = path.source.match(/\((?!\?)/g);
867
940
 
868
941
  if (groups) {
869
942
  for (var i = 0; i < groups.length; i++) {
@@ -876,7 +949,7 @@ function regexpToRegexp (path, keys) {
876
949
  partial: false,
877
950
  asterisk: false,
878
951
  pattern: null
879
- })
952
+ });
880
953
  }
881
954
  }
882
955
 
@@ -892,13 +965,13 @@ function regexpToRegexp (path, keys) {
892
965
  * @return {!RegExp}
893
966
  */
894
967
  function arrayToRegexp (path, keys, options) {
895
- var parts = []
968
+ var parts = [];
896
969
 
897
970
  for (var i = 0; i < path.length; i++) {
898
- parts.push(pathToRegexp(path[i], keys, options).source)
971
+ parts.push(pathToRegexp(path[i], keys, options).source);
899
972
  }
900
973
 
901
- var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
974
+ var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options));
902
975
 
903
976
  return attachKeys(regexp, keys)
904
977
  }
@@ -925,63 +998,63 @@ function stringToRegexp (path, keys, options) {
925
998
  */
926
999
  function tokensToRegExp (tokens, keys, options) {
927
1000
  if (!isarray(keys)) {
928
- options = /** @type {!Object} */ (keys || options)
929
- keys = []
1001
+ options = /** @type {!Object} */ (keys || options);
1002
+ keys = [];
930
1003
  }
931
1004
 
932
- options = options || {}
1005
+ options = options || {};
933
1006
 
934
- var strict = options.strict
935
- var end = options.end !== false
936
- var route = ''
1007
+ var strict = options.strict;
1008
+ var end = options.end !== false;
1009
+ var route = '';
937
1010
 
938
1011
  // Iterate over the tokens and create our regexp string.
939
1012
  for (var i = 0; i < tokens.length; i++) {
940
- var token = tokens[i]
1013
+ var token = tokens[i];
941
1014
 
942
1015
  if (typeof token === 'string') {
943
- route += escapeString(token)
1016
+ route += escapeString(token);
944
1017
  } else {
945
- var prefix = escapeString(token.prefix)
946
- var capture = '(?:' + token.pattern + ')'
1018
+ var prefix = escapeString(token.prefix);
1019
+ var capture = '(?:' + token.pattern + ')';
947
1020
 
948
- keys.push(token)
1021
+ keys.push(token);
949
1022
 
950
1023
  if (token.repeat) {
951
- capture += '(?:' + prefix + capture + ')*'
1024
+ capture += '(?:' + prefix + capture + ')*';
952
1025
  }
953
1026
 
954
1027
  if (token.optional) {
955
1028
  if (!token.partial) {
956
- capture = '(?:' + prefix + '(' + capture + '))?'
1029
+ capture = '(?:' + prefix + '(' + capture + '))?';
957
1030
  } else {
958
- capture = prefix + '(' + capture + ')?'
1031
+ capture = prefix + '(' + capture + ')?';
959
1032
  }
960
1033
  } else {
961
- capture = prefix + '(' + capture + ')'
1034
+ capture = prefix + '(' + capture + ')';
962
1035
  }
963
1036
 
964
- route += capture
1037
+ route += capture;
965
1038
  }
966
1039
  }
967
1040
 
968
- var delimiter = escapeString(options.delimiter || '/')
969
- var endsWithDelimiter = route.slice(-delimiter.length) === delimiter
1041
+ var delimiter = escapeString(options.delimiter || '/');
1042
+ var endsWithDelimiter = route.slice(-delimiter.length) === delimiter;
970
1043
 
971
1044
  // In non-strict mode we allow a slash at the end of match. If the path to
972
1045
  // match already ends with a slash, we remove it for consistency. The slash
973
1046
  // is valid at the end of a path match, not in the middle. This is important
974
1047
  // in non-ending mode, where "/test/" shouldn't match "/test//route".
975
1048
  if (!strict) {
976
- route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?'
1049
+ route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?';
977
1050
  }
978
1051
 
979
1052
  if (end) {
980
- route += '$'
1053
+ route += '$';
981
1054
  } else {
982
1055
  // In non-ending mode, we need the capturing groups to match as much as
983
1056
  // possible by using a positive lookahead to the end or next path segment.
984
- route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)'
1057
+ route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)';
985
1058
  }
986
1059
 
987
1060
  return attachKeys(new RegExp('^' + route, flags(options)), keys)
@@ -1001,11 +1074,11 @@ function tokensToRegExp (tokens, keys, options) {
1001
1074
  */
1002
1075
  function pathToRegexp (path, keys, options) {
1003
1076
  if (!isarray(keys)) {
1004
- options = /** @type {!Object} */ (keys || options)
1005
- keys = []
1077
+ options = /** @type {!Object} */ (keys || options);
1078
+ keys = [];
1006
1079
  }
1007
1080
 
1008
- options = options || {}
1081
+ options = options || {};
1009
1082
 
1010
1083
  if (path instanceof RegExp) {
1011
1084
  return regexpToRegexp(path, /** @type {!Array} */ (keys))
@@ -1025,25 +1098,25 @@ index.tokensToRegExp = tokensToRegExp_1;
1025
1098
 
1026
1099
  /* */
1027
1100
 
1028
- var regexpCache = Object.create(null)
1101
+ var regexpCache = Object.create(null);
1029
1102
 
1030
1103
  function getRouteRegex (path) {
1031
- var hit = regexpCache[path]
1032
- var keys, regexp
1104
+ var hit = regexpCache[path];
1105
+ var keys, regexp;
1033
1106
 
1034
1107
  if (hit) {
1035
- keys = hit.keys
1036
- regexp = hit.regexp
1108
+ keys = hit.keys;
1109
+ regexp = hit.regexp;
1037
1110
  } else {
1038
- keys = []
1039
- regexp = index(path, keys)
1040
- regexpCache[path] = { keys: keys, regexp: regexp }
1111
+ keys = [];
1112
+ regexp = index(path, keys);
1113
+ regexpCache[path] = { keys: keys, regexp: regexp };
1041
1114
  }
1042
1115
 
1043
1116
  return { keys: keys, regexp: regexp }
1044
1117
  }
1045
1118
 
1046
- var regexpCompileCache = Object.create(null)
1119
+ var regexpCompileCache = Object.create(null);
1047
1120
 
1048
1121
  function fillParams (
1049
1122
  path,
@@ -1053,11 +1126,11 @@ function fillParams (
1053
1126
  try {
1054
1127
  var filler =
1055
1128
  regexpCompileCache[path] ||
1056
- (regexpCompileCache[path] = index.compile(path))
1129
+ (regexpCompileCache[path] = index.compile(path));
1057
1130
  return filler(params || {}, { pretty: true })
1058
1131
  } catch (e) {
1059
- if ("development" !== 'production') {
1060
- warn(false, ("missing param for " + routeMsg + ": " + (e.message)))
1132
+ {
1133
+ warn(false, ("missing param for " + routeMsg + ": " + (e.message)));
1061
1134
  }
1062
1135
  return ''
1063
1136
  }
@@ -1070,7 +1143,7 @@ function normalizeLocation (
1070
1143
  current,
1071
1144
  append
1072
1145
  ) {
1073
- var next = typeof raw === 'string' ? { path: raw } : raw
1146
+ var next = typeof raw === 'string' ? { path: raw } : raw;
1074
1147
  // named target
1075
1148
  if (next.name || next._normalized) {
1076
1149
  return next
@@ -1078,30 +1151,30 @@ function normalizeLocation (
1078
1151
 
1079
1152
  // relative params
1080
1153
  if (!next.path && next.params && current) {
1081
- next = assign({}, next)
1082
- next._normalized = true
1083
- var params = assign(assign({}, current.params), next.params)
1154
+ next = assign({}, next);
1155
+ next._normalized = true;
1156
+ var params = assign(assign({}, current.params), next.params);
1084
1157
  if (current.name) {
1085
- next.name = current.name
1086
- next.params = params
1158
+ next.name = current.name;
1159
+ next.params = params;
1087
1160
  } else if (current.matched) {
1088
- var rawPath = current.matched[current.matched.length - 1].path
1089
- next.path = fillParams(rawPath, params, ("path " + (current.path)))
1090
- } else if ("development" !== 'production') {
1091
- warn(false, "relative params navigation requires a current route.")
1161
+ var rawPath = current.matched[current.matched.length - 1].path;
1162
+ next.path = fillParams(rawPath, params, ("path " + (current.path)));
1163
+ } else {
1164
+ warn(false, "relative params navigation requires a current route.");
1092
1165
  }
1093
1166
  return next
1094
1167
  }
1095
1168
 
1096
- var parsedPath = parsePath(next.path || '')
1097
- var basePath = (current && current.path) || '/'
1169
+ var parsedPath = parsePath(next.path || '');
1170
+ var basePath = (current && current.path) || '/';
1098
1171
  var path = parsedPath.path
1099
1172
  ? resolvePath(parsedPath.path, basePath, append || next.append)
1100
- : (current && current.path) || '/'
1101
- var query = resolveQuery(parsedPath.query, next.query)
1102
- var hash = next.hash || parsedPath.hash
1173
+ : (current && current.path) || '/';
1174
+ var query = resolveQuery(parsedPath.query, next.query);
1175
+ var hash = next.hash || parsedPath.hash;
1103
1176
  if (hash && hash.charAt(0) !== '#') {
1104
- hash = "#" + hash
1177
+ hash = "#" + hash;
1105
1178
  }
1106
1179
 
1107
1180
  return {
@@ -1114,7 +1187,7 @@ function normalizeLocation (
1114
1187
 
1115
1188
  function assign (a, b) {
1116
1189
  for (var key in b) {
1117
- a[key] = b[key]
1190
+ a[key] = b[key];
1118
1191
  }
1119
1192
  return a
1120
1193
  }
@@ -1126,38 +1199,45 @@ function createMatcher (routes) {
1126
1199
  var pathMap = ref.pathMap;
1127
1200
  var nameMap = ref.nameMap;
1128
1201
 
1202
+ function addRoutes (routes) {
1203
+ createRouteMap(routes, pathMap, nameMap);
1204
+ }
1205
+
1129
1206
  function match (
1130
1207
  raw,
1131
1208
  currentRoute,
1132
1209
  redirectedFrom
1133
1210
  ) {
1134
- var location = normalizeLocation(raw, currentRoute)
1211
+ var location = normalizeLocation(raw, currentRoute);
1135
1212
  var name = location.name;
1136
1213
 
1137
1214
  if (name) {
1138
- var record = nameMap[name]
1215
+ var record = nameMap[name];
1216
+ {
1217
+ warn(record, ("Route with name '" + name + "' does not exist"));
1218
+ }
1139
1219
  var paramNames = getRouteRegex(record.path).keys
1140
1220
  .filter(function (key) { return !key.optional; })
1141
- .map(function (key) { return key.name; })
1221
+ .map(function (key) { return key.name; });
1142
1222
 
1143
1223
  if (typeof location.params !== 'object') {
1144
- location.params = {}
1224
+ location.params = {};
1145
1225
  }
1146
1226
 
1147
1227
  if (currentRoute && typeof currentRoute.params === 'object') {
1148
1228
  for (var key in currentRoute.params) {
1149
1229
  if (!(key in location.params) && paramNames.indexOf(key) > -1) {
1150
- location.params[key] = currentRoute.params[key]
1230
+ location.params[key] = currentRoute.params[key];
1151
1231
  }
1152
1232
  }
1153
1233
  }
1154
1234
 
1155
1235
  if (record) {
1156
- location.path = fillParams(record.path, location.params, ("named route \"" + name + "\""))
1236
+ location.path = fillParams(record.path, location.params, ("named route \"" + name + "\""));
1157
1237
  return _createRoute(record, location, redirectedFrom)
1158
1238
  }
1159
1239
  } else if (location.path) {
1160
- location.params = {}
1240
+ location.params = {};
1161
1241
  for (var path in pathMap) {
1162
1242
  if (matchRoute(path, location.params, location.path)) {
1163
1243
  return _createRoute(pathMap[path], location, redirectedFrom)
@@ -1172,37 +1252,37 @@ function createMatcher (routes) {
1172
1252
  record,
1173
1253
  location
1174
1254
  ) {
1175
- var originalRedirect = record.redirect
1255
+ var originalRedirect = record.redirect;
1176
1256
  var redirect = typeof originalRedirect === 'function'
1177
1257
  ? originalRedirect(createRoute(record, location))
1178
- : originalRedirect
1258
+ : originalRedirect;
1179
1259
 
1180
1260
  if (typeof redirect === 'string') {
1181
- redirect = { path: redirect }
1261
+ redirect = { path: redirect };
1182
1262
  }
1183
1263
 
1184
1264
  if (!redirect || typeof redirect !== 'object') {
1185
1265
  "development" !== 'production' && warn(
1186
1266
  false, ("invalid redirect option: " + (JSON.stringify(redirect)))
1187
- )
1267
+ );
1188
1268
  return _createRoute(null, location)
1189
1269
  }
1190
1270
 
1191
- var re = redirect
1271
+ var re = redirect;
1192
1272
  var name = re.name;
1193
1273
  var path = re.path;
1194
1274
  var query = location.query;
1195
1275
  var hash = location.hash;
1196
1276
  var params = location.params;
1197
- query = re.hasOwnProperty('query') ? re.query : query
1198
- hash = re.hasOwnProperty('hash') ? re.hash : hash
1199
- params = re.hasOwnProperty('params') ? re.params : params
1277
+ query = re.hasOwnProperty('query') ? re.query : query;
1278
+ hash = re.hasOwnProperty('hash') ? re.hash : hash;
1279
+ params = re.hasOwnProperty('params') ? re.params : params;
1200
1280
 
1201
1281
  if (name) {
1202
1282
  // resolved named direct
1203
- var targetRecord = nameMap[name]
1204
- if ("development" !== 'production') {
1205
- assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."))
1283
+ var targetRecord = nameMap[name];
1284
+ {
1285
+ assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."));
1206
1286
  }
1207
1287
  return match({
1208
1288
  _normalized: true,
@@ -1213,9 +1293,9 @@ function createMatcher (routes) {
1213
1293
  }, undefined, location)
1214
1294
  } else if (path) {
1215
1295
  // 1. resolve relative redirect
1216
- var rawPath = resolveRecordPath(path, record)
1296
+ var rawPath = resolveRecordPath(path, record);
1217
1297
  // 2. resolve params
1218
- var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\""))
1298
+ var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\""));
1219
1299
  // 3. rematch with existing query and hash
1220
1300
  return match({
1221
1301
  _normalized: true,
@@ -1224,7 +1304,7 @@ function createMatcher (routes) {
1224
1304
  hash: hash
1225
1305
  }, undefined, location)
1226
1306
  } else {
1227
- warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))))
1307
+ warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))));
1228
1308
  return _createRoute(null, location)
1229
1309
  }
1230
1310
  }
@@ -1234,15 +1314,15 @@ function createMatcher (routes) {
1234
1314
  location,
1235
1315
  matchAs
1236
1316
  ) {
1237
- var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\""))
1317
+ var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\""));
1238
1318
  var aliasedMatch = match({
1239
1319
  _normalized: true,
1240
1320
  path: aliasedPath
1241
- })
1321
+ });
1242
1322
  if (aliasedMatch) {
1243
- var matched = aliasedMatch.matched
1244
- var aliasedRecord = matched[matched.length - 1]
1245
- location.params = aliasedMatch.params
1323
+ var matched = aliasedMatch.matched;
1324
+ var aliasedRecord = matched[matched.length - 1];
1325
+ location.params = aliasedMatch.params;
1246
1326
  return _createRoute(aliasedRecord, location)
1247
1327
  }
1248
1328
  return _createRoute(null, location)
@@ -1262,7 +1342,10 @@ function createMatcher (routes) {
1262
1342
  return createRoute(record, location, redirectedFrom)
1263
1343
  }
1264
1344
 
1265
- return match
1345
+ return {
1346
+ match: match,
1347
+ addRoutes: addRoutes
1348
+ }
1266
1349
  }
1267
1350
 
1268
1351
  function matchRoute (
@@ -1273,7 +1356,7 @@ function matchRoute (
1273
1356
  var ref = getRouteRegex(path);
1274
1357
  var regexp = ref.regexp;
1275
1358
  var keys = ref.keys;
1276
- var m = pathname.match(regexp)
1359
+ var m = pathname.match(regexp);
1277
1360
 
1278
1361
  if (!m) {
1279
1362
  return false
@@ -1282,9 +1365,9 @@ function matchRoute (
1282
1365
  }
1283
1366
 
1284
1367
  for (var i = 1, len = m.length; i < len; ++i) {
1285
- var key = keys[i - 1]
1286
- var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i]
1287
- if (key) { params[key.name] = val }
1368
+ var key = keys[i - 1];
1369
+ var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i];
1370
+ if (key) { params[key.name] = val; }
1288
1371
  }
1289
1372
 
1290
1373
  return true
@@ -1296,10 +1379,108 @@ function resolveRecordPath (path, record) {
1296
1379
 
1297
1380
  /* */
1298
1381
 
1299
- var inBrowser = typeof window !== 'undefined'
1300
1382
 
1301
- var supportsHistory = inBrowser && (function () {
1302
- var ua = window.navigator.userAgent
1383
+ var positionStore = Object.create(null);
1384
+
1385
+ function setupScroll () {
1386
+ window.addEventListener('popstate', function (e) {
1387
+ if (e.state && e.state.key) {
1388
+ setStateKey(e.state.key);
1389
+ }
1390
+ });
1391
+
1392
+ window.addEventListener('scroll', saveScrollPosition);
1393
+ }
1394
+
1395
+ function handleScroll (
1396
+ router,
1397
+ to,
1398
+ from,
1399
+ isPop
1400
+ ) {
1401
+ if (!router.app) {
1402
+ return
1403
+ }
1404
+
1405
+ var behavior = router.options.scrollBehavior;
1406
+ if (!behavior) {
1407
+ return
1408
+ }
1409
+
1410
+ {
1411
+ assert(typeof behavior === 'function', "scrollBehavior must be a function");
1412
+ }
1413
+
1414
+ // wait until re-render finishes before scrolling
1415
+ router.app.$nextTick(function () {
1416
+ var position = getScrollPosition();
1417
+ var shouldScroll = behavior(to, from, isPop ? position : null);
1418
+ if (!shouldScroll) {
1419
+ return
1420
+ }
1421
+ var isObject = typeof shouldScroll === 'object';
1422
+ if (isObject && typeof shouldScroll.selector === 'string') {
1423
+ var el = document.querySelector(shouldScroll.selector);
1424
+ if (el) {
1425
+ position = getElementPosition(el);
1426
+ } else if (isValidPosition(shouldScroll)) {
1427
+ position = normalizePosition(shouldScroll);
1428
+ }
1429
+ } else if (isObject && isValidPosition(shouldScroll)) {
1430
+ position = normalizePosition(shouldScroll);
1431
+ }
1432
+
1433
+ if (position) {
1434
+ window.scrollTo(position.x, position.y);
1435
+ }
1436
+ });
1437
+ }
1438
+
1439
+ function saveScrollPosition () {
1440
+ var key = getStateKey();
1441
+ if (key) {
1442
+ positionStore[key] = {
1443
+ x: window.pageXOffset,
1444
+ y: window.pageYOffset
1445
+ };
1446
+ }
1447
+ }
1448
+
1449
+ function getScrollPosition () {
1450
+ var key = getStateKey();
1451
+ if (key) {
1452
+ return positionStore[key]
1453
+ }
1454
+ }
1455
+
1456
+ function getElementPosition (el) {
1457
+ var docRect = document.documentElement.getBoundingClientRect();
1458
+ var elRect = el.getBoundingClientRect();
1459
+ return {
1460
+ x: elRect.left - docRect.left,
1461
+ y: elRect.top - docRect.top
1462
+ }
1463
+ }
1464
+
1465
+ function isValidPosition (obj) {
1466
+ return isNumber(obj.x) || isNumber(obj.y)
1467
+ }
1468
+
1469
+ function normalizePosition (obj) {
1470
+ return {
1471
+ x: isNumber(obj.x) ? obj.x : window.pageXOffset,
1472
+ y: isNumber(obj.y) ? obj.y : window.pageYOffset
1473
+ }
1474
+ }
1475
+
1476
+ function isNumber (v) {
1477
+ return typeof v === 'number'
1478
+ }
1479
+
1480
+ /* */
1481
+
1482
+ var supportsPushState = inBrowser && (function () {
1483
+ var ua = window.navigator.userAgent;
1303
1484
 
1304
1485
  if (
1305
1486
  (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
@@ -1311,64 +1492,127 @@ var supportsHistory = inBrowser && (function () {
1311
1492
  }
1312
1493
 
1313
1494
  return window.history && 'pushState' in window.history
1314
- })()
1495
+ })();
1496
+
1497
+ // use User Timing api (if present) for more accurate key precision
1498
+ var Time = inBrowser && window.performance && window.performance.now
1499
+ ? window.performance
1500
+ : Date;
1501
+
1502
+ var _key = genKey();
1503
+
1504
+ function genKey () {
1505
+ return Time.now().toFixed(3)
1506
+ }
1507
+
1508
+ function getStateKey () {
1509
+ return _key
1510
+ }
1511
+
1512
+ function setStateKey (key) {
1513
+ _key = key;
1514
+ }
1515
+
1516
+ function pushState (url, replace) {
1517
+ // try...catch the pushState call to get around Safari
1518
+ // DOM Exception 18 where it limits to 100 pushState calls
1519
+ var history = window.history;
1520
+ try {
1521
+ if (replace) {
1522
+ history.replaceState({ key: _key }, '', url);
1523
+ } else {
1524
+ _key = genKey();
1525
+ history.pushState({ key: _key }, '', url);
1526
+ }
1527
+ saveScrollPosition();
1528
+ } catch (e) {
1529
+ window.location[replace ? 'replace' : 'assign'](url);
1530
+ }
1531
+ }
1532
+
1533
+ function replaceState (url) {
1534
+ pushState(url, true);
1535
+ }
1315
1536
 
1316
1537
  /* */
1317
1538
 
1318
1539
  function runQueue (queue, fn, cb) {
1319
1540
  var step = function (index) {
1320
1541
  if (index >= queue.length) {
1321
- cb()
1542
+ cb();
1322
1543
  } else {
1323
1544
  if (queue[index]) {
1324
1545
  fn(queue[index], function () {
1325
- step(index + 1)
1326
- })
1546
+ step(index + 1);
1547
+ });
1327
1548
  } else {
1328
- step(index + 1)
1549
+ step(index + 1);
1329
1550
  }
1330
1551
  }
1331
- }
1332
- step(0)
1552
+ };
1553
+ step(0);
1333
1554
  }
1334
1555
 
1335
1556
  /* */
1336
1557
 
1337
1558
 
1338
1559
  var History = function History (router, base) {
1339
- this.router = router
1340
- this.base = normalizeBase(base)
1560
+ this.router = router;
1561
+ this.base = normalizeBase(base);
1341
1562
  // start with a route object that stands for "nowhere"
1342
- this.current = START
1343
- this.pending = null
1563
+ this.current = START;
1564
+ this.pending = null;
1565
+ this.ready = false;
1566
+ this.readyCbs = [];
1344
1567
  };
1345
1568
 
1346
1569
  History.prototype.listen = function listen (cb) {
1347
- this.cb = cb
1570
+ this.cb = cb;
1571
+ };
1572
+
1573
+ History.prototype.onReady = function onReady (cb) {
1574
+ if (this.ready) {
1575
+ cb();
1576
+ } else {
1577
+ this.readyCbs.push(cb);
1578
+ }
1348
1579
  };
1349
1580
 
1350
1581
  History.prototype.transitionTo = function transitionTo (location, onComplete, onAbort) {
1351
1582
  var this$1 = this;
1352
1583
 
1353
- var route = this.router.match(location, this.current)
1584
+ var route = this.router.match(location, this.current);
1354
1585
  this.confirmTransition(route, function () {
1355
- this$1.updateRoute(route)
1356
- onComplete && onComplete(route)
1357
- this$1.ensureURL()
1358
- }, onAbort)
1586
+ this$1.updateRoute(route);
1587
+ onComplete && onComplete(route);
1588
+ this$1.ensureURL();
1589
+
1590
+ // fire ready cbs once
1591
+ if (!this$1.ready) {
1592
+ this$1.ready = true;
1593
+ this$1.readyCbs.forEach(function (cb) {
1594
+ cb(route);
1595
+ });
1596
+ }
1597
+ }, onAbort);
1359
1598
  };
1360
1599
 
1361
1600
  History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) {
1362
1601
  var this$1 = this;
1363
1602
 
1364
- var current = this.current
1365
- var abort = function () { onAbort && onAbort() }
1366
- if (isSameRoute(route, current)) {
1367
- this.ensureURL()
1603
+ var current = this.current;
1604
+ var abort = function () { onAbort && onAbort(); };
1605
+ if (
1606
+ isSameRoute(route, current) &&
1607
+ // in the case the route map has been dynamically appended to
1608
+ route.matched.length === current.matched.length
1609
+ ) {
1610
+ this.ensureURL();
1368
1611
  return abort()
1369
1612
  }
1370
1613
 
1371
1614
  var ref = resolveQueue(this.current.matched, route.matched);
1615
+ var updated = ref.updated;
1372
1616
  var deactivated = ref.deactivated;
1373
1617
  var activated = ref.activated;
1374
1618
 
@@ -1377,13 +1621,15 @@ History.prototype.confirmTransition = function confirmTransition (route, onCompl
1377
1621
  extractLeaveGuards(deactivated),
1378
1622
  // global before hooks
1379
1623
  this.router.beforeHooks,
1380
- // enter guards
1624
+ // in-component update hooks
1625
+ extractUpdateHooks(updated),
1626
+ // in-config enter guards
1381
1627
  activated.map(function (m) { return m.beforeEnter; }),
1382
1628
  // async components
1383
1629
  resolveAsyncComponents(activated)
1384
- )
1630
+ );
1385
1631
 
1386
- this.pending = route
1632
+ this.pending = route;
1387
1633
  var iterator = function (hook, next) {
1388
1634
  if (this$1.pending !== route) {
1389
1635
  return abort()
@@ -1391,63 +1637,62 @@ History.prototype.confirmTransition = function confirmTransition (route, onCompl
1391
1637
  hook(route, current, function (to) {
1392
1638
  if (to === false) {
1393
1639
  // next(false) -> abort navigation, ensure current URL
1394
- this$1.ensureURL(true)
1395
- abort()
1640
+ this$1.ensureURL(true);
1641
+ abort();
1396
1642
  } else if (typeof to === 'string' || typeof to === 'object') {
1397
1643
  // next('/') or next({ path: '/' }) -> redirect
1398
- (typeof to === 'object' && to.replace) ? this$1.replace(to) : this$1.push(to)
1399
- abort()
1644
+ (typeof to === 'object' && to.replace) ? this$1.replace(to) : this$1.push(to);
1645
+ abort();
1400
1646
  } else {
1401
1647
  // confirm transition and pass on the value
1402
- next(to)
1648
+ next(to);
1403
1649
  }
1404
- })
1405
- }
1650
+ });
1651
+ };
1406
1652
 
1407
1653
  runQueue(queue, iterator, function () {
1408
- var postEnterCbs = []
1409
- var enterGuards = extractEnterGuards(activated, postEnterCbs, function () {
1410
- return this$1.current === route
1411
- })
1654
+ var postEnterCbs = [];
1655
+ var isValid = function () { return this$1.current === route; };
1656
+ var enterGuards = extractEnterGuards(activated, postEnterCbs, isValid);
1412
1657
  // wait until async components are resolved before
1413
1658
  // extracting in-component enter guards
1414
1659
  runQueue(enterGuards, iterator, function () {
1415
1660
  if (this$1.pending !== route) {
1416
1661
  return abort()
1417
1662
  }
1418
- this$1.pending = null
1419
- onComplete(route)
1663
+ this$1.pending = null;
1664
+ onComplete(route);
1420
1665
  if (this$1.router.app) {
1421
1666
  this$1.router.app.$nextTick(function () {
1422
- postEnterCbs.forEach(function (cb) { return cb(); })
1423
- })
1667
+ postEnterCbs.forEach(function (cb) { return cb(); });
1668
+ });
1424
1669
  }
1425
- })
1426
- })
1670
+ });
1671
+ });
1427
1672
  };
1428
1673
 
1429
1674
  History.prototype.updateRoute = function updateRoute (route) {
1430
- var prev = this.current
1431
- this.current = route
1432
- this.cb && this.cb(route)
1675
+ var prev = this.current;
1676
+ this.current = route;
1677
+ this.cb && this.cb(route);
1433
1678
  this.router.afterHooks.forEach(function (hook) {
1434
- hook && hook(route, prev)
1435
- })
1679
+ hook && hook(route, prev);
1680
+ });
1436
1681
  };
1437
1682
 
1438
1683
  function normalizeBase (base) {
1439
1684
  if (!base) {
1440
1685
  if (inBrowser) {
1441
1686
  // respect <base> tag
1442
- var baseEl = document.querySelector('base')
1443
- base = baseEl ? baseEl.getAttribute('href') : '/'
1687
+ var baseEl = document.querySelector('base');
1688
+ base = baseEl ? baseEl.getAttribute('href') : '/';
1444
1689
  } else {
1445
- base = '/'
1690
+ base = '/';
1446
1691
  }
1447
1692
  }
1448
1693
  // make sure there's the starting slash
1449
1694
  if (base.charAt(0) !== '/') {
1450
- base = '/' + base
1695
+ base = '/' + base;
1451
1696
  }
1452
1697
  // remove trailing slash
1453
1698
  return base.replace(/\/$/, '')
@@ -1457,75 +1702,82 @@ function resolveQueue (
1457
1702
  current,
1458
1703
  next
1459
1704
  ) {
1460
- var i
1461
- var max = Math.max(current.length, next.length)
1705
+ var i;
1706
+ var max = Math.max(current.length, next.length);
1462
1707
  for (i = 0; i < max; i++) {
1463
1708
  if (current[i] !== next[i]) {
1464
1709
  break
1465
1710
  }
1466
1711
  }
1467
1712
  return {
1713
+ updated: next.slice(0, i),
1468
1714
  activated: next.slice(i),
1469
1715
  deactivated: current.slice(i)
1470
1716
  }
1471
1717
  }
1472
1718
 
1719
+ function extractGuards (
1720
+ records,
1721
+ name,
1722
+ bind,
1723
+ reverse
1724
+ ) {
1725
+ var guards = flatMapComponents(records, function (def, instance, match, key) {
1726
+ var guard = extractGuard(def, name);
1727
+ if (guard) {
1728
+ return Array.isArray(guard)
1729
+ ? guard.map(function (guard) { return bind(guard, instance, match, key); })
1730
+ : bind(guard, instance, match, key)
1731
+ }
1732
+ });
1733
+ return flatten(reverse ? guards.reverse() : guards)
1734
+ }
1735
+
1473
1736
  function extractGuard (
1474
1737
  def,
1475
1738
  key
1476
1739
  ) {
1477
1740
  if (typeof def !== 'function') {
1478
1741
  // extend now so that global mixins are applied.
1479
- def = _Vue.extend(def)
1742
+ def = _Vue.extend(def);
1480
1743
  }
1481
1744
  return def.options[key]
1482
1745
  }
1483
1746
 
1484
- function extractLeaveGuards (matched) {
1485
- return flatten(flatMapComponents(matched, function (def, instance) {
1486
- var guard = extractGuard(def, 'beforeRouteLeave')
1487
- if (guard) {
1488
- return Array.isArray(guard)
1489
- ? guard.map(function (guard) { return wrapLeaveGuard(guard, instance); })
1490
- : wrapLeaveGuard(guard, instance)
1491
- }
1492
- }).reverse())
1747
+ function extractLeaveGuards (deactivated) {
1748
+ return extractGuards(deactivated, 'beforeRouteLeave', bindGuard, true)
1493
1749
  }
1494
1750
 
1495
- function wrapLeaveGuard (
1496
- guard,
1497
- instance
1498
- ) {
1499
- return function routeLeaveGuard () {
1751
+ function extractUpdateHooks (updated) {
1752
+ return extractGuards(updated, 'beforeRouteUpdate', bindGuard)
1753
+ }
1754
+
1755
+ function bindGuard (guard, instance) {
1756
+ return function boundRouteGuard () {
1500
1757
  return guard.apply(instance, arguments)
1501
1758
  }
1502
1759
  }
1503
1760
 
1504
1761
  function extractEnterGuards (
1505
- matched,
1762
+ activated,
1506
1763
  cbs,
1507
1764
  isValid
1508
1765
  ) {
1509
- return flatten(flatMapComponents(matched, function (def, _, match, key) {
1510
- var guard = extractGuard(def, 'beforeRouteEnter')
1511
- if (guard) {
1512
- return Array.isArray(guard)
1513
- ? guard.map(function (guard) { return wrapEnterGuard(guard, cbs, match, key, isValid); })
1514
- : wrapEnterGuard(guard, cbs, match, key, isValid)
1515
- }
1516
- }))
1766
+ return extractGuards(activated, 'beforeRouteEnter', function (guard, _, match, key) {
1767
+ return bindEnterGuard(guard, match, key, cbs, isValid)
1768
+ })
1517
1769
  }
1518
1770
 
1519
- function wrapEnterGuard (
1771
+ function bindEnterGuard (
1520
1772
  guard,
1521
- cbs,
1522
1773
  match,
1523
1774
  key,
1775
+ cbs,
1524
1776
  isValid
1525
1777
  ) {
1526
1778
  return function routeEnterGuard (to, from, next) {
1527
1779
  return guard(to, from, function (cb) {
1528
- next(cb)
1780
+ next(cb);
1529
1781
  if (typeof cb === 'function') {
1530
1782
  cbs.push(function () {
1531
1783
  // #750
@@ -1533,8 +1785,8 @@ function wrapEnterGuard (
1533
1785
  // the instance may not have been registered at this time.
1534
1786
  // we will need to poll for registration until current route
1535
1787
  // is no longer valid.
1536
- poll(cb, match.instances, key, isValid)
1537
- })
1788
+ poll(cb, match.instances, key, isValid);
1789
+ });
1538
1790
  }
1539
1791
  })
1540
1792
  }
@@ -1547,11 +1799,11 @@ function poll (
1547
1799
  isValid
1548
1800
  ) {
1549
1801
  if (instances[key]) {
1550
- cb(instances[key])
1802
+ cb(instances[key]);
1551
1803
  } else if (isValid()) {
1552
1804
  setTimeout(function () {
1553
- poll(cb, instances, key, isValid)
1554
- }, 16)
1805
+ poll(cb, instances, key, isValid);
1806
+ }, 16);
1555
1807
  }
1556
1808
  }
1557
1809
 
@@ -1564,19 +1816,19 @@ function resolveAsyncComponents (matched) {
1564
1816
  // resolved.
1565
1817
  if (typeof def === 'function' && !def.options) {
1566
1818
  return function (to, from, next) {
1567
- var resolve = function (resolvedDef) {
1568
- match.components[key] = resolvedDef
1569
- next()
1570
- }
1819
+ var resolve = once(function (resolvedDef) {
1820
+ match.components[key] = resolvedDef;
1821
+ next();
1822
+ });
1571
1823
 
1572
- var reject = function (reason) {
1573
- warn(false, ("Failed to resolve async component " + key + ": " + reason))
1574
- next(false)
1575
- }
1824
+ var reject = once(function (reason) {
1825
+ warn(false, ("Failed to resolve async component " + key + ": " + reason));
1826
+ next(false);
1827
+ });
1576
1828
 
1577
- var res = def(resolve, reject)
1829
+ var res = def(resolve, reject);
1578
1830
  if (res && typeof res.then === 'function') {
1579
- res.then(resolve, reject)
1831
+ res.then(resolve, reject);
1580
1832
  }
1581
1833
  }
1582
1834
  }
@@ -1600,316 +1852,245 @@ function flatten (arr) {
1600
1852
  return Array.prototype.concat.apply([], arr)
1601
1853
  }
1602
1854
 
1603
- /* */
1604
-
1605
- var positionStore = Object.create(null)
1606
-
1607
- function saveScrollPosition (key) {
1608
- if (!key) { return }
1609
- positionStore[key] = {
1610
- x: window.pageXOffset,
1611
- y: window.pageYOffset
1612
- }
1613
- }
1614
-
1615
- function getScrollPosition (key) {
1616
- if (!key) { return }
1617
- return positionStore[key]
1618
- }
1619
-
1620
- function getElementPosition (el) {
1621
- var docRect = document.documentElement.getBoundingClientRect()
1622
- var elRect = el.getBoundingClientRect()
1623
- return {
1624
- x: elRect.left - docRect.left,
1625
- y: elRect.top - docRect.top
1626
- }
1627
- }
1628
-
1629
- function isValidPosition (obj) {
1630
- return isNumber(obj.x) || isNumber(obj.y)
1631
- }
1632
-
1633
- function normalizePosition (obj) {
1634
- return {
1635
- x: isNumber(obj.x) ? obj.x : window.pageXOffset,
1636
- y: isNumber(obj.y) ? obj.y : window.pageYOffset
1855
+ // in Webpack 2, require.ensure now also returns a Promise
1856
+ // so the resolve/reject functions may get called an extra time
1857
+ // if the user uses an arrow function shorthand that happens to
1858
+ // return that Promise.
1859
+ function once (fn) {
1860
+ var called = false;
1861
+ return function () {
1862
+ if (called) { return }
1863
+ called = true;
1864
+ return fn.apply(this, arguments)
1637
1865
  }
1638
1866
  }
1639
1867
 
1640
- function isNumber (v) {
1641
- return typeof v === 'number'
1642
- }
1643
-
1644
1868
  /* */
1645
1869
 
1646
1870
 
1647
- var genKey = function () { return String(Date.now()); }
1648
- var _key = genKey()
1649
-
1650
- var HTML5History = (function (History) {
1871
+ var HTML5History = (function (History$$1) {
1651
1872
  function HTML5History (router, base) {
1652
1873
  var this$1 = this;
1653
1874
 
1654
- History.call(this, router, base)
1875
+ History$$1.call(this, router, base);
1655
1876
 
1656
- var expectScroll = router.options.scrollBehavior
1657
- window.addEventListener('popstate', function (e) {
1658
- _key = e.state && e.state.key
1659
- var current = this$1.current
1660
- this$1.transitionTo(getLocation(this$1.base), function (next) {
1661
- if (expectScroll) {
1662
- this$1.handleScroll(next, current, true)
1663
- }
1664
- })
1665
- })
1877
+ var expectScroll = router.options.scrollBehavior;
1666
1878
 
1667
1879
  if (expectScroll) {
1668
- window.addEventListener('scroll', function () {
1669
- saveScrollPosition(_key)
1670
- })
1880
+ setupScroll();
1671
1881
  }
1882
+
1883
+ window.addEventListener('popstate', function (e) {
1884
+ this$1.transitionTo(getLocation(this$1.base), function (route) {
1885
+ if (expectScroll) {
1886
+ handleScroll(router, route, this$1.current, true);
1887
+ }
1888
+ });
1889
+ });
1672
1890
  }
1673
1891
 
1674
- if ( History ) HTML5History.__proto__ = History;
1675
- HTML5History.prototype = Object.create( History && History.prototype );
1892
+ if ( History$$1 ) HTML5History.__proto__ = History$$1;
1893
+ HTML5History.prototype = Object.create( History$$1 && History$$1.prototype );
1676
1894
  HTML5History.prototype.constructor = HTML5History;
1677
1895
 
1678
1896
  HTML5History.prototype.go = function go (n) {
1679
- window.history.go(n)
1897
+ window.history.go(n);
1680
1898
  };
1681
1899
 
1682
- HTML5History.prototype.push = function push (location) {
1900
+ HTML5History.prototype.push = function push (location, onComplete, onAbort) {
1683
1901
  var this$1 = this;
1684
1902
 
1685
- var current = this.current
1686
1903
  this.transitionTo(location, function (route) {
1687
- pushState(cleanPath(this$1.base + route.fullPath))
1688
- this$1.handleScroll(route, current, false)
1689
- })
1904
+ pushState(cleanPath(this$1.base + route.fullPath));
1905
+ handleScroll(this$1.router, route, this$1.current, false);
1906
+ onComplete && onComplete(route);
1907
+ }, onAbort);
1690
1908
  };
1691
1909
 
1692
- HTML5History.prototype.replace = function replace (location) {
1910
+ HTML5History.prototype.replace = function replace (location, onComplete, onAbort) {
1693
1911
  var this$1 = this;
1694
1912
 
1695
- var current = this.current
1696
1913
  this.transitionTo(location, function (route) {
1697
- replaceState(cleanPath(this$1.base + route.fullPath))
1698
- this$1.handleScroll(route, current, false)
1699
- })
1914
+ replaceState(cleanPath(this$1.base + route.fullPath));
1915
+ handleScroll(this$1.router, route, this$1.current, false);
1916
+ onComplete && onComplete(route);
1917
+ }, onAbort);
1700
1918
  };
1701
1919
 
1702
1920
  HTML5History.prototype.ensureURL = function ensureURL (push) {
1703
1921
  if (getLocation(this.base) !== this.current.fullPath) {
1704
- var current = cleanPath(this.base + this.current.fullPath)
1705
- push ? pushState(current) : replaceState(current)
1922
+ var current = cleanPath(this.base + this.current.fullPath);
1923
+ push ? pushState(current) : replaceState(current);
1706
1924
  }
1707
1925
  };
1708
1926
 
1709
- HTML5History.prototype.handleScroll = function handleScroll (to, from, isPop) {
1710
- var router = this.router
1711
- if (!router.app) {
1712
- return
1713
- }
1714
-
1715
- var behavior = router.options.scrollBehavior
1716
- if (!behavior) {
1717
- return
1718
- }
1719
- if ("development" !== 'production') {
1720
- assert(typeof behavior === 'function', "scrollBehavior must be a function")
1721
- }
1722
-
1723
- // wait until re-render finishes before scrolling
1724
- router.app.$nextTick(function () {
1725
- var position = getScrollPosition(_key)
1726
- var shouldScroll = behavior(to, from, isPop ? position : null)
1727
- if (!shouldScroll) {
1728
- return
1729
- }
1730
- var isObject = typeof shouldScroll === 'object'
1731
- if (isObject && typeof shouldScroll.selector === 'string') {
1732
- var el = document.querySelector(shouldScroll.selector)
1733
- if (el) {
1734
- position = getElementPosition(el)
1735
- } else if (isValidPosition(shouldScroll)) {
1736
- position = normalizePosition(shouldScroll)
1737
- }
1738
- } else if (isObject && isValidPosition(shouldScroll)) {
1739
- position = normalizePosition(shouldScroll)
1740
- }
1741
-
1742
- if (position) {
1743
- window.scrollTo(position.x, position.y)
1744
- }
1745
- })
1927
+ HTML5History.prototype.getCurrentLocation = function getCurrentLocation () {
1928
+ return getLocation(this.base)
1746
1929
  };
1747
1930
 
1748
1931
  return HTML5History;
1749
1932
  }(History));
1750
1933
 
1751
1934
  function getLocation (base) {
1752
- var path = window.location.pathname
1935
+ var path = window.location.pathname;
1753
1936
  if (base && path.indexOf(base) === 0) {
1754
- path = path.slice(base.length)
1937
+ path = path.slice(base.length);
1755
1938
  }
1756
1939
  return (path || '/') + window.location.search + window.location.hash
1757
1940
  }
1758
1941
 
1759
- function pushState (url, replace) {
1760
- // try...catch the pushState call to get around Safari
1761
- // DOM Exception 18 where it limits to 100 pushState calls
1762
- var history = window.history
1763
- try {
1764
- if (replace) {
1765
- history.replaceState({ key: _key }, '', url)
1766
- } else {
1767
- _key = genKey()
1768
- history.pushState({ key: _key }, '', url)
1769
- }
1770
- saveScrollPosition(_key)
1771
- } catch (e) {
1772
- window.location[replace ? 'assign' : 'replace'](url)
1773
- }
1774
- }
1775
-
1776
- function replaceState (url) {
1777
- pushState(url, true)
1778
- }
1779
-
1780
1942
  /* */
1781
1943
 
1782
1944
 
1783
- var HashHistory = (function (History) {
1945
+ var HashHistory = (function (History$$1) {
1784
1946
  function HashHistory (router, base, fallback) {
1785
- History.call(this, router, base)
1947
+ History$$1.call(this, router, base);
1786
1948
  // check history fallback deeplinking
1787
- if (fallback && this.checkFallback()) {
1949
+ if (fallback && checkFallback(this.base)) {
1788
1950
  return
1789
1951
  }
1790
- ensureSlash()
1952
+ ensureSlash();
1791
1953
  }
1792
1954
 
1793
- if ( History ) HashHistory.__proto__ = History;
1794
- HashHistory.prototype = Object.create( History && History.prototype );
1955
+ if ( History$$1 ) HashHistory.__proto__ = History$$1;
1956
+ HashHistory.prototype = Object.create( History$$1 && History$$1.prototype );
1795
1957
  HashHistory.prototype.constructor = HashHistory;
1796
1958
 
1797
- HashHistory.prototype.checkFallback = function checkFallback () {
1798
- var location = getLocation(this.base)
1799
- if (!/^\/#/.test(location)) {
1800
- window.location.replace(
1801
- cleanPath(this.base + '/#' + location)
1802
- )
1803
- return true
1804
- }
1805
- };
1959
+ // this is delayed until the app mounts
1960
+ // to avoid the hashchange listener being fired too early
1961
+ HashHistory.prototype.setupListeners = function setupListeners () {
1962
+ var this$1 = this;
1806
1963
 
1807
- HashHistory.prototype.onHashChange = function onHashChange () {
1808
- if (!ensureSlash()) {
1809
- return
1810
- }
1811
- this.transitionTo(getHash(), function (route) {
1812
- replaceHash(route.fullPath)
1813
- })
1964
+ window.addEventListener('hashchange', function () {
1965
+ if (!ensureSlash()) {
1966
+ return
1967
+ }
1968
+ this$1.transitionTo(getHash(), function (route) {
1969
+ replaceHash(route.fullPath);
1970
+ });
1971
+ });
1814
1972
  };
1815
1973
 
1816
- HashHistory.prototype.push = function push (location) {
1974
+ HashHistory.prototype.push = function push (location, onComplete, onAbort) {
1817
1975
  this.transitionTo(location, function (route) {
1818
- pushHash(route.fullPath)
1819
- })
1976
+ pushHash(route.fullPath);
1977
+ onComplete && onComplete(route);
1978
+ }, onAbort);
1820
1979
  };
1821
1980
 
1822
- HashHistory.prototype.replace = function replace (location) {
1981
+ HashHistory.prototype.replace = function replace (location, onComplete, onAbort) {
1823
1982
  this.transitionTo(location, function (route) {
1824
- replaceHash(route.fullPath)
1825
- })
1983
+ replaceHash(route.fullPath);
1984
+ onComplete && onComplete(route);
1985
+ }, onAbort);
1826
1986
  };
1827
1987
 
1828
1988
  HashHistory.prototype.go = function go (n) {
1829
- window.history.go(n)
1989
+ window.history.go(n);
1830
1990
  };
1831
1991
 
1832
1992
  HashHistory.prototype.ensureURL = function ensureURL (push) {
1833
- var current = this.current.fullPath
1993
+ var current = this.current.fullPath;
1834
1994
  if (getHash() !== current) {
1835
- push ? pushHash(current) : replaceHash(current)
1995
+ push ? pushHash(current) : replaceHash(current);
1836
1996
  }
1837
1997
  };
1838
1998
 
1999
+ HashHistory.prototype.getCurrentLocation = function getCurrentLocation () {
2000
+ return getHash()
2001
+ };
2002
+
1839
2003
  return HashHistory;
1840
2004
  }(History));
1841
2005
 
2006
+ function checkFallback (base) {
2007
+ var location = getLocation(base);
2008
+ if (!/^\/#/.test(location)) {
2009
+ window.location.replace(
2010
+ cleanPath(base + '/#' + location)
2011
+ );
2012
+ return true
2013
+ }
2014
+ }
2015
+
1842
2016
  function ensureSlash () {
1843
- var path = getHash()
2017
+ var path = getHash();
1844
2018
  if (path.charAt(0) === '/') {
1845
2019
  return true
1846
2020
  }
1847
- replaceHash('/' + path)
2021
+ replaceHash('/' + path);
1848
2022
  return false
1849
2023
  }
1850
2024
 
1851
2025
  function getHash () {
1852
2026
  // We can't use window.location.hash here because it's not
1853
2027
  // consistent across browsers - Firefox will pre-decode it!
1854
- var href = window.location.href
1855
- var index = href.indexOf('#')
2028
+ var href = window.location.href;
2029
+ var index = href.indexOf('#');
1856
2030
  return index === -1 ? '' : href.slice(index + 1)
1857
2031
  }
1858
2032
 
1859
2033
  function pushHash (path) {
1860
- window.location.hash = path
2034
+ window.location.hash = path;
1861
2035
  }
1862
2036
 
1863
2037
  function replaceHash (path) {
1864
- var i = window.location.href.indexOf('#')
2038
+ var i = window.location.href.indexOf('#');
1865
2039
  window.location.replace(
1866
2040
  window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path
1867
- )
2041
+ );
1868
2042
  }
1869
2043
 
1870
2044
  /* */
1871
2045
 
1872
2046
 
1873
- var AbstractHistory = (function (History) {
1874
- function AbstractHistory (router) {
1875
- History.call(this, router)
1876
- this.stack = []
1877
- this.index = -1
2047
+ var AbstractHistory = (function (History$$1) {
2048
+ function AbstractHistory (router, base) {
2049
+ History$$1.call(this, router, base);
2050
+ this.stack = [];
2051
+ this.index = -1;
1878
2052
  }
1879
2053
 
1880
- if ( History ) AbstractHistory.__proto__ = History;
1881
- AbstractHistory.prototype = Object.create( History && History.prototype );
2054
+ if ( History$$1 ) AbstractHistory.__proto__ = History$$1;
2055
+ AbstractHistory.prototype = Object.create( History$$1 && History$$1.prototype );
1882
2056
  AbstractHistory.prototype.constructor = AbstractHistory;
1883
2057
 
1884
- AbstractHistory.prototype.push = function push (location) {
2058
+ AbstractHistory.prototype.push = function push (location, onComplete, onAbort) {
1885
2059
  var this$1 = this;
1886
2060
 
1887
2061
  this.transitionTo(location, function (route) {
1888
- this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route)
1889
- this$1.index++
1890
- })
2062
+ this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route);
2063
+ this$1.index++;
2064
+ onComplete && onComplete(route);
2065
+ }, onAbort);
1891
2066
  };
1892
2067
 
1893
- AbstractHistory.prototype.replace = function replace (location) {
2068
+ AbstractHistory.prototype.replace = function replace (location, onComplete, onAbort) {
1894
2069
  var this$1 = this;
1895
2070
 
1896
2071
  this.transitionTo(location, function (route) {
1897
- this$1.stack = this$1.stack.slice(0, this$1.index).concat(route)
1898
- })
2072
+ this$1.stack = this$1.stack.slice(0, this$1.index).concat(route);
2073
+ onComplete && onComplete(route);
2074
+ }, onAbort);
1899
2075
  };
1900
2076
 
1901
2077
  AbstractHistory.prototype.go = function go (n) {
1902
2078
  var this$1 = this;
1903
2079
 
1904
- var targetIndex = this.index + n
2080
+ var targetIndex = this.index + n;
1905
2081
  if (targetIndex < 0 || targetIndex >= this.stack.length) {
1906
2082
  return
1907
2083
  }
1908
- var route = this.stack[targetIndex]
2084
+ var route = this.stack[targetIndex];
1909
2085
  this.confirmTransition(route, function () {
1910
- this$1.index = targetIndex
1911
- this$1.updateRoute(route)
1912
- })
2086
+ this$1.index = targetIndex;
2087
+ this$1.updateRoute(route);
2088
+ });
2089
+ };
2090
+
2091
+ AbstractHistory.prototype.getCurrentLocation = function getCurrentLocation () {
2092
+ var current = this.stack[this.stack.length - 1];
2093
+ return current ? current.fullPath : '/'
1913
2094
  };
1914
2095
 
1915
2096
  AbstractHistory.prototype.ensureURL = function ensureURL () {
@@ -1924,39 +2105,50 @@ var AbstractHistory = (function (History) {
1924
2105
  var VueRouter = function VueRouter (options) {
1925
2106
  if ( options === void 0 ) options = {};
1926
2107
 
1927
- this.app = null
1928
- this.options = options
1929
- this.beforeHooks = []
1930
- this.afterHooks = []
1931
- this.match = createMatcher(options.routes || [])
2108
+ this.app = null;
2109
+ this.apps = [];
2110
+ this.options = options;
2111
+ this.beforeHooks = [];
2112
+ this.afterHooks = [];
2113
+ this.matcher = createMatcher(options.routes || []);
1932
2114
 
1933
- var mode = options.mode || 'hash'
1934
- this.fallback = mode === 'history' && !supportsHistory
2115
+ var mode = options.mode || 'hash';
2116
+ this.fallback = mode === 'history' && !supportsPushState;
1935
2117
  if (this.fallback) {
1936
- mode = 'hash'
2118
+ mode = 'hash';
1937
2119
  }
1938
2120
  if (!inBrowser) {
1939
- mode = 'abstract'
2121
+ mode = 'abstract';
1940
2122
  }
1941
- this.mode = mode
2123
+ this.mode = mode;
1942
2124
 
1943
2125
  switch (mode) {
1944
2126
  case 'history':
1945
- this.history = new HTML5History(this, options.base)
2127
+ this.history = new HTML5History(this, options.base);
1946
2128
  break
1947
2129
  case 'hash':
1948
- this.history = new HashHistory(this, options.base, this.fallback)
2130
+ this.history = new HashHistory(this, options.base, this.fallback);
1949
2131
  break
1950
2132
  case 'abstract':
1951
- this.history = new AbstractHistory(this)
2133
+ this.history = new AbstractHistory(this, options.base);
1952
2134
  break
1953
2135
  default:
1954
- "development" !== 'production' && assert(false, ("invalid mode: " + mode))
2136
+ {
2137
+ assert(false, ("invalid mode: " + mode));
2138
+ }
1955
2139
  }
1956
2140
  };
1957
2141
 
1958
2142
  var prototypeAccessors = { currentRoute: {} };
1959
2143
 
2144
+ VueRouter.prototype.match = function match (
2145
+ raw,
2146
+ current,
2147
+ redirectedFrom
2148
+ ) {
2149
+ return this.matcher.match(raw, current, redirectedFrom)
2150
+ };
2151
+
1960
2152
  prototypeAccessors.currentRoute.get = function () {
1961
2153
  return this.history && this.history.current
1962
2154
  };
@@ -1968,60 +2160,75 @@ VueRouter.prototype.init = function init (app /* Vue component instance */) {
1968
2160
  install.installed,
1969
2161
  "not installed. Make sure to call `Vue.use(VueRouter)` " +
1970
2162
  "before creating root instance."
1971
- )
2163
+ );
2164
+
2165
+ this.apps.push(app);
1972
2166
 
1973
- this.app = app
2167
+ // main app already initialized.
2168
+ if (this.app) {
2169
+ return
2170
+ }
2171
+
2172
+ this.app = app;
1974
2173
 
1975
- var history = this.history
2174
+ var history = this.history;
1976
2175
 
1977
2176
  if (history instanceof HTML5History) {
1978
- history.transitionTo(getLocation(history.base))
2177
+ history.transitionTo(history.getCurrentLocation());
1979
2178
  } else if (history instanceof HashHistory) {
1980
2179
  var setupHashListener = function () {
1981
- window.addEventListener('hashchange', function () {
1982
- history.onHashChange()
1983
- })
1984
- }
1985
- history.transitionTo(getHash(), setupHashListener, setupHashListener)
2180
+ history.setupListeners();
2181
+ };
2182
+ history.transitionTo(
2183
+ history.getCurrentLocation(),
2184
+ setupHashListener,
2185
+ setupHashListener
2186
+ );
1986
2187
  }
1987
2188
 
1988
2189
  history.listen(function (route) {
1989
- this$1.app._route = route
1990
- })
2190
+ this$1.apps.forEach(function (app) {
2191
+ app._route = route;
2192
+ });
2193
+ });
1991
2194
  };
1992
2195
 
1993
2196
  VueRouter.prototype.beforeEach = function beforeEach (fn) {
1994
- this.beforeHooks.push(fn)
2197
+ this.beforeHooks.push(fn);
1995
2198
  };
1996
2199
 
1997
2200
  VueRouter.prototype.afterEach = function afterEach (fn) {
1998
- this.afterHooks.push(fn)
2201
+ this.afterHooks.push(fn);
1999
2202
  };
2000
2203
 
2001
- VueRouter.prototype.push = function push (location) {
2002
- this.history.push(location)
2204
+ VueRouter.prototype.onReady = function onReady (cb) {
2205
+ this.history.onReady(cb);
2003
2206
  };
2004
2207
 
2005
- VueRouter.prototype.replace = function replace (location) {
2006
- this.history.replace(location)
2208
+ VueRouter.prototype.push = function push (location, onComplete, onAbort) {
2209
+ this.history.push(location, onComplete, onAbort);
2210
+ };
2211
+
2212
+ VueRouter.prototype.replace = function replace (location, onComplete, onAbort) {
2213
+ this.history.replace(location, onComplete, onAbort);
2007
2214
  };
2008
2215
 
2009
2216
  VueRouter.prototype.go = function go (n) {
2010
- this.history.go(n)
2217
+ this.history.go(n);
2011
2218
  };
2012
2219
 
2013
2220
  VueRouter.prototype.back = function back () {
2014
- this.go(-1)
2221
+ this.go(-1);
2015
2222
  };
2016
2223
 
2017
2224
  VueRouter.prototype.forward = function forward () {
2018
- this.go(1)
2225
+ this.go(1);
2019
2226
  };
2020
2227
 
2021
2228
  VueRouter.prototype.getMatchedComponents = function getMatchedComponents (to) {
2022
2229
  var route = to
2023
- ? this.resolve(to).resolved
2024
- : this.currentRoute
2230
+ ? this.resolve(to).route
2231
+ : this.currentRoute;
2025
2232
  if (!route) {
2026
2233
  return []
2027
2234
  }
@@ -2037,31 +2244,42 @@ VueRouter.prototype.resolve = function resolve (
2037
2244
  current,
2038
2245
  append
2039
2246
  ) {
2040
- var normalizedTo = normalizeLocation(to, current || this.history.current, append)
2041
- var resolved = this.match(normalizedTo, current)
2042
- var fullPath = resolved.redirectedFrom || resolved.fullPath
2043
- var base = this.history.base
2044
- var href = createHref(base, fullPath, this.mode)
2247
+ var location = normalizeLocation(to, current || this.history.current, append);
2248
+ var route = this.match(location, current);
2249
+ var fullPath = route.redirectedFrom || route.fullPath;
2250
+ var base = this.history.base;
2251
+ var href = createHref(base, fullPath, this.mode);
2045
2252
  return {
2046
- normalizedTo: normalizedTo,
2047
- resolved: resolved,
2048
- href: href
2253
+ location: location,
2254
+ route: route,
2255
+ href: href,
2256
+ // for backwards compat
2257
+ normalizedTo: location,
2258
+ resolved: route
2259
+ }
2260
+ };
2261
+
2262
+ VueRouter.prototype.addRoutes = function addRoutes (routes) {
2263
+ this.matcher.addRoutes(routes);
2264
+ if (this.history.current !== START) {
2265
+ this.history.transitionTo(this.history.getCurrentLocation());
2049
2266
  }
2050
2267
  };
2051
2268
 
2052
2269
  Object.defineProperties( VueRouter.prototype, prototypeAccessors );
2053
2270
 
2054
2271
  function createHref (base, fullPath, mode) {
2055
- var path = mode === 'hash' ? '#' + fullPath : fullPath
2272
+ var path = mode === 'hash' ? '#' + fullPath : fullPath;
2056
2273
  return base ? cleanPath(base + '/' + path) : path
2057
2274
  }
2058
2275
 
2059
- VueRouter.install = install
2276
+ VueRouter.install = install;
2277
+ VueRouter.version = '2.2.0';
2060
2278
 
2061
2279
  if (inBrowser && window.Vue) {
2062
- window.Vue.use(VueRouter)
2280
+ window.Vue.use(VueRouter);
2063
2281
  }
2064
2282
 
2065
2283
  return VueRouter;
2066
2284
 
2067
- })));
2285
+ })));