PageSourceSearch

https://app.voxingpro.com/packages/kadira_flow-router.js?hash=9028c4c1cc6e56062bd5c1c3c2e96ab23301ecb7

js voxingpro.com collected 2026-10-02 14:39:13 UTC 81,813 bytes, 2,719 lines download raw bytes

1//////////////////////////////////////////////////////////////////////////
2//                                                                      //
3// This is a generated file. You can view the original                  //
4// source in your browser if your browser supports source maps.         //
5// Source maps are supported by all recent versions of Chrome, Safari,  //
6// and Firefox, and by Internet Explorer 11.                            //
7//                                                                      //
8//////////////////////////////////////////////////////////////////////////
9
10
11(function () {
12
13/* Imports */
14var Meteor = Package.meteor.Meteor;
15var global = Package.meteor.global;
16var meteorEnv = Package.meteor.meteorEnv;
17var _ = Package.underscore._;
18var Tracker = Package.tracker.Tracker;
19var Deps = Package.tracker.Deps;
20var ReactiveDict = Package['reactive-dict'].ReactiveDict;
21var ReactiveVar = Package['reactive-var'].ReactiveVar;
22var EJSON = Package.ejson.EJSON;
23var meteorInstall = Package.modules.meteorInstall;
24
25/* Package-scope variables */
26var page, qs, Triggers, Router, Group, Route, FlowRouter;
27
28var require = meteorInstall({"node_modules":{"meteor":{"kadira:flow-router":{"client":{
28"modules.js":function(require){
29
30////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31//                                                                                                                    //
32// packages/kadira_flow-router/client/modules.js                                                                      //
33//                                                                                                                    //
34////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35                                                                                                                      //
36page = require('page');
37qs   = require('qs');
38
39////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40
41},
41"triggers.js":function(){
42
43////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
44//                                                                                                                    //
45// packages/kadira_flow-router/client/triggers.js                                                                     //
46//                                                                                                                    //
47////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
48                                                                                                                      //
49// a set of utility functions for triggers
50
51Triggers = {};
52
53// Apply filters for a set of triggers
54// @triggers - a set of triggers
55// @filter - filter with array fileds with `only` and `except` 
56//           support only either `only` or `except`, but not both
57Triggers.applyFilters = function(triggers, filter) {
58  if(!(triggers instanceof Array)) {
59    triggers = [triggers];
60  }
61
62  if(!filter) {
63    return triggers;
64  }
65
66  if(filter.only && filter.except) {
67    throw new Error("Triggers don't support only and except filters at once");
68  }
69
70  if(filter.only && !(filter.only instanceof Array)) {
71    throw new Error("only filters needs to be an array");
72  }
73
74  if(filter.except && !(filter.except instanceof Array)) {
75    throw new Error("except filters needs to be an array");
76  }
77
78  if(filter.only) {
79    return Triggers.createRouteBoundTriggers(triggers, filter.only);
80  }
81
82  if(filter.except) {
83    return Triggers.createRouteBoundTriggers(triggers, filter.except, true);
84  }
85
86  throw new Error("Provided a filter but not supported");
87};
88
89//  create triggers by bounding them to a set of route names
90//  @triggers - a set of triggers 
91//  @names - list of route names to be bound (trigger runs only for these names)
92//  @negate - negate the result (triggers won't run for above names)
93Triggers.createRouteBoundTriggers = function(triggers, names, negate) {
94  var namesMap = {};
95  _.each(names, function(name) {
96    namesMap[name] = true;
97  });
98
99  var filteredTriggers = _.map(triggers, function(originalTrigger) {
100    var modifiedTrigger = function(context, next) {
101      var routeName = context.route.name;
102      var matched = (namesMap[routeName])? 1: -1;
103      matched = (negate)? matched * -1 : matched;
104
105      if(matched === 1) {
106        originalTrigger(context, next);
107      }
108    };
109    return modifiedTrigger;
110  });
111
112  return filteredTriggers;
113};
114
115//  run triggers and abort if redirected or callback stopped
116//  @triggers - a set of triggers 
117//  @context - context we need to pass (it must have the route)
118//  @redirectFn - function which used to redirect 
119//  @after - called after if only all the triggers runs
120Triggers.runTriggers = function(triggers, context, redirectFn, after) {
121  var abort = false;
122  var inCurrentLoop = true;
123  var alreadyRedirected = false;
124
125  for(var lc=0; lc<triggers.length; lc++) {
126    var trigger = triggers[lc];
127    trigger(context, doRedirect, doStop);
128
129    if(abort) {
130      return;
131    }
132  }
133
134  // mark that, we've exceeds the currentEventloop for
135  // this set of triggers.
136  inCurrentLoop = false;
137  after();
138
139  function doRedirect(url, params, queryParams) {
140    if(alreadyRedirected) {
141      throw new Error("already redirected");
142    }
143
144    if(!inCurrentLoop) {
145      throw new Error("redirect needs to be done in sync");
146    }
147
148    if(!url) {
149      throw new Error("trigger redirect requires an URL");
150    }
151
152    abort = true;
153    alreadyRedirected = true;
154    redirectFn(url, params, queryParams);
155  }
156
157  function doStop() {
158    abort = true;
159  }
160};
161////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
162
163},
163"router.js":function(){
164
165////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
166//                                                                                                                    //
167// packages/kadira_flow-router/client/router.js                                                                       //
168//                                                                                                                    //
169////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
170                                                                                                                      //
171Router = function () {
172  var self = this;
173  this.globals = [];
174  this.subscriptions = Function.prototype;
175
176  this._tracker = this._buildTracker();
177  this._current = {};
178
179  // tracks the current path change
180  this._onEveryPath = new Tracker.Dependency();
181
182  this._globalRoute = new Route(this);
183
184  // holds onRoute callbacks
185  this._onRouteCallbacks = [];
186
187  // if _askedToWait is true. We don't automatically start the router
188  // in Meteor.startup callback. (see client/_init.js)
189  // Instead user need to call `.initialize()
190  this._askedToWait = false;
191  this._initialized = false;
192  this._triggersEnter = [];
193  this._triggersExit = [];
194  this._routes = [];
195  this._routesMap = {};
196  this._updateCallbacks();
197  this.notFound = this.notfound = null;
198  // indicate it's okay (or not okay) to run the tracker
199  // when doing subscriptions
200  // using a number and increment it help us to support FlowRouter.go()
201  // and legitimate reruns inside tracker on the same event loop.
202  // this is a solution for #145
203  this.safeToRun = 0;
204
205  // Meteor exposes to the client the path prefix that was defined using the
206  // ROOT_URL environement variable on the server using the global runtime
207  // configuration. See #315.
208  this._basePath = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX || '';
209
210  // this is a chain contains a list of old routes
211  // most of the time, there is only one old route
212  // but when it's the time for a trigger redirect we've a chain
213  this._oldRouteChain = [];
214
215  this.env = {
216    replaceState: new Meteor.EnvironmentVariable(),
217    reload: new Meteor.EnvironmentVariable(),
218    trailingSlash: new Meteor.EnvironmentVariable()
219  };
220
221  // redirect function used inside triggers
222  this._redirectFn = function(pathDef, fields, queryParams) {
223    if (/^http(s)?:\/\//.test(pathDef)) {
224        var message = "Redirects to URLs outside of the app are not supported in this version of Flow Router. Use 'window.location = yourUrl' instead";
225        throw new Error(message);
226    }
227    self.withReplaceState(function() {
228      var path = FlowRouter.path(pathDef, fields, queryParams);
229      self._page.redirect(path);
230    });
231  };
232  this._initTriggersAPI();
233};
234
235Router.prototype.route = function(pathDef, options, group) {
236  if (!/^\/.*/.test(pathDef)) {
237    var message = "route's path must start with '/'";
238    throw new Error(message);
239  }
240
241  options = options || {};
242  var self = this;
243  var route = new Route(this, pathDef, options, group);
244
245  // calls when the page route being activates
246  route._actionHandle = function (context, next) {
247    var oldRoute = self._current.route;
248    self._oldRouteChain.push(oldRoute);
249
250    var queryParams = self._qs.parse(context.querystring);
251    // _qs.parse() gives us a object without prototypes,
252    // created with Object.create(null)
253    // Meteor's check doesn't play nice with it.
254    // So, we need to fix it by cloning it.
255    // see more: https://github.com/meteorhacks/flow-router/issues/164
256    queryParams = JSON.parse(JSON.stringify(queryParams));
257
258    self._current = {
259      path: context.path,
260      context: context,
261      params: context.params,
262      queryParams: queryParams,
263      route: route,
264      oldRoute: oldRoute
265    };
266
267    // we need to invalidate if all the triggers have been completed
268    // if not that means, we've been redirected to another path
269    // then we don't need to invalidate
270    var afterAllTriggersRan = function() {
271      self._invalidateTracker();
272    };
273
274    var triggers = self._triggersEnter.concat(route._triggersEnter);
275    Triggers.runTriggers(
276      triggers,
277      self._current,
278      self._redirectFn,
279      afterAllTriggersRan
280    );
281  };
282
283  // calls when you exit from the page js route
284  route._exitHandle = function(context, next) {
285    var triggers = self._triggersExit.concat(route._triggersExit);
286    Triggers.runTriggers(
287      triggers,
288      self._current,
289      self._redirectFn,
290      next
291    );
292  };
293
294  this._routes.push(route);
295  if (options.name) {
296    this._routesMap[options.name] = route;
297  }
298
299  this._updateCallbacks();
300  this._triggerRouteRegister(route);
301
302  return route;
303};
304
305Router.prototype.group = function(options) {
306  return new Group(this, options);
307};
308
309Router.prototype.path = function(pathDef, fields, queryParams) {
310  if (this._routesMap[pathDef]) {
311    pathDef = this._routesMap[pathDef].pathDef;
312  }
313
314  var path = "";
315
316  // Prefix the path with the router global prefix
317  if (this._basePath) {
318    path += "/" + this._basePath + "/";
319  }
320
321  fields = fields || {};
322  var regExp = /(:[\w\(\)\\\+\*\.\?]+)+/g;
323  path += pathDef.replace(regExp, function(key) {
324    var firstRegexpChar = key.indexOf("(");
325    // get the content behind : and (\\d+/)
326    key = key.substring(1, (firstRegexpChar > 0)? firstRegexpChar: undefined);
327    // remove +?*
328    key = key.replace(/[\+\*\?]+/g, "");
329
330    // this is to allow page js to keep the custom characters as it is
331    // we need to encode 2 times otherwise "/" char does not work properly
332    // So, in that case, when I includes "/" it will think it's a part of the
333    // route. encoding 2times fixes it
334    return encodeURIComponent(encodeURIComponent(fields[key] || ""));
335  });
336
337  // Replace multiple slashes with single slash
338  path = path.replace(/\/\/+/g, "/");
339
340  // remove trailing slash
341  // but keep the root slash if it's the only one
342  path = path.match(/^\/{1}$/) ? path: path.replace(/\/$/, "");
343
344  // explictly asked to add a trailing slash
345  if(this.env.trailingSlash.get() && _.last(path) !== "/") {
346    path += "/";
347  }
348
349  var strQueryParams = this._qs.stringify(queryParams || {});
350  if(strQueryParams) {
351    path += "?" + strQueryParams;
352  }
353
354  return path;
355};
356
357Router.prototype.go = function(pathDef, fields, queryParams) {
358  var path = this.path(pathDef, fields, queryParams);
359
360  var useReplaceState = this.env.replaceState.get();
361  if(useReplaceState) {
362    this._page.replace(path);
363  } else {
364    this._page(path);
365  }
366};
367
368Router.prototype.reload = function() {
369  var self = this;
370
371  self.env.reload.withValue(true, function() {
372    self._page.replace(self._current.path);
373  });
374};
375
376Router.prototype.redirect = function(path) {
377  this._page.redirect(path);
378};
379
380Router.prototype.setParams = function(newParams) {
381  if(!this._current.route) {return false;}
382
383  var pathDef = this._current.route.pathDef;
384  var existingParams = this._current.params;
385  var params = {};
386  _.each(_.keys(existingParams), function(key) {
387    params[key] = existingParams[key];
388  });
389
390  params = _.extend(params, newParams);
391  var queryParams = this._current.queryParams;
392
393  this.go(pathDef, params, queryParams);
394  return true;
395};
396
397Router.prototype.setQueryParams = function(newParams) {
398  if(!this._current.route) {return false;}
399
400  var queryParams = _.clone(this._current.queryParams);
401  _.extend(queryParams, newParams);
402
403  for (var k in queryParams) {
404    if (queryParams[k] === null || queryParams[k] === undefined) {
405      delete queryParams[k];
406    }
407  }
408
409  var pathDef = this._current.route.pathDef;
410  var params = this._current.params;
411  this.go(pathDef, params, queryParams);
412  return true;
413};
414
415// .current is not reactive
416// This is by design. use .getParam() instead
417// If you really need to watch the path change, use .watchPathChange()
418Router.prototype.current = function() {
419  // We can't trust outside, that's why we clone this
420  // Anyway, we can't clone the whole object since it has non-jsonable values
421  // That's why we clone what's really needed.
422  var current = _.clone(this._current);
423  current.queryParams = EJSON.clone(current.queryParams);
424  current.params = EJSON.clone(current.params);
425  return current;
426};
427
428// Implementing Reactive APIs
429var reactiveApis = [
430  'getParam', 'getQueryParam',
431  'getRouteName', 'watchPathChange'
432];
433reactiveApis.forEach(function(api) {
434  Router.prototype[api] = function(arg1) {
435    // when this is calling, there may not be any route initiated
436    // so we need to handle it
437    var currentRoute = this._current.route;
438    if(!currentRoute) {
439      this._onEveryPath.depend();
440      return;
441    }
442
443    // currently, there is only one argument. If we've more let's add more args
444    // this is not clean code, but better in performance
445    return currentRoute[api].call(currentRoute, arg1);
446  };
447});
448
449Router.prototype.subsReady = function() {
450  var callback = null;
451  var args = _.toArray(arguments);
452
453  if (typeof _.last(args) === "function") {
454    callback = args.pop();
455  }
456
457  var currentRoute = this.current().route;
458  var globalRoute = this._globalRoute;
459
460  // we need to depend for every route change and
461  // rerun subscriptions to check the ready state
462  this._onEveryPath.depend();
463
464  if(!currentRoute) {
465    return false;
466  }
467
468  var subscriptions;
469  if(args.length === 0) {
470    subscriptions = _.values(globalRoute.getAllSubscriptions());
471    subscriptions = subscriptions.concat(_.values(currentRoute.getAllSubscriptions()));
472  } else {
473    subscriptions = _.map(args, function(subName) {
474      return globalRoute.getSubscription(subName) || currentRoute.getSubscription(subName);
475    });
476  }
477
478  var isReady = function() {
479    var ready =  _.every(subscriptions, function(sub) {
480      return sub && sub.ready();
481    });
482
483    return ready;
484  };
485
486  if (callback) {
487    Tracker.autorun(function(c) {
488      if (isReady()) {
489        callback();
490        c.stop();
491      }
492    });
493  } else {
494    return isReady();
495  }
496};
497
498Router.prototype.withReplaceState = function(fn) {
499  return this.env.replaceState.withValue(true, fn);
500};
501
502Router.prototype.withTrailingSlash = function(fn) {
503  return this.env.trailingSlash.withValue(true, fn);
504};
505
506Router.prototype._notfoundRoute = function(context) {
507  this._current = {
508    path: context.path,
509    context: context,
510    params: [],
511    queryParams: {},
512  };
513
514  // XXX this.notfound kept for backwards compatibility
515  this.notFound = this.notFound || this.notfound;
516  if(!this.notFound) {
517    console.error("There is no route for the path:", context.path);
518    return;
519  }
520
521  this._current.route = new Route(this, "*", this.notFound);
522  this._invalidateTracker();
523};
524
525Router.prototype.initialize = function(options) {
526  options = options || {};
527
528  if(this._initialized) {
529    throw new Error("FlowRouter is already initialized");
530  }
531
532  var self = this;
533  this._updateCallbacks();
534
535  // Implementing idempotent routing
536  // by overriding page.js`s "show" method.
537  // Why?
538  // It is impossible to bypass exit triggers,
539  // because they execute before the handler and
540  // can not know what the next path is, inside exit trigger.
541  //
542  // we need override both show, replace to make this work
543  // since we use redirect when we are talking about withReplaceState
544  _.each(['show', 'replace'], function(fnName) {
545    var original = self._page[fnName];
546    self._page[fnName] = function(path, state, dispatch, push) {
547      var reload = self.env.reload.get();
548      if (!reload && self._current.path === path) {
549        return;
550      }
551
552      original.call(this, path, state, dispatch, push);
553    };
554  });
555
556  // this is very ugly part of pagejs and it does decoding few times
557  // in unpredicatable manner. See #168
558  // this is the default behaviour and we need keep it like that
559  // we are doing a hack. see .path()
560  this._page.base(this._basePath);
561  this._page({
562    decodeURLComponents: true,
563    hashbang: !!options.hashbang
564  });
565
566  this._initialized = true;
567};
568
569Router.prototype._buildTracker = function() {
570  var self = this;
571
572  // main autorun function
573  var tracker = Tracker.autorun(function () {
574    if(!self._current || !self._current.route) {
575      return;
576    }
577
578    // see the definition of `this._processingContexts`
579    var currentContext = self._current;
580    var route = currentContext.route;
581    var path = currentContext.path;
582
583    if(self.safeToRun === 0) {
584      var message =
585        "You can't use reactive data sources like Session" +
586        " inside the `.subscriptions` method!";
587      throw new Error(message);
588    }
589
590    // We need to run subscriptions inside a Tracker
591    // to stop subs when switching between routes
592    // But we don't need to run this tracker with
593    // other reactive changes inside the .subscription method
594    // We tackle this with the `safeToRun` variable
595    self._globalRoute.clearSubscriptions();
596    self.subscriptions.call(self._globalRoute, path);
597    route.callSubscriptions(currentContext);
598
599    // otherwise, computations inside action will trigger to re-run
600    // this computation. which we do not need.
601    Tracker.nonreactive(function() {
602      var isRouteChange = currentContext.oldRoute !== currentContext.route;
603      var isFirstRoute = !currentContext.oldRoute;
604      // first route is not a route change
605      if(isFirstRoute) {
606        isRouteChange = false;
607      }
608
609      // Clear oldRouteChain just before calling the action
610      // We still need to get a copy of the oldestRoute first
611      // It's very important to get the oldest route and registerRouteClose() it
612      // See: https://github.com/kadirahq/flow-router/issues/314
613      var oldestRoute = self._oldRouteChain[0];
614      self._oldRouteChain = [];
615
616      currentContext.route.registerRouteChange(currentContext, isRouteChange);
617      route.callAction(currentContext);
618
619      Tracker.afterFlush(function() {
620        self._onEveryPath.changed();
621        if(isRouteChange) {
622          // We need to trigger that route (definition itself) has changed.
623          // So, we need to re-run all the register callbacks to current route
624          // This is pretty important, otherwise tracker
625          // can't identify new route's items
626
627          // We also need to afterFlush, otherwise this will re-run
628          // helpers on templates which are marked for destroying
629          if(oldestRoute) {
630            oldestRoute.registerRouteClose();
631          }
632        }
633      });
634    });
635
636    self.safeToRun--;
637  });
638
639  return tracker;
640};
641
642Router.prototype._invalidateTracker = function() {
643  var self = this;
644  this.safeToRun++;
645  this._tracker.invalidate();
646  // After the invalidation we need to flush to make changes imediately
647  // otherwise, we have face some issues context mix-maches and so on.
648  // But there are some cases we can't flush. So we need to ready for that.
649
650  // we clearly know, we can't flush inside an autorun
651  // this may leads some issues on flow-routing
652  // we may need to do some warning
653  if(!Tracker.currentComputation) {
654    // Still there are some cases where we can't flush
655    //  eg:- when there is a flush currently
656    // But we've no public API or hacks to get that state
657    // So, this is the only solution
658    try {
659      Tracker.flush();
660    } catch(ex) {
661      // only handling "while flushing" errors
662      if(!/Tracker\.flush while flushing/.test(ex.message)) {
663        return;
664      }
665
666      // XXX: fix this with a proper solution by removing subscription mgt.
667      // from the router. Then we don't need to run invalidate using a tracker
668
669      // this happens when we are trying to invoke a route change
670      // with inside a route chnage. (eg:- Template.onCreated)
671      // Since we use page.js and tracker, we don't have much control
672      // over this process.
673      // only solution is to defer route execution.
674
675      // It's possible to have more than one path want to defer
676      // But, we only need to pick the last one.
677      // self._nextPath = self._current.path;
678      Meteor.defer(function() {
679        var path = self._nextPath;
680        if(!path) {
681          return;
682        }
683
684        delete self._nextPath;
685        self.env.reload.withValue(true, function() {
686          self.go(path);
687        });
688      });
689    }
690  }
691};
692
693Router.prototype._updateCallbacks = function () {
694  var self = this;
695
696  self._page.callbacks = [];
697  self._page.exits = [];
698
699  _.each(self._routes, function(route) {
700    self._page(route.pathDef, route._actionHandle);
701    self._page.exit(route.pathDef, route._exitHandle);
702  });
703
704  self._page("*", function(context) {
705    self._notfoundRoute(context);
706  });
707};
708
709Router.prototype._initTriggersAPI = function() {
710  var self = this;
711  this.triggers = {
712    enter: function(triggers, filter) {
713      triggers = Triggers.applyFilters(triggers, filter);
714      if(triggers.length) {
715        self._triggersEnter = self._triggersEnter.concat(triggers);
716      }
717    },
718
719    exit: function(triggers, filter) {
720      triggers = Triggers.applyFilters(triggers, filter);
721      if(triggers.length) {
722        self._triggersExit = self._triggersExit.concat(triggers);
723      }
724    }
725  };
726};
727
728Router.prototype.wait = function() {
729  if(this._initialized) {
730    throw new Error("can't wait after FlowRouter has been initialized");
731  }
732
733  this._askedToWait = true;
734};
735
736Router.prototype.onRouteRegister = function(cb) {
737  this._onRouteCallbacks.push(cb);
738};
739
740Router.prototype._triggerRouteRegister = function(currentRoute) {
741  // We should only need to send a safe set of fields on the route
742  // object.
743  // This is not to hide what's inside the route object, but to show
744  // these are the public APIs
745  var routePublicApi = _.pick(currentRoute, 'name', 'pathDef', 'path');
746  var omittingOptionFields = [
747    'triggersEnter', 'triggersExit', 'action', 'subscriptions', 'name'
748  ];
749  routePublicApi.options = _.omit(currentRoute.options, omittingOptionFields);
750
751  _.each(this._onRouteCallbacks, function(cb) {
752    cb(routePublicApi);
753  });
754};
755
756Router.prototype._page = page;
757Router.prototype._qs = qs;
758
759////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
760
761},
761"group.js":function(){
762
763////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
764//                                                                                                                    //
765// packages/kadira_flow-router/client/group.js                                                                        //
766//                                                                                                                    //
767////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
768                                                                                                                      //
769Group = function(router, options, parent) {
770  options = options || {};
771
772  if (options.prefix && !/^\/.*/.test(options.prefix)) {
773    var message = "group's prefix must start with '/'";
774    throw new Error(message);
775  }
776
777  this._router = router;
778  this.prefix = options.prefix || '';
779  this.name = options.name;
780  this.options = options;
781
782  this._triggersEnter = options.triggersEnter || [];
783  this._triggersExit = options.triggersExit || [];
784  this._subscriptions = options.subscriptions || Function.prototype;
785
786  this.parent = parent;
787  if (this.parent) {
788    this.prefix = parent.prefix + this.prefix;
789
790    this._triggersEnter = parent._triggersEnter.concat(this._triggersEnter);
791    this._triggersExit = this._triggersExit.concat(parent._triggersExit);
792  }
793};
794
795Group.prototype.route = function(pathDef, options, group) {
796  options = options || {};
797
798  if (!/^\/.*/.test(pathDef)) {
799    var message = "route's path must start with '/'";
800    throw new Error(message);
801  }
802
803  group = group || this;
804  pathDef = this.prefix + pathDef;
805
806  var triggersEnter = options.triggersEnter || [];
807  options.triggersEnter = this._triggersEnter.concat(triggersEnter);
808
809  var triggersExit = options.triggersExit || [];
810  options.triggersExit = triggersExit.concat(this._triggersExit);
811
812  return this._router.route(pathDef, options, group);
813};
814
815Group.prototype.group = function(options) {
816  return new Group(this._router, options, this);
817};
818
819Group.prototype.callSubscriptions = function(current) {
820  if (this.parent) {
821    this.parent.callSubscriptions(current);
822  }
823
824  this._subscriptions.call(current.route, current.params, current.queryParams);
825};
826
827////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
828
829},
829"route.js":function(){
830
831////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
832//                                                                                                                    //
833// packages/kadira_flow-router/client/route.js                                                                        //
834//                                                                                                                    //
835////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
836                                                                                                                      //
837Route = function(router, pathDef, options, group) {
838  options = options || {};
839
840  this.options = options;
841  this.pathDef = pathDef
842
843  // Route.path is deprecated and will be removed in 3.0
844  this.path = pathDef;
845
846  if (options.name) {
847    this.name = options.name;
848  }
849
850  this._action = options.action || Function.prototype;
851  this._subscriptions = options.subscriptions || Function.prototype;
852  this._triggersEnter = options.triggersEnter || [];
853  this._triggersExit = options.triggersExit || [];
854  this._subsMap = {};
855  this._router = router;
856
857  this._params = new ReactiveDict();
858  this._queryParams = new ReactiveDict();
859  this._routeCloseDep = new Tracker.Dependency();
860
861  // tracks the changes in the URL
862  this._pathChangeDep = new Tracker.Dependency();
863
864  this.group = group;
865};
866
867Route.prototype.clearSubscriptions = function() {
868  this._subsMap = {};
869};
870
871Route.prototype.register = function(name, sub, options) {
872  this._subsMap[name] = sub;
873};
874
875
876Route.prototype.getSubscription = function(name) {
877  return this._subsMap[name];
878};
879
880
881Route.prototype.getAllSubscriptions = function() {
882  return this._subsMap;
883};
884
885Route.prototype.callAction = function(current) {
886  var self = this;
887  self._action(current.params, current.queryParams);
888};
889
890Route.prototype.callSubscriptions = function(current) {
891  this.clearSubscriptions();
892  if (this.group) {
893    this.group.callSubscriptions(current);
894  }
895
896  this._subscriptions(current.params, current.queryParams);
897};
898
899Route.prototype.getRouteName = function() {
900  this._routeCloseDep.depend();
901  return this.name;
902};
903
904Route.prototype.getParam = function(key) {
905  this._routeCloseDep.depend();
906  return this._params.get(key);
907};
908
909Route.prototype.getQueryParam = function(key) {
910  this._routeCloseDep.depend();
911  return this._queryParams.get(key);
912};
913
914Route.prototype.watchPathChange = function() {
915  this._pathChangeDep.depend();
916};
917
918Route.prototype.registerRouteClose = function() {
919  this._params = new ReactiveDict();
920  this._queryParams = new ReactiveDict();
921  this._routeCloseDep.changed();
922  this._pathChangeDep.changed();
923};
924
925Route.prototype.registerRouteChange = function(currentContext, routeChanging) {
926  // register params
927  var params = currentContext.params;
928  this._updateReactiveDict(this._params, params);
929
930  // register query params
931  var queryParams = currentContext.queryParams;
932  this._updateReactiveDict(this._queryParams, queryParams);
933
934  // if the route is changing, we need to defer triggering path changing
935  // if we did this, old route's path watchers will detect this
936  // Real issue is, above watcher will get removed with the new route
937  // So, we don't need to trigger it now
938  // We are doing it on the route close event. So, if they exists they'll 
939  // get notify that
940  if(!routeChanging) {
941    this._pathChangeDep.changed();
942  }
943};
944
945Route.prototype._updateReactiveDict = function(dict, newValues) {
946  var currentKeys = _.keys(newValues);
947  var oldKeys = _.keys(dict.keyDeps);
948
949  // set new values
950  //  params is an array. So, _.each(params) does not works
951  //  to iterate params
952  _.each(currentKeys, function(key) {
953    dict.set(key, newValues[key]);
954  });
955
956  // remove keys which does not exisits here
957  var removedKeys = _.difference(oldKeys, currentKeys);
958  _.each(removedKeys, function(key) {
959    dict.set(key, undefined);
960  });
961};
962
963////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
964
965},
965"_init.js":function(){
966
967////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
968//                                                                                                                    //
969// packages/kadira_flow-router/client/_init.js                                                                        //
970//                                                                                                                    //
971////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
972                                                                                                                      //
973// Export Router Instance
974FlowRouter = new Router();
975FlowRouter.Router = Router;
976FlowRouter.Route = Route;
977
978// Initialize FlowRouter
979Meteor.startup(function () {
980  if(!FlowRouter._askedToWait) {
981    FlowRouter.initialize();
982  }
983});
984
985////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
986
987}},"lib":{
987"router.js":function(){
988
989////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
990//                                                                                                                    //
991// packages/kadira_flow-router/lib/router.js                                                                          //
992//                                                                                                                    //
993////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
994                                                                                                                      //
995Router.prototype.url = function() {
996  // We need to remove the leading base path, or "/", as it will be inserted
997  // automatically by `Meteor.absoluteUrl` as documented in:
998  // http://docs.meteor.com/#/full/meteor_absoluteurl
999  var completePath = this.path.apply(this, arguments);
1000  var basePath = this._basePath || '/';
1001  var pathWithoutBase = completePath.replace(new RegExp('^' + basePath), '');
1002  return Meteor.absoluteUrl(pathWithoutBase);
1003};
1004
1005////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1006
1007}},"node_modules":{"page":{
1007"package.json":function(require,exports){
1008
1009////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1010//                                                                                                                    //
1011// node_modules/meteor/kadira_flow-router/node_modules/page/package.json                                              //
1012//                                                                                                                    //
1013////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1014                                                                                                                      //
1015exports.name = "page";
1016exports.version = "1.6.4";
1017
1018////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1019
1020},
1020"index.js":function(require,exports,module){
1021
1022////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1023//                                                                                                                    //
1024// node_modules/meteor/kadira_flow-router/node_modules/page/index.js                                                  //
1025//                                                                                                                    //
1026////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1027                                                                                                                      //
1028  /* globals require, module */
1029
1030  'use strict';
1031
1032  /**
1033   * Module dependencies.
1034   */
1035
1036  var pathtoRegexp = require('path-to-regexp');
1037
1038  /**
1039   * Module exports.
1040   */
1041
1042  module.exports = page;
1043
1044  /**
1045   * Detect click event
1046   */
1047  var clickEvent = ('undefined' !== typeof document) && document.ontouchstart ? 'touchstart' : 'click';
1048
1049  /**
1050   * To work properly with the URL
1051   * history.location generated polyfill in https://github.com/devote/HTML5-History-API
1052   */
1053
1054  var location = ('undefined' !== typeof window) && (window.history.location || window.location);
1055
1056  /**
1057   * Perform initial dispatch.
1058   */
1059
1060  var dispatch = true;
1061
1062
1063  /**
1064   * Decode URL components (query string, pathname, hash).
1065   * Accommodates both regular percent encoding and x-www-form-urlencoded format.
1066   */
1067  var decodeURLComponents = true;
1068
1069  /**
1070   * Base path.
1071   */
1072
1073  var base = '';
1074
1075  /**
1076   * Running flag.
1077   */
1078
1079  var running;
1080
1081  /**
1082   * HashBang option
1083   */
1084
1085  var hashbang = false;
1086
1087  /**
1088   * Previous context, for capturing
1089   * page exit events.
1090   */
1091
1092  var prevContext;
1093
1094  /**
1095   * Register `path` with callback `fn()`,
1096   * or route `path`, or redirection,
1097   * or `page.start()`.
1098   *
1099   *   page(fn);
1100   *   page('*', fn);
1101   *   page('/user/:id', load, user);
1102   *   page('/user/' + user.id, { some: 'thing' });
1103   *   page('/user/' + user.id);
1104   *   page('/from', '/to')
1105   *   page();
1106   *
1107   * @param {string|!Function|!Object} path
1108   * @param {Function=} fn
1109   * @api public
1110   */
1111
1112  function page(path, fn) {
1113    // <callback>
1114    if ('function' === typeof path) {
1115      return page('*', path);
1116    }
1117
1118    // route <path> to <callback ...>
1119    if ('function' === typeof fn) {
1120      var route = new Route(/** @type {string} */ (path));
1121      for (var i = 1; i < arguments.length; ++i) {
1122        page.callbacks.push(route.middleware(arguments[i]));
1123      }
1124      // show <path> with [state]
1125    } else if ('string' === typeof path) {
1126      page['string' === typeof fn ? 'redirect' : 'show'](path, fn);
1127      // start [options]
1128    } else {
1129      page.start(path);
1130    }
1131  }
1132
1133  /**
1134   * Callback functions.
1135   */
1136
1137  page.callbacks = [];
1138  page.exits = [];
1139
1140  /**
1141   * Current path being processed
1142   * @type {string}
1143   */
1144  page.current = '';
1145
1146  /**
1147   * Number of pages navigated to.
1148   * @type {number}
1149   *
1150   *     page.len == 0;
1151   *     page('/login');
1152   *     page.len == 1;
1153   */
1154
1155  page.len = 0;
1156
1157  /**
1158   * Get or set basepath to `path`.
1159   *
1160   * @param {string} path
1161   * @api public
1162   */
1163
1164  page.base = function(path) {
1165    if (0 === arguments.length) return base;
1166    base = path;
1167  };
1168
1169  /**
1170   * Bind with the given `options`.
1171   *
1172   * Options:
1173   *
1174   *    - `click` bind to click events [true]
1175   *    - `popstate` bind to popstate [true]
1176   *    - `dispatch` perform initial dispatch [true]
1177   *
1178   * @param {Object} options
1179   * @api public
1180   */
1181
1182  page.start = function(options) {
1183    options = options || {};
1184    if (running) return;
1185    running = true;
1186    if (false === options.dispatch) dispatch = false;
1187    if (false === options.decodeURLComponents) decodeURLComponents = false;
1188    if (false !== options.popstate) window.addEventListener('popstate', onpopstate, false);
1189    if (false !== options.click) {
1190      document.addEventListener(clickEvent, onclick, false);
1191    }
1192    if (true === options.hashbang) hashbang = true;
1193    if (!dispatch) return;
1194    var url = (hashbang && ~location.hash.indexOf('#!')) ? location.hash.substr(2) + location.search : location.pathname + location.search + location.hash;
1195    page.replace(url, null, true, dispatch);
1196  };
1197
1198  /**
1199   * Unbind click and popstate event handlers.
1200   *
1201   * @api public
1202   */
1203
1204  page.stop = function() {
1205    if (!running) return;
1206    page.current = '';
1207    page.len = 0;
1208    running = false;
1209    document.removeEventListener(clickEvent, onclick, false);
1210    window.removeEventListener('popstate', onpopstate, false);
1211  };
1212
1213  /**
1214   * Show `path` with optional `state` object.
1215   *
1216   * @param {string} path
1217   * @param {Object=} state
1218   * @param {boolean=} dispatch
1219   * @param {boolean=} push
1220   * @return {!Context}
1221   * @api public
1222   */
1223
1224  page.show = function(path, state, dispatch, push) {
1225    var ctx = new Context(path, state);
1226    page.current = ctx.path;
1227    if (false !== dispatch) page.dispatch(ctx);
1228    if (false !== ctx.handled && false !== push) ctx.pushState();
1229    return ctx;
1230  };
1231
1232  /**
1233   * Goes back in the history
1234   * Back should always let the current route push state and then go back.
1235   *
1236   * @param {string} path - fallback path to go back if no more history exists, if undefined defaults to page.base
1237   * @param {Object=} state
1238   * @api public
1239   */
1240
1241  page.back = function(path, state) {
1242    if (page.len > 0) {
1243      // this may need more testing to see if all browsers
1244      // wait for the next tick to go back in history
1245      history.back();
1246      page.len--;
1247    } else if (path) {
1248      setTimeout(function() {
1249        page.show(path, state);
1250      });
1251    }else{
1252      setTimeout(function() {
1253        page.show(base, state);
1254      });
1255    }
1256  };
1257
1258
1259  /**
1260   * Register route to redirect from one path to other
1261   * or just redirect to another route
1262   *
1263   * @param {string} from - if param 'to' is undefined redirects to 'from'
1264   * @param {string=} to
1265   * @api public
1266   */
1267  page.redirect = function(from, to) {
1268    // Define route from a path to another
1269    if ('string' === typeof from && 'string' === typeof to) {
1270      page(from, function(e) {
1271        setTimeout(function() {
1272          page.replace(/** @type {!string} */ (to));
1273        }, 0);
1274      });
1275    }
1276
1277    // Wait for the push state and replace it with another
1278    if ('string' === typeof from && 'undefined' === typeof to) {
1279      setTimeout(function() {
1280        page.replace(from);
1281      }, 0);
1282    }
1283  };
1284
1285  /**
1286   * Replace `path` with optional `state` object.
1287   *
1288   * @param {string} path
1289   * @param {Object=} state
1290   * @param {boolean=} init
1291   * @param {boolean=} dispatch
1292   * @return {!Context}
1293   * @api public
1294   */
1295
1296
1297  page.replace = function(path, state, init, dispatch) {
1298    var ctx = new Context(path, state);
1299    page.current = ctx.path;
1300    ctx.init = init;
1301    ctx.save(); // save before dispatching, which may redirect
1302    if (false !== dispatch) page.dispatch(ctx);
1303    return ctx;
1304  };
1305
1306  /**
1307   * Dispatch the given `ctx`.
1308   *
1309   * @param {Context} ctx
1310   * @api private
1311   */
1312  page.dispatch = function(ctx) {
1313    var prev = prevContext,
1314      i = 0,
1315      j = 0;
1316
1317    prevContext = ctx;
1318
1319    function nextExit() {
1320      var fn = page.exits[j++];
1321      if (!fn) return nextEnter();
1322      fn(prev, nextExit);
1323    }
1324
1325    function nextEnter() {
1326      var fn = page.callbacks[i++];
1327
1328      if (ctx.path !== page.current) {
1329        ctx.handled = false;
1330        return;
1331      }
1332      if (!fn) return unhandled(ctx);
1333      fn(ctx, nextEnter);
1334    }
1335
1336    if (prev) {
1337      nextExit();
1338    } else {
1339      nextEnter();
1340    }
1341  };
1342
1343  /**
1344   * Unhandled `ctx`. When it's not the initial
1345   * popstate then redirect. If you wish to handle
1346   * 404s on your own use `page('*', callback)`.
1347   *
1348   * @param {Context} ctx
1349   * @api private
1350   */
1351  function unhandled(ctx) {
1352    if (ctx.handled) return;
1353    var current;
1354
1355    if (hashbang) {
1356      current = base + location.hash.replace('#!', '');
1357    } else {
1358      current = location.pathname + location.search;
1359    }
1360
1361    if (current === ctx.canonicalPath) return;
1362    page.stop();
1363    ctx.handled = false;
1364    location.href = ctx.canonicalPath;
1365  }
1366
1367  /**
1368   * Register an exit route on `path` with
1369   * callback `fn()`, which will be called
1370   * on the previous context when a new
1371   * page is visited.
1372   */
1373  page.exit = function(path, fn) {
1374    if (typeof path === 'function') {
1375      return page.exit('*', path);
1376    }
1377
1378    var route = new Route(path);
1379    for (var i = 1; i < arguments.length; ++i) {
1380      page.exits.push(route.middleware(arguments[i]));
1381    }
1382  };
1383
1384  /**
1385   * Remove URL encoding from the given `str`.
1386   * Accommodates whitespace in both x-www-form-urlencoded
1387   * and regular percent-encoded form.
1388   *
1389   * @param {string} val - URL component to decode
1390   */
1391  function decodeURLEncodedURIComponent(val) {
1392    if (typeof val !== 'string') { return val; }
1393    return decodeURLComponents ? decodeURIComponent(val.replace(/\+/g, ' ')) : val;
1394  }
1395
1396  /**
1397   * Initialize a new "request" `Context`
1398   * with the given `path` and optional initial `state`.
1399   *
1400   * @constructor
1401   * @param {string} path
1402   * @param {Object=} state
1403   * @api public
1404   */
1405
1406  function Context(path, state) {
1407    if ('/' === path[0] && 0 !== path.indexOf(base)) path = base + (hashbang ? '#!' : '') + path;
1408    var i = path.indexOf('?');
1409
1410    this.canonicalPath = path;
1411    this.path = path.replace(base, '') || '/';
1412    if (hashbang) this.path = this.path.replace('#!', '') || '/';
1413
1414    this.title = document.title;
1415    this.state = state || {};
1416    this.state.path = path;
1417    this.querystring = ~i ? decodeURLEncodedURIComponent(path.slice(i + 1)) : '';
1418    this.pathname = decodeURLEncodedURIComponent(~i ? path.slice(0, i) : path);
1419    this.params = {};
1420
1421    // fragment
1422    this.hash = '';
1423    if (!hashbang) {
1424      if (!~this.path.indexOf('#')) return;
1425      var parts = this.path.split('#');
1426      this.path = parts[0];
1427      this.hash = decodeURLEncodedURIComponent(parts[1]) || '';
1428      this.querystring = this.querystring.split('#')[0];
1429    }
1430  }
1431
1432  /**
1433   * Expose `Context`.
1434   */
1435
1436  page.Context = Context;
1437
1438  /**
1439   * Push state.
1440   *
1441   * @api private
1442   */
1443
1444  Context.prototype.pushState = function() {
1445    page.len++;
1446    history.pushState(this.state, this.title, hashbang && this.path !== '/' ? '#!' + this.path : this.canonicalPath);
1447  };
1448
1449  /**
1450   * Save the context state.
1451   *
1452   * @api public
1453   */
1454
1455  Context.prototype.save = function() {
1456    history.replaceState(this.state, this.title, hashbang && this.path !== '/' ? '#!' + this.path : this.canonicalPath);
1457  };
1458
1459  /**
1460   * Initialize `Route` with the given HTTP `path`,
1461   * and an array of `callbacks` and `options`.
1462   *
1463   * Options:
1464   *
1465   *   - `sensitive`    enable case-sensitive routes
1466   *   - `strict`       enable strict matching for trailing slashes
1467   *
1468   * @constructor
1469   * @param {string} path
1470   * @param {Object=} options
1471   * @api private
1472   */
1473
1474  function Route(path, options) {
1475    options = options || {};
1476    this.path = (path === '*') ? '(.*)' : path;
1477    this.method = 'GET';
1478    this.regexp = pathtoRegexp(this.path,
1479      this.keys = [],
1480      options);
1481  }
1482
1483  /**
1484   * Expose `Route`.
1485   */
1486
1487  page.Route = Route;
1488
1489  /**
1490   * Return route middleware with
1491   * the given callback `fn()`.
1492   *
1493   * @param {Function} fn
1494   * @return {Function}
1495   * @api public
1496   */
1497
1498  Route.prototype.middleware = function(fn) {
1499    var self = this;
1500    return function(ctx, next) {
1501      if (self.match(ctx.path, ctx.params)) return fn(ctx, next);
1502      next();
1503    };
1504  };
1505
1506  /**
1507   * Check if this route matches `path`, if so
1508   * populate `params`.
1509   *
1510   * @param {string} path
1511   * @param {Object} params
1512   * @return {boolean}
1513   * @api private
1514   */
1515
1516  Route.prototype.match = function(path, params) {
1517    var keys = this.keys,
1518      qsIndex = path.indexOf('?'),
1519      pathname = ~qsIndex ? path.slice(0, qsIndex) : path,
1520      m = this.regexp.exec(decodeURIComponent(pathname));
1521
1522    if (!m) return false;
1523
1524    for (var i = 1, len = m.length; i < len; ++i) {
1525      var key = keys[i - 1];
1526      var val = decodeURLEncodedURIComponent(m[i]);
1527      if (val !== undefined || !(hasOwnProperty.call(params, key.name))) {
1528        params[key.name] = val;
1529      }
1530    }
1531
1532    return true;
1533  };
1534
1535
1536  /**
1537   * Handle "populate" events.
1538   */
1539
1540  var onpopstate = (function () {
1541    var loaded = false;
1542    if ('undefined' === typeof window) {
1543      return;
1544    }
1545    if (document.readyState === 'complete') {
1546      loaded = true;
1547    } else {
1548      window.addEventListener('load', function() {
1549        setTimeout(function() {
1550          loaded = true;
1551        }, 0);
1552      });
1553    }
1554    return function onpopstate(e) {
1555      if (!loaded) return;
1556      if (e.state) {
1557        var path = e.state.path;
1558        page.replace(path, e.state);
1559      } else {
1560        page.show(location.pathname + location.hash, undefined, undefined, false);
1561      }
1562    };
1563  })();
1564  /**
1565   * Handle "click" events.
1566   */
1567
1568  function onclick(e) {
1569
1570    if (1 !== which(e)) return;
1571
1572    if (e.metaKey || e.ctrlKey || e.shiftKey) return;
1573    if (e.defaultPrevented) return;
1574
1575
1576
1577    // ensure link
1578    var el = e.target;
1579    while (el && 'A' !== el.nodeName) el = el.parentNode;
1580    if (!el || 'A' !== el.nodeName) return;
1581
1582
1583
1584    // Ignore if tag has
1585    // 1. "download" attribute
1586    // 2. rel="external" attribute
1587    if (el.hasAttribute('download') || el.getAttribute('rel') === 'external') return;
1588
1589    // ensure non-hash for the same path
1590    var link = el.getAttribute('href');
1591    if (!hashbang && el.pathname === location.pathname && (el.hash || '#' === link)) return;
1592
1593
1594
1595    // Check for mailto: in the href
1596    if (link && link.indexOf('mailto:') > -1) return;
1597
1598    // check target
1599    if (el.target) return;
1600
1601    // x-origin
1602    if (!sameOrigin(el.href)) return;
1603
1604
1605
1606    // rebuild path
1607    var path = el.pathname + el.search + (el.hash || '');
1608
1609    path = path[0] !== '/' ? '/' + path : path;
1610
1611    // strip leading "/[drive letter]:" on NW.js on Windows
1612    if (typeof process !== 'undefined' && path.match(/^\/[a-zA-Z]:\//)) {
1613      path = path.replace(/^\/[a-zA-Z]:\//, '/');
1614    }
1615
1616    // same page
1617    var orig = path;
1618
1619    if (path.indexOf(base) === 0) {
1620      path = path.substr(base.length);
1621    }
1622
1623    if (hashbang) path = path.replace('#!', '');
1624
1625    if (base && orig === path) return;
1626
1627    e.preventDefault();
1628    page.show(orig);
1629  }
1630
1631  /**
1632   * Event button.
1633   */
1634
1635  function which(e) {
1636    e = e || window.event;
1637    return null === e.which ? e.button : e.which;
1638  }
1639
1640  /**
1641   * Check if `href` is the same origin.
1642   */
1643
1644  function sameOrigin(href) {
1645    var origin = location.protocol + '//' + location.hostname;
1646    if (location.port) origin += ':' + location.port;
1647    return (href && (0 === href.indexOf(origin)));
1648  }
1649
1650  page.sameOrigin = sameOrigin;
1651
1652////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1653
1654},"node_modules":{"path-to-regexp":{
1654"package.json":function(require,exports){
1655
1656////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1657//                                                                                                                    //
1658// node_modules/meteor/kadira_flow-router/node_modules/page/node_modules/path-to-regexp/package.json                  //
1659//                                                                                                                    //
1660////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1661                                                                                                                      //
1662exports.name = "path-to-regexp";
1663exports.version = "1.2.1";
1664
1665////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1666
1667},
1667"index.js":function(require,exports,module){
1668
1669////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1670//                                                                                                                    //
1671// node_modules/meteor/kadira_flow-router/node_modules/page/node_modules/path-to-regexp/index.js                      //
1672//                                                                                                                    //
1673////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1674                                                                                                                      //
1675var isarray = require('isarray')
1676
1677/**
1678 * Expose `pathToRegexp`.
1679 */
1680module.exports = pathToRegexp
1681module.exports.parse = parse
1682module.exports.compile = compile
1683module.exports.tokensToFunction = tokensToFunction
1684module.exports.tokensToRegExp = tokensToRegExp
1685
1686/**
1687 * The main path matching regexp utility.
1688 *
1689 * @type {RegExp}
1690 */
1691var PATH_REGEXP = new RegExp([
1692  // Match escaped characters that would otherwise appear in future matches.
1693  // This allows the user to escape special characters that won't transform.
1694  '(\\\\.)',
1695  // Match Express-style parameters and un-named parameters with a prefix
1696  // and optional suffixes. Matches appear as:
1697  //
1698  // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
1699  // "/route(\\d+)"  => [undefined, undefined, undefined, "\d+", undefined, undefined]
1700  // "/*"            => ["/", undefined, undefined, undefined, undefined, "*"]
1701  '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^()])+)\\))?|\\(((?:\\\\.|[^()])+)\\))([+*?])?|(\\*))'
1702].join('|'), 'g')
1703
1704/**
1705 * Parse a string for the raw tokens.
1706 *
1707 * @param  {String} str
1708 * @return {Array}
1709 */
1710function parse (str) {
1711  var tokens = []
1712  var key = 0
1713  var index = 0
1714  var path = ''
1715  var res
1716
1717  while ((res = PATH_REGEXP.exec(str)) != null) {
1718    var m = res[0]
1719    var escaped = res[1]
1720    var offset = res.index
1721    path += str.slice(index, offset)
1722    index = offset + m.length
1723
1724    // Ignore already escaped sequences.
1725    if (escaped) {
1726      path += escaped[1]
1727      continue
1728    }
1729
1730    // Push the current path onto the tokens.
1731    if (path) {
1732      tokens.push(path)
1733      path = ''
1734    }
1735
1736    var prefix = res[2]
1737    var name = res[3]
1738    var capture = res[4]
1739    var group = res[5]
1740    var suffix = res[6]
1741    var asterisk = res[7]
1742
1743    var repeat = suffix === '+' || suffix === '*'
1744    var optional = suffix === '?' || suffix === '*'
1745    var delimiter = prefix || '/'
1746    var pattern = capture || group || (asterisk ? '.*' : '[^' + delimiter + ']+?')
1747
1748    tokens.push({
1749      name: name || key++,
1750      prefix: prefix || '',
1751      delimiter: delimiter,
1752      optional: optional,
1753      repeat: repeat,
1754      pattern: escapeGroup(pattern)
1755    })
1756  }
1757
1758  // Match any characters still remaining.
1759  if (index < str.length) {
1760    path += str.substr(index)
1761  }
1762
1763  // If the path exists, push it onto the end.
1764  if (path) {
1765    tokens.push(path)
1766  }
1767
1768  return tokens
1769}
1770
1771/**
1772 * Compile a string to a template function for the path.
1773 *
1774 * @param  {String}   str
1775 * @return {Function}
1776 */
1777function compile (str) {
1778  return tokensToFunction(parse(str))
1779}
1780
1781/**
1782 * Expose a method for transforming tokens into the path function.
1783 */
1784function tokensToFunction (tokens) {
1785  // Compile all the tokens into regexps.
1786  var matches = new Array(tokens.length)
1787
1788  // Compile all the patterns before compilation.
1789  for (var i = 0; i < tokens.length; i++) {
1790    if (typeof tokens[i] === 'object') {
1791      matches[i] = new RegExp('^' + tokens[i].pattern + '$')
1792    }
1793  }
1794
1795  return function (obj) {
1796    var path = ''
1797    var data = obj || {}
1798
1799    for (var i = 0; i < tokens.length; i++) {
1800      var token = tokens[i]
1801
1802      if (typeof token === 'string') {
1803        path += token
1804
1805        continue
1806      }
1807
1808      var value = data[token.name]
1809      var segment
1810
1811      if (value == null) {
1812        if (token.optional) {
1813          continue
1814        } else {
1815          throw new TypeError('Expected "' + token.name + '" to be defined')
1816        }
1817      }
1818
1819      if (isarray(value)) {
1820        if (!token.repeat) {
1821          throw new TypeError('Expected "' + token.name + '" to not repeat, but received "' + value + '"')
1822        }
1823
1824        if (value.length === 0) {
1825          if (token.optional) {
1826            continue
1827          } else {
1828            throw new TypeError('Expected "' + token.name + '" to not be empty')
1829          }
1830        }
1831
1832        for (var j = 0; j < value.length; j++) {
1833          segment = encodeURIComponent(value[j])
1834
1835          if (!matches[i].test(segment)) {
1836            throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
1837          }
1838
1839          path += (j === 0 ? token.prefix : token.delimiter) + segment
1840        }
1841
1842        continue
1843      }
1844
1845      segment = encodeURIComponent(value)
1846
1847      if (!matches[i].test(segment)) {
1848        throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
1849      }
1850
1851      path += token.prefix + segment
1852    }
1853
1854    return path
1855  }
1856}
1857
1858/**
1859 * Escape a regular expression string.
1860 *
1861 * @param  {String} str
1862 * @return {String}
1863 */
1864function escapeString (str) {
1865  return str.replace(/([.+*?=^!:${}()[\]|\/])/g, '\\$1')
1866}
1867
1868/**
1869 * Escape the capturing group by escaping special characters and meaning.
1870 *
1871 * @param  {String} group
1872 * @return {String}
1873 */
1874function escapeGroup (group) {
1875  return group.replace(/([=!:$\/()])/g, '\\$1')
1876}
1877
1878/**
1879 * Attach the keys as a property of the regexp.
1880 *
1881 * @param  {RegExp} re
1882 * @param  {Array}  keys
1883 * @return {RegExp}
1884 */
1885function attachKeys (re, keys) {
1886  re.keys = keys
1887  return re
1888}
1889
1890/**
1891 * Get the flags for a regexp from the options.
1892 *
1893 * @param  {Object} options
1894 * @return {String}
1895 */
1896function flags (options) {
1897  return options.sensitive ? '' : 'i'
1898}
1899
1900/**
1901 * Pull out keys from a regexp.
1902 *
1903 * @param  {RegExp} path
1904 * @param  {Array}  keys
1905 * @return {RegExp}
1906 */
1907function regexpToRegexp (path, keys) {
1908  // Use a negative lookahead to match only capturing groups.
1909  var groups = path.source.match(/\((?!\?)/g)
1910
1911  if (groups) {
1912    for (var i = 0; i < groups.length; i++) {
1913      keys.push({
1914        name: i,
1915        prefix: null,
1916        delimiter: null,
1917        optional: false,
1918        repeat: false,
1919        pattern: null
1920      })
1921    }
1922  }
1923
1924  return attachKeys(path, keys)
1925}
1926
1927/**
1928 * Transform an array into a regexp.
1929 *
1930 * @param  {Array}  path
1931 * @param  {Array}  keys
1932 * @param  {Object} options
1933 * @return {RegExp}
1934 */
1935function arrayToRegexp (path, keys, options) {
1936  var parts = []
1937
1938  for (var i = 0; i < path.length; i++) {
1939    parts.push(pathToRegexp(path[i], keys, options).source)
1940  }
1941
1942  var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
1943
1944  return attachKeys(regexp, keys)
1945}
1946
1947/**
1948 * Create a path regexp from string input.
1949 *
1950 * @param  {String} path
1951 * @param  {Array}  keys
1952 * @param  {Object} options
1953 * @return {RegExp}
1954 */
1955function stringToRegexp (path, keys, options) {
1956  var tokens = parse(path)
1957  var re = tokensToRegExp(tokens, options)
1958
1959  // Attach keys back to the regexp.
1960  for (var i = 0; i < tokens.length; i++) {
1961    if (typeof tokens[i] !== 'string') {
1962      keys.push(tokens[i])
1963    }
1964  }
1965
1966  return attachKeys(re, keys)
1967}
1968
1969/**
1970 * Expose a function for taking tokens and returning a RegExp.
1971 *
1972 * @param  {Array}  tokens
1973 * @param  {Array}  keys
1974 * @param  {Object} options
1975 * @return {RegExp}
1976 */
1977function tokensToRegExp (tokens, options) {
1978  options = options || {}
1979
1980  var strict = options.strict
1981  var end = options.end !== false
1982  var route = ''
1983  var lastToken = tokens[tokens.length - 1]
1984  var endsWithSlash = typeof lastToken === 'string' && /\/$/.test(lastToken)
1985
1986  // Iterate over the tokens and create our regexp string.
1987  for (var i = 0; i < tokens.length; i++) {
1988    var token = tokens[i]
1989
1990    if (typeof token === 'string') {
1991      route += escapeString(token)
1992    } else {
1993      var prefix = escapeString(token.prefix)
1994      var capture = token.pattern
1995
1996      if (token.repeat) {
1997        capture += '(?:' + prefix + capture + ')*'
1998      }
1999
2000      if (token.optional) {
2001        if (prefix) {
2002          capture = '(?:' + prefix + '(' + capture + '))?'
2003        } else {
2004          capture = '(' + capture + ')?'
2005        }
2006      } else {
2007        capture = prefix + '(' + capture + ')'
2008      }
2009
2010      route += capture
2011    }
2012  }
2013
2014  // In non-strict mode we allow a slash at the end of match. If the path to
2015  // match already ends with a slash, we remove it for consistency. The slash
2016  // is valid at the end of a path match, not in the middle. This is important
2017  // in non-ending mode, where "/test/" shouldn't match "/test//route".
2018  if (!strict) {
2019    route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?'
2020  }
2021
2022  if (end) {
2023    route += '$'
2024  } else {
2025    // In non-ending mode, we need the capturing groups to match as much as
2026    // possible by using a positive lookahead to the end or next path segment.
2027    route += strict && endsWithSlash ? '' : '(?=\\/|$)'
2028  }
2029
2030  return new RegExp('^' + route, flags(options))
2031}
2032
2033/**
2034 * Normalize the given path string, returning a regular expression.
2035 *
2036 * An empty array can be passed in for the keys, which will hold the
2037 * placeholder key descriptions. For example, using `/user/:id`, `keys` will
2038 * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
2039 *
2040 * @param  {(String|RegExp|Array)} path
2041 * @param  {Array}                 [keys]
2042 * @param  {Object}                [options]
2043 * @return {RegExp}
2044 */
2045function pathToRegexp (path, keys, options) {
2046  keys = keys || []
2047
2048  if (!isarray(keys)) {
2049    options = keys
2050    keys = []
2051  } else if (!options) {
2052    options = {}
2053  }
2054
2055  if (path instanceof RegExp) {
2056    return regexpToRegexp(path, keys, options)
2057  }
2058
2059  if (isarray(path)) {
2060    return arrayToRegexp(path, keys, options)
2061  }
2062
2063  return stringToRegexp(path, keys, options)
2064}
2065
2066////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2067
2068},"node_modules":{"isarray":{
2068"package.json":function(require,exports){
2069
2070////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2071//                                                                                                                    //
2072// node_modules/meteor/kadira_flow-router/node_modules/page/node_modules/path-to-regexp/node_modules/isarray/package. //
2073//                                                                                                                    //
2074////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2075                                                                                                                      //
2076exports.name = "isarray";
2077exports.version = "0.0.1";
2078exports.main = "index.js";
2079
2080////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2081
2082},
2082"index.js":function(require,exports,module){
2083
2084////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2085//                                                                                                                    //
2086// node_modules/meteor/kadira_flow-router/node_modules/page/node_modules/path-to-regexp/node_modules/isarray/index.js //
2087//                                                                                                                    //
2088////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2089                                                                                                                      //
2090module.exports = Array.isArray || function (arr) {
2091  return Object.prototype.toString.call(arr) == '[object Array]';
2092};
2093
2094////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2095
2096}}}}}},"qs":{
2096"package.json":function(require,exports){
2097
2098////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2099//                                                                                                                    //
2100// node_modules/meteor/kadira_flow-router/node_modules/qs/package.json                                                //
2101//                                                                                                                    //
2102////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2103                                                                                                                      //
2104exports.name = "qs";
2105exports.version = "5.2.0";
2106exports.main = "lib/index.js";
2107
2108////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2109
2110},"lib":{
2110"index.js":function(require,exports,module){
2111
2112////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2113//                                                                                                                    //
2114// node_modules/meteor/kadira_flow-router/node_modules/qs/lib/index.js                                                //
2115//                                                                                                                    //
2116////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2117                                                                                                                      //
2118// Load modules
2119
2120var Stringify = require('./stringify');
2121var Parse = require('./parse');
2122
2123
2124// Declare internals
2125
2126var internals = {};
2127
2128
2129module.exports = {
2130    stringify: Stringify,
2131    parse: Parse
2132};
2133
2134////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2135
2136},
2136"stringify.js":function(require,exports,module){
2137
2138////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2139//                                                                                                                    //
2140// node_modules/meteor/kadira_flow-router/node_modules/qs/lib/stringify.js                                            //
2141//                                                                                                                    //
2142////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2143                                                                                                                      //
2144// Load modules
2145
2146var Utils = require('./utils');
2147
2148
2149// Declare internals
2150
2151var internals = {
2152    delimiter: '&',
2153    arrayPrefixGenerators: {
2154        brackets: function (prefix, key) {
2155
2156            return prefix + '[]';
2157        },
2158        indices: function (prefix, key) {
2159
2160            return prefix + '[' + key + ']';
2161        },
2162        repeat: function (prefix, key) {
2163
2164            return prefix;
2165        }
2166    },
2167    strictNullHandling: false,
2168    skipNulls: false,
2169    encode: true
2170};
2171
2172
2173internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort) {
2174
2175    if (typeof filter === 'function') {
2176        obj = filter(prefix, obj);
2177    }
2178    else if (Utils.isBuffer(obj)) {
2179        obj = obj.toString();
2180    }
2181    else if (obj instanceof Date) {
2182        obj = obj.toISOString();
2183    }
2184    else if (obj === null) {
2185        if (strictNullHandling) {
2186            return encode ? Utils.encode(prefix) : prefix;
2187        }
2188
2189        obj = '';
2190    }
2191
2192    if (typeof obj === 'string' ||
2193        typeof obj === 'number' ||
2194        typeof obj === 'boolean') {
2195
2196        if (encode) {
2197            return [Utils.encode(prefix) + '=' + Utils.encode(obj)];
2198        }
2199        return [prefix + '=' + obj];
2200    }
2201
2202    var values = [];
2203
2204    if (typeof obj === 'undefined') {
2205        return values;
2206    }
2207
2208    var objKeys;
2209    if (Array.isArray(filter)) {
2210        objKeys = filter;
2211    } else {
2212        var keys = Object.keys(obj);
2213        objKeys = sort ? keys.sort(sort) : keys;
2214    }
2215
2216    for (var i = 0, il = objKeys.length; i < il; ++i) {
2217        var key = objKeys[i];
2218
2219        if (skipNulls &&
2220            obj[key] === null) {
2221
2222            continue;
2223        }
2224
2225        if (Array.isArray(obj)) {
2226            values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
2227        }
2228        else {
2229            values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
2230        }
2231    }
2232
2233    return values;
2234};
2235
2236
2237module.exports = function (obj, options) {
2238
2239    options = options || {};
2240    var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
2241    var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
2242    var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
2243    var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
2244    var sort = typeof options.sort === 'function' ? options.sort : null;
2245    var objKeys;
2246    var filter;
2247    if (typeof options.filter === 'function') {
2248        filter = options.filter;
2249        obj = filter('', obj);
2250    }
2251    else if (Array.isArray(options.filter)) {
2252        objKeys = filter = options.filter;
2253    }
2254
2255    var keys = [];
2256
2257    if (typeof obj !== 'object' ||
2258        obj === null) {
2259
2260        return '';
2261    }
2262
2263    var arrayFormat;
2264    if (options.arrayFormat in internals.arrayPrefixGenerators) {
2265        arrayFormat = options.arrayFormat;
2266    }
2267    else if ('indices' in options) {
2268        arrayFormat = options.indices ? 'indices' : 'repeat';
2269    }
2270    else {
2271        arrayFormat = 'indices';
2272    }
2273
2274    var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];
2275
2276    if (!objKeys) {
2277        objKeys = Object.keys(obj);
2278    }
2279
2280    if (sort) {
2281        objKeys.sort(sort);
2282    }
2283
2284    for (var i = 0, il = objKeys.length; i < il; ++i) {
2285        var key = objKeys[i];
2286
2287        if (skipNulls &&
2288            obj[key] === null) {
2289
2290            continue;
2291        }
2292
2293        keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort));
2294    }
2295
2296    return keys.join(delimiter);
2297};
2298
2299////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2300
2301},
2301"utils.js":function(require,exports){
2302
2303////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2304//                                                                                                                    //
2305// node_modules/meteor/kadira_flow-router/node_modules/qs/lib/utils.js                                                //
2306//                                                                                                                    //
2307////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2308                                                                                                                      //
2309// Load modules
2310
2311
2312// Declare internals
2313
2314var internals = {};
2315internals.hexTable = new Array(256);
2316for (var h = 0; h < 256; ++h) {
2317    internals.hexTable[h] = '%' + ((h < 16 ? '0' : '') + h.toString(16)).toUpperCase();
2318}
2319
2320
2321exports.arrayToObject = function (source, options) {
2322
2323    var obj = options.plainObjects ? Object.create(null) : {};
2324    for (var i = 0, il = source.length; i < il; ++i) {
2325        if (typeof source[i] !== 'undefined') {
2326
2327            obj[i] = source[i];
2328        }
2329    }
2330
2331    return obj;
2332};
2333
2334
2335exports.merge = function (target, source, options) {
2336
2337    if (!source) {
2338        return target;
2339    }
2340
2341    if (typeof source !== 'object') {
2342        if (Array.isArray(target)) {
2343            target.push(source);
2344        }
2345        else if (typeof target === 'object') {
2346            target[source] = true;
2347        }
2348        else {
2349            target = [target, source];
2350        }
2351
2352        return target;
2353    }
2354
2355    if (typeof target !== 'object') {
2356        target = [target].concat(source);
2357        return target;
2358    }
2359
2360    if (Array.isArray(target) &&
2361        !Array.isArray(source)) {
2362
2363        target = exports.arrayToObject(target, options);
2364    }
2365
2366    var keys = Object.keys(source);
2367    for (var k = 0, kl = keys.length; k < kl; ++k) {
2368        var key = keys[k];
2369        var value = source[key];
2370
2371        if (!Object.prototype.hasOwnProperty.call(target, key)) {
2372            target[key] = value;
2373        }
2374        else {
2375            target[key] = exports.merge(target[key], value, options);
2376        }
2377    }
2378
2379    return target;
2380};
2381
2382
2383exports.decode = function (str) {
2384
2385    try {
2386        return decodeURIComponent(str.replace(/\+/g, ' '));
2387    } catch (e) {
2388        return str;
2389    }
2390};
2391
2392exports.encode = function (str) {
2393
2394    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
2395    // It has been adapted here for stricter adherence to RFC 3986
2396    if (str.length === 0) {
2397        return str;
2398    }
2399
2400    if (typeof str !== 'string') {
2401        str = '' + str;
2402    }
2403
2404    var out = '';
2405    for (var i = 0, il = str.length; i < il; ++i) {
2406        var c = str.charCodeAt(i);
2407
2408        if (c === 0x2D || // -
2409            c === 0x2E || // .
2410            c === 0x5F || // _
2411            c === 0x7E || // ~
2412            (c >= 0x30 && c <= 0x39) || // 0-9
2413            (c >= 0x41 && c <= 0x5A) || // a-z
2414            (c >= 0x61 && c <= 0x7A)) { // A-Z
2415
2416            out += str[i];
2417            continue;
2418        }
2419
2420        if (c < 0x80) {
2421            out += internals.hexTable[c];
2422            continue;
2423        }
2424
2425        if (c < 0x800) {
2426            out += internals.hexTable[0xC0 | (c >> 6)] + internals.hexTable[0x80 | (c & 0x3F)];
2427            continue;
2428        }
2429
2430        if (c < 0xD800 || c >= 0xE000) {
2431            out += internals.hexTable[0xE0 | (c >> 12)] + internals.hexTable[0x80 | ((c >> 6) & 0x3F)] + internals.hexTable[0x80 | (c & 0x3F)];
2432            continue;
2433        }
2434
2435        ++i;
2436        c = 0x10000 + (((c & 0x3FF) << 10) | (str.charCodeAt(i) & 0x3FF));
2437        out += internals.hexTable[0xF0 | (c >> 18)] + internals.hexTable[0x80 | ((c >> 12) & 0x3F)] + internals.hexTable[0x80 | ((c >> 6) & 0x3F)] + internals.hexTable[0x80 | (c & 0x3F)];
2438    }
2439
2440    return out;
2441};
2442
2443exports.compact = function (obj, refs) {
2444
2445    if (typeof obj !== 'object' ||
2446        obj === null) {
2447
2448        return obj;
2449    }
2450
2451    refs = refs || [];
2452    var lookup = refs.indexOf(obj);
2453    if (lookup !== -1) {
2454        return refs[lookup];
2455    }
2456
2457    refs.push(obj);
2458
2459    if (Array.isArray(obj)) {
2460        var compacted = [];
2461
2462        for (var i = 0, il = obj.length; i < il; ++i) {
2463            if (typeof obj[i] !== 'undefined') {
2464                compacted.push(obj[i]);
2465            }
2466        }
2467
2468        return compacted;
2469    }
2470
2471    var keys = Object.keys(obj);
2472    for (i = 0, il = keys.length; i < il; ++i) {
2473        var key = keys[i];
2474        obj[key] = exports.compact(obj[key], refs);
2475    }
2476
2477    return obj;
2478};
2479
2480
2481exports.isRegExp = function (obj) {
2482
2483    return Object.prototype.toString.call(obj) === '[object RegExp]';
2484};
2485
2486
2487exports.isBuffer = function (obj) {
2488
2489    if (obj === null ||
2490        typeof obj === 'undefined') {
2491
2492        return false;
2493    }
2494
2495    return !!(obj.constructor &&
2496              obj.constructor.isBuffer &&
2497              obj.constructor.isBuffer(obj));
2498};
2499
2500////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2501
2502},
2502"parse.js":function(require,exports,module){
2503
2504////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2505//                                                                                                                    //
2506// node_modules/meteor/kadira_flow-router/node_modules/qs/lib/parse.js                                                //
2507//                                                                                                                    //
2508////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2509                                                                                                                      //
2510// Load modules
2511
2512var Utils = require('./utils');
2513
2514
2515// Declare internals
2516
2517var internals = {
2518    delimiter: '&',
2519    depth: 5,
2520    arrayLimit: 20,
2521    parameterLimit: 1000,
2522    strictNullHandling: false,
2523    plainObjects: false,
2524    allowPrototypes: false,
2525    allowDots: false
2526};
2527
2528
2529internals.parseValues = function (str, options) {
2530
2531    var obj = {};
2532    var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
2533
2534    for (var i = 0, il = parts.length; i < il; ++i) {
2535        var part = parts[i];
2536        var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
2537
2538        if (pos === -1) {
2539            obj[Utils.decode(part)] = '';
2540
2541            if (options.strictNullHandling) {
2542                obj[Utils.decode(part)] = null;
2543            }
2544        }
2545        else {
2546            var key = Utils.decode(part.slice(0, pos));
2547            var val = Utils.decode(part.slice(pos + 1));
2548
2549            if (!Object.prototype.hasOwnProperty.call(obj, key)) {
2550                obj[key] = val;
2551            }
2552            else {
2553                obj[key] = [].concat(obj[key]).concat(val);
2554            }
2555        }
2556    }
2557
2558    return obj;
2559};
2560
2561
2562internals.parseObject = function (chain, val, options) {
2563
2564    if (!chain.length) {
2565        return val;
2566    }
2567
2568    var root = chain.shift();
2569
2570    var obj;
2571    if (root === '[]') {
2572        obj = [];
2573        obj = obj.concat(internals.parseObject(chain, val, options));
2574    }
2575    else {
2576        obj = options.plainObjects ? Object.create(null) : {};
2577        var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
2578        var index = parseInt(cleanRoot, 10);
2579        var indexString = '' + index;
2580        if (!isNaN(index) &&
2581            root !== cleanRoot &&
2582            indexString === cleanRoot &&
2583            index >= 0 &&
2584            (options.parseArrays &&
2585             index <= options.arrayLimit)) {
2586
2587            obj = [];
2588            obj[index] = internals.parseObject(chain, val, options);
2589        }
2590        else {
2591            obj[cleanRoot] = internals.parseObject(chain, val, options);
2592        }
2593    }
2594
2595    return obj;
2596};
2597
2598
2599internals.parseKeys = function (key, val, options) {
2600
2601    if (!key) {
2602        return;
2603    }
2604
2605    // Transform dot notation to bracket notation
2606
2607    if (options.allowDots) {
2608        key = key.replace(/\.([^\.\[]+)/g, '[$1]');
2609    }
2610
2611    // The regex chunks
2612
2613    var parent = /^([^\[\]]*)/;
2614    var child = /(\[[^\[\]]*\])/g;
2615
2616    // Get the parent
2617
2618    var segment = parent.exec(key);
2619
2620    // Stash the parent if it exists
2621
2622    var keys = [];
2623    if (segment[1]) {
2624        // If we aren't using plain objects, optionally prefix keys
2625        // that would overwrite object prototype properties
2626        if (!options.plainObjects &&
2627            Object.prototype.hasOwnProperty(segment[1])) {
2628
2629            if (!options.allowPrototypes) {
2630                return;
2631            }
2632        }
2633
2634        keys.push(segment[1]);
2635    }
2636
2637    // Loop through children appending to the array until we hit depth
2638
2639    var i = 0;
2640    while ((segment = child.exec(key)) !== null && i < options.depth) {
2641
2642        ++i;
2643        if (!options.plainObjects &&
2644            Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
2645
2646            if (!options.allowPrototypes) {
2647                continue;
2648            }
2649        }
2650        keys.push(segment[1]);
2651    }
2652
2653    // If there's a remainder, just add whatever is left
2654
2655    if (segment) {
2656        keys.push('[' + key.slice(segment.index) + ']');
2657    }
2658
2659    return internals.parseObject(keys, val, options);
2660};
2661
2662
2663module.exports = function (str, options) {
2664
2665    options = options || {};
2666    options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
2667    options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
2668    options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
2669    options.parseArrays = options.parseArrays !== false;
2670    options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : internals.allowDots;
2671    options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : internals.plainObjects;
2672    options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : internals.allowPrototypes;
2673    options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
2674    options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
2675
2676    if (str === '' ||
2677        str === null ||
2678        typeof str === 'undefined') {
2679
2680        return options.plainObjects ? Object.create(null) : {};
2681    }
2682
2683    var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
2684    var obj = options.plainObjects ? Object.create(null) : {};
2685
2686    // Iterate over the keys and setup the new object
2687
2688    var keys = Object.keys(tempObj);
2689    for (var i = 0, il = keys.length; i < il; ++i) {
2690        var key = keys[i];
2691        var newObj = internals.parseKeys(key, tempObj[key], options);
2692        obj = Utils.merge(obj, newObj, options);
2693    }
2694
2695    return Utils.compact(obj);
2696};
2697
2698////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2699
2700}
2700}}}}}}},{
2701  "extensions": [
2702    ".js",
2703    ".json"
2704  ]
2705});
2706require("/node_modules/meteor/kadira:flow-router/client/modules.js");
2707require("/node_modules/meteor/kadira:flow-router/client/triggers.js");
2708require("/node_modules/meteor/kadira:flow-router/client/router.js");
2709require("/node_modules/meteor/kadira:flow-router/client/group.js");
2710require("/node_modules/meteor/kadira:flow-router/client/route.js");
2711require("/node_modules/meteor/kadira:flow-router/client/_init.js");
2712require("/node_modules/meteor/kadira:flow-router/lib/router.js");
2713
2714/* Exports */
2715Package._define("kadira:flow-router", {
2716  FlowRouter: FlowRouter
2717});
2718
2719})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.