;(function (t) { var e = (typeof self == 'object' && self.self === self && self) || (typeof global == 'object' && global.global === global && global) if (typeof define === 'function' && define.amd) { define(['underscore', 'jquery', 'exports'], function (i, n, r) { e.Backbone = t(e, r, i, n) }) } else if (typeof exports !== 'undefined') { var i = require('underscore'), n try { n = require('jquery') } catch (r) {} t(e, exports, i, n) } else { e.Backbone = t(e, {}, e._, e.jQuery || e.Zepto || e.ender || e.$) } })(function (t, e, i, n) { var r = t.Backbone var s = Array.prototype.slice e.VERSION = '1.4.0' e.$ = n e.noConflict = function () { t.Backbone = r return this } e.emulateHTTP = false e.emulateJSON = false var a = (e.Events = {}) var o = /\s+/ var h var u = function (t, e, n, r, s) { var a = 0, h if (n && typeof n === 'object') { if (r !== void 0 && 'context' in s && s.context === void 0) s.context = r for (h = i.keys(n); a < h.length; a++) { e = u(t, e, h[a], n[h[a]], s) } } else if (n && o.test(n)) { for (h = n.split(o); a < h.length; a++) { e = t(e, h[a], r, s) } } else { e = t(e, n, r, s) } return e } a.on = function (t, e, i) { this._events = u(l, this._events || {}, t, e, { context: i, ctx: this, listening: h }) if (h) { var n = this._listeners || (this._listeners = {}) n[h.id] = h h.interop = false } return this } a.listenTo = function (t, e, n) { if (!t) return this var r = t._listenId || (t._listenId = i.uniqueId('l')) var s = this._listeningTo || (this._listeningTo = {}) var a = (h = s[r]) if (!a) { this._listenId || (this._listenId = i.uniqueId('l')) a = h = s[r] = new g(this, t) } var o = c(t, e, n, this) h = void 0 if (o) throw o if (a.interop) a.on(e, n) return this } var l = function (t, e, i, n) { if (i) { var r = t[e] || (t[e] = []) var s = n.context, a = n.ctx, o = n.listening if (o) o.count++ r.push({ callback: i, context: s, ctx: s || a, listening: o }) } return t } var c = function (t, e, i, n) { try { t.on(e, i, n) } catch (r) { return r } } a.off = function (t, e, i) { if (!this._events) return this this._events = u(f, this._events, t, e, { context: i, listeners: this._listeners }) return this } a.stopListening = function (t, e, n) { var r = this._listeningTo if (!r) return this var s = t ? [t._listenId] : i.keys(r) for (var a = 0; a < s.length; a++) { var o = r[s[a]] if (!o) break o.obj.off(e, n, this) if (o.interop) o.off(e, n) } if (i.isEmpty(r)) this._listeningTo = void 0 return this } var f = function (t, e, n, r) { if (!t) return var s = r.context, a = r.listeners var o = 0, h if (!e && !s && !n) { for (h = i.keys(a); o < h.length; o++) { a[h[o]].cleanup() } return } h = e ? [e] : i.keys(t) for (; o < h.length; o++) { e = h[o] var u = t[e] if (!u) break var l = [] for (var c = 0; c < u.length; c++) { var f = u[c] if ((n && n !== f.callback && n !== f.callback._callback) || (s && s !== f.context)) { l.push(f) } else { var d = f.listening if (d) d.off(e, n) } } if (l.length) { t[e] = l } else { delete t[e] } } return t } a.once = function (t, e, i) { var n = u(d, {}, t, e, this.off.bind(this)) if (typeof t === 'string' && i == null) e = void 0 return this.on(n, e, i) } a.listenToOnce = function (t, e, i) { var n = u(d, {}, e, i, this.stopListening.bind(this, t)) return this.listenTo(t, n) } var d = function (t, e, n, r) { if (n) { var s = (t[e] = i.once(function () { r(e, s) n.apply(this, arguments) })) s._callback = n } return t } a.trigger = function (t) { if (!this._events) return this var e = Math.max(0, arguments.length - 1) var i = Array(e) for (var n = 0; n < e; n++) i[n] = arguments[n + 1] u(v, this._events, t, void 0, i) return this } var v = function (t, e, i, n) { if (t) { var r = t[e] var s = t.all if (r && s) s = s.slice() if (r) p(r, n) if (s) p(s, [e].concat(n)) } return t } var p = function (t, e) { var i, n = -1, r = t.length, s = e[0], a = e[1], o = e[2] switch (e.length) { case 0: while (++n < r) (i = t[n]).callback.call(i.ctx) return case 1: while (++n < r) (i = t[n]).callback.call(i.ctx, s) return case 2: while (++n < r) (i = t[n]).callback.call(i.ctx, s, a) return case 3: while (++n < r) (i = t[n]).callback.call(i.ctx, s, a, o) return default: while (++n < r) (i = t[n]).callback.apply(i.ctx, e) return } } var g = function (t, e) { this.id = t._listenId this.listener = t this.obj = e this.interop = true this.count = 0 this._events = void 0 } g.prototype.on = a.on g.prototype.off = function (t, e) { var i if (this.interop) { this._events = u(f, this._events, t, e, { context: void 0, listeners: void 0 }) i = !this._events } else { this.count-- i = this.count === 0 } if (i) this.cleanup() } g.prototype.cleanup = function () { delete this.listener._listeningTo[this.obj._listenId] if (!this.interop) delete this.obj._listeners[this.id] } a.bind = a.on a.unbind = a.off i.extend(e, a) var m = (e.Model = function (t, e) { var n = t || {} e || (e = {}) this.preinitialize.apply(this, arguments) this.cid = i.uniqueId(this.cidPrefix) this.attributes = {} if (e.collection) this.collection = e.collection if (e.parse) n = this.parse(n, e) || {} var r = i.result(this, 'defaults') n = i.defaults(i.extend({}, r, n), r) this.set(n, e) this.changed = {} this.initialize.apply(this, arguments) }) i.extend(m.prototype, a, { changed: null, validationError: null, idAttribute: 'id', cidPrefix: 'c', preinitialize: function () {}, initialize: function () {}, toJSON: function (t) { return i.clone(this.attributes) }, sync: function () { return e.sync.apply(this, arguments) }, get: function (t) { return this.attributes[t] }, escape: function (t) { return i.escape(this.get(t)) }, has: function (t) { return this.get(t) != null }, matches: function (t) { return !!i.iteratee(t, this)(this.attributes) }, set: function (t, e, n) { if (t == null) return this var r if (typeof t === 'object') { r = t n = e } else { ;(r = {})[t] = e } n || (n = {}) if (!this._validate(r, n)) return false var s = n.unset var a = n.silent var o = [] var h = this._changing this._changing = true if (!h) { this._previousAttributes = i.clone(this.attributes) this.changed = {} } var u = this.attributes var l = this.changed var c = this._previousAttributes for (var f in r) { e = r[f] if (!i.isEqual(u[f], e)) o.push(f) if (!i.isEqual(c[f], e)) { l[f] = e } else { delete l[f] } s ? delete u[f] : (u[f] = e) } if (this.idAttribute in r) this.id = this.get(this.idAttribute) if (!a) { if (o.length) this._pending = n for (var d = 0; d < o.length; d++) { this.trigger('change:' + o[d], this, u[o[d]], n) } } if (h) return this if (!a) { while (this._pending) { n = this._pending this._pending = false this.trigger('change', this, n) } } this._pending = false this._changing = false return this }, unset: function (t, e) { return this.set(t, void 0, i.extend({}, e, { unset: true })) }, clear: function (t) { var e = {} for (var n in this.attributes) e[n] = void 0 return this.set(e, i.extend({}, t, { unset: true })) }, hasChanged: function (t) { if (t == null) return !i.isEmpty(this.changed) return i.has(this.changed, t) }, changedAttributes: function (t) { if (!t) return this.hasChanged() ? i.clone(this.changed) : false var e = this._changing ? this._previousAttributes : this.attributes var n = {} var r for (var s in t) { var a = t[s] if (i.isEqual(e[s], a)) continue n[s] = a r = true } return r ? n : false }, previous: function (t) { if (t == null || !this._previousAttributes) return null return this._previousAttributes[t] }, previousAttributes: function () { return i.clone(this._previousAttributes) }, fetch: function (t) { t = i.extend({ parse: true }, t) var e = this var n = t.success t.success = function (i) { var r = t.parse ? e.parse(i, t) : i if (!e.set(r, t)) return false if (n) n.call(t.context, e, i, t) e.trigger('sync', e, i, t) } G(this, t) return this.sync('read', this, t) }, save: function (t, e, n) { var r if (t == null || typeof t === 'object') { r = t n = e } else { ;(r = {})[t] = e } n = i.extend({ validate: true, parse: true }, n) var s = n.wait if (r && !s) { if (!this.set(r, n)) return false } else if (!this._validate(r, n)) { return false } var a = this var o = n.success var h = this.attributes n.success = function (t) { a.attributes = h var e = n.parse ? a.parse(t, n) : t if (s) e = i.extend({}, r, e) if (e && !a.set(e, n)) return false if (o) o.call(n.context, a, t, n) a.trigger('sync', a, t, n) } G(this, n) if (r && s) this.attributes = i.extend({}, h, r) var u = this.isNew() ? 'create' : n.patch ? 'patch' : 'update' if (u === 'patch' && !n.attrs) n.attrs = r var l = this.sync(u, this, n) this.attributes = h return l }, destroy: function (t) { t = t ? i.clone(t) : {} var e = this var n = t.success var r = t.wait var s = function () { e.stopListening() e.trigger('destroy', e, e.collection, t) } t.success = function (i) { if (r) s() if (n) n.call(t.context, e, i, t) if (!e.isNew()) e.trigger('sync', e, i, t) } var a = false if (this.isNew()) { i.defer(t.success) } else { G(this, t) a = this.sync('delete', this, t) } if (!r) s() return a }, url: function () { var t = i.result(this, 'urlRoot') || i.result(this.collection, 'url') || V() if (this.isNew()) return t var e = this.get(this.idAttribute) return t.replace(/[^\/]$/, '$&/') + encodeURIComponent(e) }, parse: function (t, e) { return t }, clone: function () { return new this.constructor(this.attributes) }, isNew: function () { return !this.has(this.idAttribute) }, isValid: function (t) { return this._validate({}, i.extend({}, t, { validate: true })) }, _validate: function (t, e) { if (!e.validate || !this.validate) return true t = i.extend({}, this.attributes, t) var n = (this.validationError = this.validate(t, e) || null) if (!n) return true this.trigger('invalid', this, n, i.extend(e, { validationError: n })) return false }, }) var _ = (e.Collection = function (t, e) { e || (e = {}) this.preinitialize.apply(this, arguments) if (e.model) this.model = e.model if (e.comparator !== void 0) this.comparator = e.comparator this._reset() this.initialize.apply(this, arguments) if (t) this.reset(t, i.extend({ silent: true }, e)) }) var y = { add: true, remove: true, merge: true } var b = { add: true, remove: false } var x = function (t, e, i) { i = Math.min(Math.max(i, 0), t.length) var n = Array(t.length - i) var r = e.length var s for (s = 0; s < n.length; s++) n[s] = t[s + i] for (s = 0; s < r; s++) t[s + i] = e[s] for (s = 0; s < n.length; s++) t[s + r + i] = n[s] } i.extend(_.prototype, a, { model: m, preinitialize: function () {}, initialize: function () {}, toJSON: function (t) { return this.map(function (e) { return e.toJSON(t) }) }, sync: function () { return e.sync.apply(this, arguments) }, add: function (t, e) { return this.set(t, i.extend({ merge: false }, e, b)) }, remove: function (t, e) { e = i.extend({}, e) var n = !i.isArray(t) t = n ? [t] : t.slice() var r = this._removeModels(t, e) if (!e.silent && r.length) { e.changes = { added: [], merged: [], removed: r } this.trigger('update', this, e) } return n ? r[0] : r }, set: function (t, e) { if (t == null) return e = i.extend({}, y, e) if (e.parse && !this._isModel(t)) { t = this.parse(t, e) || [] } var n = !i.isArray(t) t = n ? [t] : t.slice() var r = e.at if (r != null) r = +r if (r > this.length) r = this.length if (r < 0) r += this.length + 1 var s = [] var a = [] var o = [] var h = [] var u = {} var l = e.add var c = e.merge var f = e.remove var d = false var v = this.comparator && r == null && e.sort !== false var p = i.isString(this.comparator) ? this.comparator : null var g, m for (m = 0; m < t.length; m++) { g = t[m] var _ = this.get(g) if (_) { if (c && g !== _) { var b = this._isModel(g) ? g.attributes : g if (e.parse) b = _.parse(b, e) _.set(b, e) o.push(_) if (v && !d) d = _.hasChanged(p) } if (!u[_.cid]) { u[_.cid] = true s.push(_) } t[m] = _ } else if (l) { g = t[m] = this._prepareModel(g, e) if (g) { a.push(g) this._addReference(g, e) u[g.cid] = true s.push(g) } } } if (f) { for (m = 0; m < this.length; m++) { g = this.models[m] if (!u[g.cid]) h.push(g) } if (h.length) this._removeModels(h, e) } var w = false var E = !v && l && f if (s.length && E) { w = this.length !== s.length || i.some(this.models, function (t, e) { return t !== s[e] }) this.models.length = 0 x(this.models, s, 0) this.length = this.models.length } else if (a.length) { if (v) d = true x(this.models, a, r == null ? this.length : r) this.length = this.models.length } if (d) this.sort({ silent: true }) if (!e.silent) { for (m = 0; m < a.length; m++) { if (r != null) e.index = r + m g = a[m] g.trigger('add', g, this, e) } if (d || w) this.trigger('sort', this, e) if (a.length || h.length || o.length) { e.changes = { added: a, removed: h, merged: o } this.trigger('update', this, e) } } return n ? t[0] : t }, reset: function (t, e) { e = e ? i.clone(e) : {} for (var n = 0; n < this.models.length; n++) { this._removeReference(this.models[n], e) } e.previousModels = this.models this._reset() t = this.add(t, i.extend({ silent: true }, e)) if (!e.silent) this.trigger('reset', this, e) return t }, push: function (t, e) { return this.add(t, i.extend({ at: this.length }, e)) }, pop: function (t) { var e = this.at(this.length - 1) return this.remove(e, t) }, unshift: function (t, e) { return this.add(t, i.extend({ at: 0 }, e)) }, shift: function (t) { var e = this.at(0) return this.remove(e, t) }, slice: function () { return s.apply(this.models, arguments) }, get: function (t) { if (t == null) return void 0 return ( this._byId[t] || this._byId[this.modelId(this._isModel(t) ? t.attributes : t)] || (t.cid && this._byId[t.cid]) ) }, has: function (t) { return this.get(t) != null }, at: function (t) { if (t < 0) t += this.length return this.models[t] }, where: function (t, e) { return this[e ? 'find' : 'filter'](t) }, findWhere: function (t) { return this.where(t, true) }, sort: function (t) { var e = this.comparator if (!e) throw new Error('Cannot sort a set without a comparator') t || (t = {}) var n = e.length if (i.isFunction(e)) e = e.bind(this) if (n === 1 || i.isString(e)) { this.models = this.sortBy(e) } else { this.models.sort(e) } if (!t.silent) this.trigger('sort', this, t) return this }, pluck: function (t) { return this.map(t + '') }, fetch: function (t) { t = i.extend({ parse: true }, t) var e = t.success var n = this t.success = function (i) { var r = t.reset ? 'reset' : 'set' n[r](i, t) if (e) e.call(t.context, n, i, t) n.trigger('sync', n, i, t) } G(this, t) return this.sync('read', this, t) }, create: function (t, e) { e = e ? i.clone(e) : {} var n = e.wait t = this._prepareModel(t, e) if (!t) return false if (!n) this.add(t, e) var r = this var s = e.success e.success = function (t, e, i) { if (n) r.add(t, i) if (s) s.call(i.context, t, e, i) } t.save(null, e) return t }, parse: function (t, e) { return t }, clone: function () { return new this.constructor(this.models, { model: this.model, comparator: this.comparator }) }, modelId: function (t) { return t[this.model.prototype.idAttribute || 'id'] }, values: function () { return new E(this, k) }, keys: function () { return new E(this, I) }, entries: function () { return new E(this, S) }, _reset: function () { this.length = 0 this.models = [] this._byId = {} }, _prepareModel: function (t, e) { if (this._isModel(t)) { if (!t.collection) t.collection = this return t } e = e ? i.clone(e) : {} e.collection = this var n = new this.model(t, e) if (!n.validationError) return n this.trigger('invalid', this, n.validationError, e) return false }, _removeModels: function (t, e) { var i = [] for (var n = 0; n < t.length; n++) { var r = this.get(t[n]) if (!r) continue var s = this.indexOf(r) this.models.splice(s, 1) this.length-- delete this._byId[r.cid] var a = this.modelId(r.attributes) if (a != null) delete this._byId[a] if (!e.silent) { e.index = s r.trigger('remove', r, this, e) } i.push(r) this._removeReference(r, e) } return i }, _isModel: function (t) { return t instanceof m }, _addReference: function (t, e) { this._byId[t.cid] = t var i = this.modelId(t.attributes) if (i != null) this._byId[i] = t t.on('all', this._onModelEvent, this) }, _removeReference: function (t, e) { delete this._byId[t.cid] var i = this.modelId(t.attributes) if (i != null) delete this._byId[i] if (this === t.collection) delete t.collection t.off('all', this._onModelEvent, this) }, _onModelEvent: function (t, e, i, n) { if (e) { if ((t === 'add' || t === 'remove') && i !== this) return if (t === 'destroy') this.remove(e, n) if (t === 'change') { var r = this.modelId(e.previousAttributes()) var s = this.modelId(e.attributes) if (r !== s) { if (r != null) delete this._byId[r] if (s != null) this._byId[s] = e } } } this.trigger.apply(this, arguments) }, }) var w = typeof Symbol === 'function' && Symbol.iterator if (w) { _.prototype[w] = _.prototype.values } var E = function (t, e) { this._collection = t this._kind = e this._index = 0 } var k = 1 var I = 2 var S = 3 if (w) { E.prototype[w] = function () { return this } } E.prototype.next = function () { if (this._collection) { if (this._index < this._collection.length) { var t = this._collection.at(this._index) this._index++ var e if (this._kind === k) { e = t } else { var i = this._collection.modelId(t.attributes) if (this._kind === I) { e = i } else { e = [i, t] } } return { value: e, done: false } } this._collection = void 0 } return { value: void 0, done: true } } var T = (e.View = function (t) { this.cid = i.uniqueId('view') this.preinitialize.apply(this, arguments) i.extend(this, i.pick(t, H)) this._ensureElement() this.initialize.apply(this, arguments) }) var P = /^(\S+)\s*(.*)$/ var H = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'] i.extend(T.prototype, a, { tagName: 'div', $: function (t) { return this.$el.find(t) }, preinitialize: function () {}, initialize: function () {}, render: function () { return this }, remove: function () { this._removeElement() this.stopListening() return this }, _removeElement: function () { this.$el.remove() }, setElement: function (t) { this.undelegateEvents() this._setElement(t) this.delegateEvents() return this }, _setElement: function (t) { this.$el = t instanceof e.$ ? t : e.$(t) this.el = this.$el[0] }, delegateEvents: function (t) { t || (t = i.result(this, 'events')) if (!t) return this this.undelegateEvents() for (var e in t) { var n = t[e] if (!i.isFunction(n)) n = this[n] if (!n) continue var r = e.match(P) this.delegate(r[1], r[2], n.bind(this)) } return this }, delegate: function (t, e, i) { this.$el.on(t + '.delegateEvents' + this.cid, e, i) return this }, undelegateEvents: function () { if (this.$el) this.$el.off('.delegateEvents' + this.cid) return this }, undelegate: function (t, e, i) { this.$el.off(t + '.delegateEvents' + this.cid, e, i) return this }, _createElement: function (t) { return document.createElement(t) }, _ensureElement: function () { if (!this.el) { var t = i.extend({}, i.result(this, 'attributes')) if (this.id) t.id = i.result(this, 'id') if (this.className) t['class'] = i.result(this, 'className') this.setElement(this._createElement(i.result(this, 'tagName'))) this._setAttributes(t) } else { this.setElement(i.result(this, 'el')) } }, _setAttributes: function (t) { this.$el.attr(t) }, }) var $ = function (t, e, i, n) { switch (e) { case 1: return function () { return t[i](this[n]) } case 2: return function (e) { return t[i](this[n], e) } case 3: return function (e, r) { return t[i](this[n], C(e, this), r) } case 4: return function (e, r, s) { return t[i](this[n], C(e, this), r, s) } default: return function () { var e = s.call(arguments) e.unshift(this[n]) return t[i].apply(t, e) } } } var A = function (t, e, n, r) { i.each(n, function (i, n) { if (e[n]) t.prototype[n] = $(e, i, n, r) }) } var C = function (t, e) { if (i.isFunction(t)) return t if (i.isObject(t) && !e._isModel(t)) return R(t) if (i.isString(t)) return function (e) { return e.get(t) } return t } var R = function (t) { var e = i.matches(t) return function (t) { return e(t.attributes) } } var M = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 0, foldl: 0, inject: 0, reduceRight: 0, foldr: 0, find: 3, detect: 3, filter: 3, select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3, contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3, head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3, without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3, isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3, sortBy: 3, indexBy: 3, findIndex: 3, findLastIndex: 3, } var N = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0, omit: 0, chain: 1, isEmpty: 1 } i.each( [ [_, M, 'models'], [m, N, 'attributes'], ], function (t) { var e = t[0], n = t[1], r = t[2] e.mixin = function (t) { var n = i.reduce( i.functions(t), function (t, e) { t[e] = 0 return t }, {}, ) A(e, t, n, r) } A(e, i, n, r) }, ) e.sync = function (t, n, r) { var s = j[t] i.defaults(r || (r = {}), { emulateHTTP: e.emulateHTTP, emulateJSON: e.emulateJSON }) var a = { type: s, dataType: 'json' } if (!r.url) { a.url = i.result(n, 'url') || V() } if (r.data == null && n && (t === 'create' || t === 'update' || t === 'patch')) { a.contentType = 'application/json' a.data = JSON.stringify(r.attrs || n.toJSON(r)) } if (r.emulateJSON) { a.contentType = 'application/x-www-form-urlencoded' a.data = a.data ? { model: a.data } : {} } if (r.emulateHTTP && (s === 'PUT' || s === 'DELETE' || s === 'PATCH')) { a.type = 'POST' if (r.emulateJSON) a.data._method = s var o = r.beforeSend r.beforeSend = function (t) { t.setRequestHeader('X-HTTP-Method-Override', s) if (o) return o.apply(this, arguments) } } if (a.type !== 'GET' && !r.emulateJSON) { a.processData = false } var h = r.error r.error = function (t, e, i) { r.textStatus = e r.errorThrown = i if (h) h.call(r.context, t, e, i) } var u = (r.xhr = e.ajax(i.extend(a, r))) n.trigger('request', n, u, r) return u } var j = { create: 'POST', update: 'PUT', patch: 'PATCH', delete: 'DELETE', read: 'GET' } e.ajax = function () { return e.$.ajax.apply(e.$, arguments) } var O = (e.Router = function (t) { t || (t = {}) this.preinitialize.apply(this, arguments) if (t.routes) this.routes = t.routes this._bindRoutes() this.initialize.apply(this, arguments) }) var U = /\((.*?)\)/g var z = /(\(\?)?:\w+/g var q = /\*\w+/g var F = /[\-{}\[\]+?.,\\\^$|#\s]/g i.extend(O.prototype, a, { preinitialize: function () {}, initialize: function () {}, route: function (t, n, r) { if (!i.isRegExp(t)) t = this._routeToRegExp(t) if (i.isFunction(n)) { r = n n = '' } if (!r) r = this[n] var s = this e.history.route(t, function (i) { var a = s._extractParameters(t, i) if (s.execute(r, a, n) !== false) { s.trigger.apply(s, ['route:' + n].concat(a)) s.trigger('route', n, a) e.history.trigger('route', s, n, a) } }) return this }, execute: function (t, e, i) { if (t) t.apply(this, e) }, navigate: function (t, i) { e.history.navigate(t, i) return this }, _bindRoutes: function () { if (!this.routes) return this.routes = i.result(this, 'routes') var t, e = i.keys(this.routes) while ((t = e.pop()) != null) { this.route(t, this.routes[t]) } }, _routeToRegExp: function (t) { t = t .replace(F, '\\$&') .replace(U, '(?:$1)?') .replace(z, function (t, e) { return e ? t : '([^/?]+)' }) .replace(q, '([^?]*?)') return new RegExp('^' + t + '(?:\\?([\\s\\S]*))?$') }, _extractParameters: function (t, e) { var n = t.exec(e).slice(1) return i.map(n, function (t, e) { if (e === n.length - 1) return t || null return t ? decodeURIComponent(t) : null }) }, }) var B = (e.History = function () { this.handlers = [] this.checkUrl = this.checkUrl.bind(this) if (typeof window !== 'undefined') { this.location = window.location this.history = window.history } }) var J = /^[#\/]|\s+$/g var L = /^\/+|\/+$/g var W = /#.*$/ B.started = false i.extend(B.prototype, a, { interval: 50, atRoot: function () { var t = this.location.pathname.replace(/[^\/]$/, '$&/') return t === this.root && !this.getSearch() }, matchRoot: function () { var t = this.decodeFragment(this.location.pathname) var e = t.slice(0, this.root.length - 1) + '/' return e === this.root }, decodeFragment: function (t) { return decodeURI(t.replace(/%25/g, '%2525')) }, getSearch: function () { var t = this.location.href.replace(/#.*/, '').match(/\?.+/) return t ? t[0] : '' }, getHash: function (t) { var e = (t || this).location.href.match(/#(.*)$/) return e ? e[1] : '' }, getPath: function () { var t = this.decodeFragment(this.location.pathname + this.getSearch()).slice( this.root.length - 1, ) return t.charAt(0) === '/' ? t.slice(1) : t }, getFragment: function (t) { if (t == null) { if (this._usePushState || !this._wantsHashChange) { t = this.getPath() } else { t = this.getHash() } } return t.replace(J, '') }, start: function (t) { if (B.started) throw new Error('Backbone.history has already been started') B.started = true this.options = i.extend({ root: '/' }, this.options, t) this.root = this.options.root this._wantsHashChange = this.options.hashChange !== false this._hasHashChange = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7) this._useHashChange = this._wantsHashChange && this._hasHashChange this._wantsPushState = !!this.options.pushState this._hasPushState = !!(this.history && this.history.pushState) this._usePushState = this._wantsPushState && this._hasPushState this.fragment = this.getFragment() this.root = ('/' + this.root + '/').replace(L, '/') if (this._wantsHashChange && this._wantsPushState) { if (!this._hasPushState && !this.atRoot()) { var e = this.root.slice(0, -1) || '/' this.location.replace(e + '#' + this.getPath()) return true } else if (this._hasPushState && this.atRoot()) { this.navigate(this.getHash(), { replace: true }) } } if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) { this.iframe = document.createElement('iframe') this.iframe.src = 'javascript:0' this.iframe.style.display = 'none' this.iframe.tabIndex = -1 var n = document.body var r = n.insertBefore(this.iframe, n.firstChild).contentWindow r.document.open() r.document.close() r.location.hash = '#' + this.fragment } var s = window.addEventListener || function (t, e) { return attachEvent('on' + t, e) } if (this._usePushState) { s('popstate', this.checkUrl, false) } else if (this._useHashChange && !this.iframe) { s('hashchange', this.checkUrl, false) } else if (this._wantsHashChange) { this._checkUrlInterval = setInterval(this.checkUrl, this.interval) } if (!this.options.silent) return this.loadUrl() }, stop: function () { var t = window.removeEventListener || function (t, e) { return detachEvent('on' + t, e) } if (this._usePushState) { t('popstate', this.checkUrl, false) } else if (this._useHashChange && !this.iframe) { t('hashchange', this.checkUrl, false) } if (this.iframe) { document.body.removeChild(this.iframe) this.iframe = null } if (this._checkUrlInterval) clearInterval(this._checkUrlInterval) B.started = false }, route: function (t, e) { this.handlers.unshift({ route: t, callback: e }) }, checkUrl: function (t) { var e = this.getFragment() if (e === this.fragment && this.iframe) { e = this.getHash(this.iframe.contentWindow) } if (e === this.fragment) return false if (this.iframe) this.navigate(e) this.loadUrl() }, loadUrl: function (t) { if (!this.matchRoot()) return false t = this.fragment = this.getFragment(t) return i.some(this.handlers, function (e) { if (e.route.test(t)) { e.callback(t) return true } }) }, navigate: function (t, e) { if (!B.started) return false if (!e || e === true) e = { trigger: !!e } t = this.getFragment(t || '') var i = this.root if (t === '' || t.charAt(0) === '?') { i = i.slice(0, -1) || '/' } var n = i + t t = t.replace(W, '') var r = this.decodeFragment(t) if (this.fragment === r) return this.fragment = r if (this._usePushState) { this.history[e.replace ? 'replaceState' : 'pushState']({}, document.title, n) } else if (this._wantsHashChange) { this._updateHash(this.location, t, e.replace) if (this.iframe && t !== this.getHash(this.iframe.contentWindow)) { var s = this.iframe.contentWindow if (!e.replace) { s.document.open() s.document.close() } this._updateHash(s.location, t, e.replace) } } else { return this.location.assign(n) } if (e.trigger) return this.loadUrl(t) }, _updateHash: function (t, e, i) { if (i) { var n = t.href.replace(/(javascript:|#).*$/, '') t.replace(n + '#' + e) } else { t.hash = '#' + e } }, }) e.history = new B() var D = function (t, e) { var n = this var r if (t && i.has(t, 'constructor')) { r = t.constructor } else { r = function () { return n.apply(this, arguments) } } i.extend(r, n, e) r.prototype = i.create(n.prototype, t) r.prototype.constructor = r r.__super__ = n.prototype return r } m.extend = _.extend = O.extend = T.extend = B.extend = D var V = function () { throw new Error('A "url" property or function must be specified') } var G = function (t, e) { var i = e.error e.error = function (n) { if (i) i.call(e.context, t, n, e) t.trigger('error', t, n, e) } } return e })