UNPKG

62.6 kBJavaScriptView Raw
1/*
2* @version 19.7.1
3* @author Lauri Rooden <lauri@rooden.ee>
4* @license MIT License
5*/
6
7
8
9!function(Date, proto) {
10 var Date$prototype = Date[proto]
11 , String$prototype = String[proto]
12 , Number$prototype = Number[proto]
13 , maskRe = /(\[)((?:\\?.)*?)\]|([YMD])\3\3\3?|([YMDHhmsWSZ])(\4?)|[uUASwoQ]|(["\\\n\r\u2028\u2029])/g
14 , dateRe = /(\d+)[-.\/](\d+)[-.\/](\d+)/
15 , timeRe = /(\d+):(\d+)(?::(\d+))?(\.\d+)?(?:\s*(?:(a)|(p))\.?m\.?)?(\s*(?:Z|GMT|UTC)?(?:([-+]\d\d):?(\d\d)?)?)?/i
16 , fns = Object.create(null)
17 , aliases = {
18 sec: "s",
19 second: "s",
20 seconds: "s",
21 min: "m",
22 minute: "m",
23 minutes: "m",
24 hr: "h",
25 hour: "h",
26 hours: "h",
27 day: "D",
28 days: "D",
29 week: "W",
30 weeks: "W",
31 month: "M",
32 months: "M",
33 year: "Y",
34 years: "Y"
35 }
36 , units = {
37 S: 1,
38 s: 1000,
39 m: 60000,
40 h: 3600000,
41 D: 86400000,
42 W: 604800000
43 }
44 , tmp1 = new Date()
45 , tmp2 = new Date()
46 , map = Date.fnMap = {
47 w: "Day()||7",
48 Y: "FullYear()%100",
49 M: "Month()+1",
50 D: "Date()",
51 h: "Hours()",
52 H: "Hours()%12||12",
53 m: "Minutes()",
54 s: "Seconds()",
55 S: "Milliseconds()"
56 }
57 , locales = Date.locales = {
58 en: {
59 am: "AM",
60 pm: "PM",
61 names: "JanFebMarAprMayJunJulAugSepOctNovDecJanuaryFebruaryMarchAprilMayJuneJulyAugustSeptemberOctoberNovemberDecemberSunMonTueWedThuFriSatSundayMondayTuesdayWednesdayThursdayFridaySaturday".match(/.[a-z]+/g),
62 masks: {
63 LT: "hh:mm",
64 LTS: "hh:mm:ss",
65 L: "DD/MM/YYYY",
66 LL: "D MMMM YYYY",
67 LLL: "D MMMM YYYY hh:mm",
68 LLLL: "DDDD, D MMMM YYYY hh:mm"
69 }
70 }
71 }
72 , masks = Date.masks = {
73 "iso": "UTC:YYYY-MM-DD[T]hh:mm:ss[Z]"
74 }
75
76
77 Date.makeStr = makeStr
78 function makeStr(mask, utc) {
79 var get = "d.get" + (utc ? "UTC" : "")
80 , setA = "a.setTime(+d+((4-(" + get + map.w + "))*864e5))"
81 return (utc ? mask.slice(4) : mask).replace(maskRe, function(match, quote, text, MD, single, pad, esc) {
82 var str = (
83 esc ? escape(esc).replace(/%u/g, "\\u").replace(/%/g, "\\x") :
84 quote ? text :
85 MD == "Y" ? get + "FullYear()" :
86 MD ? "l.names[" + get + (MD == "M" ? "Month" : "Day" ) + "()+" + (match == "DDD" ? 24 : MD == "D" ? 31 : match == "MMM" ? 0 : 12) + "]" :
87 match == "u" ? "(d/1000)>>>0" :
88 match == "U" ? "+d" :
89 match == "Q" ? "((" + get + "Month()/3)|0)+1" :
90 match == "A" ? "l[" + get + map.h + ">11?'pm':'am']" :
91 match == "o" ? setA + ",a" + get.slice(1) + "FullYear()" :
92 single == "Z" ? "(t=o)?(t<0?((t=-t),'-'):'+')+(t<600?'0':'')+(0|(t/60))" + (pad ? "" : "+':'") + "+((t%=60)>9?t:'0'+t):'Z'" :
93 single == "W" ? "Math.ceil(((" + setA + "-a.s" + get.slice(3) + "Month(0,1))/864e5+1)/7)" :
94 get + map[single || match]
95 )
96 return quote || esc ? str : '"+(' + (
97 match == "SS" ? "(t=" + str + ")>9?t>99?t:'0'+t:'00'+t" :
98 pad && single != "Z" ? "(t=" + str + ")>9?t:'0'+t" :
99 str
100 ) + ')+"'
101 })
102 }
103
104 Date$prototype.date = function(_mask, _zone) {
105 var offset, undef
106 , date = this
107 , locale = locales[date._locale || Date._locale || "en"] || locales.en
108 , mask = locale.masks && locale.masks[_mask] || masks[_mask] || _mask || masks.iso
109 , zone = _zone == undef ? date._tz || Date._tz : _zone
110 , utc = mask.slice(0, 4) == "UTC:"
111 if (zone != undef && !utc) {
112 offset = 60 * zone
113 tmp1.setTime(+date + offset * 6e4)
114 utc = mask = "UTC:" + mask
115 } else {
116 offset = utc ? 0 : -date.getTimezoneOffset()
117 tmp1.setTime(+date)
118 }
119 return isNaN(+date) ? "" + date : (
120 fns[mask] || (fns[mask] = Function("d,a,o,l", 'var t;return "' + makeStr(mask, utc) + '"')))(
121 tmp1,
122 tmp2,
123 offset,
124 locale
125 )
126 }
127
128 addFn("add", function(amount, _unit, mask) {
129 var date = this
130 , unit = aliases[_unit] || _unit
131 if (unit == "M" || unit == "Y" && (amount *= 12)) {
132 unit = date.getUTCDate()
133 date.setUTCMonth(date.getUTCMonth() + amount)
134 if (unit > (unit = date.getUTCDate())) {
135 date.add(-unit, "D")
136 }
137 } else if (amount) {
138 date.setTime(date.getTime() + (amount * (units[unit] || 1)))
139 }
140 return mask ? date.date(mask) : date
141 })
142
143 addFn("startOf", function(_unit, mask) {
144 var date = this
145 , unit = aliases[_unit] || _unit
146 if (unit == "Y") {
147 date.setUTCMonth(0, 1)
148 unit = "D"
149 } else if (unit == "M") {
150 date.setUTCDate(1)
151 unit = "D"
152 }
153 date.setTime(date - (date % (units[unit] || 1)))
154 return mask ? date.date(mask) : date
155 })
156
157 addFn("endOf", function(unit, mask) {
158 return this.startOf(unit).add(1, unit).add(-1, "S", mask)
159 })
160
161 addFn("since", function(from, _unit) {
162 var diff
163 , date = this
164 , unit = aliases[_unit] || _unit
165 if (typeof from == "string") {
166 from = aliases[from] ? (tmp2.setTime(+date), tmp2.startOf(from)) : from.date()
167 }
168 if (units[unit]) {
169 diff = (date - from) / units[unit]
170 } else {
171 diff = date.since("month", "S") - from.since("month", "S")
172 if (diff) {
173 tmp1.setTime(+date)
174 diff /= units.D * tmp1.endOf("M").getUTCDate()
175 }
176 diff += 12 * (date.getUTCFullYear() - from.getUTCFullYear()) + date.getUTCMonth() - from.getUTCMonth()
177 if (unit == "Y") {
178 diff /= 12
179 }
180 }
181
182 return diff
183 })
184
185 //*/
186
187
188 /*
189 * // In Chrome Date.parse("01.02.2001") is Jan
190 * num = +date || Date.parse(date) || ""+date;
191 */
192
193 String$prototype.date = function(mask, zoneOut, zoneIn) {
194 var undef, date, match, year, month
195 , str = this
196 if (isNaN(+str)) {
197 if (match = str.match(dateRe)) {
198 // Big endian date, starting with the year, eg. 2011-01-31
199 // Middle endian date, starting with the month, eg. 01/31/2011
200 // Little endian date, starting with the day, eg. 31.01.2011
201 year = match[1] > 99 ? 1 : 3
202 month = Date.middleEndian ? 4 - year : 2
203 date = new Date(match[year], match[month] - 1, match[6 - month - year])
204 } else {
205 date = new Date()
206 }
207
208 // Time
209 match = str.match(timeRe) || [0, 0, 0]
210 date.setHours(
211 match[6] && match[1] < 12 ? +match[1] + 12 :
212 match[5] && match[1] == 12 ? 0 : match[1],
213 match[2], match[3]|0, (1000 * match[4])|0
214 )
215
216 // Timezone
217 if (match[7]) {
218 zoneIn = (match[8]|0) + ((match[9]|0)/(match[8]<0?-60:60))
219 }
220
221 if (zoneIn != undef) {
222 date.setTime(date - (60 * zoneIn + date.getTimezoneOffset()) * 60000)
223 }
224 return mask ? date.date(mask, zoneOut) : date
225 }
226 return (+str).date(mask, zoneOut, zoneIn)
227 }
228
229 Number$prototype.date = function(mask, zoneOut, zoneIn) {
230 var date
231 , num = this
232 if (num < 4294967296) num *= 1000
233 date = new Date(
234 zoneIn != date ?
235 tmp1.setTime(num) - (60 * zoneIn + tmp1.getTimezoneOffset()) * 60000 :
236 num
237 )
238
239 return mask ? date.date(mask, zoneOut) : date
240 }
241
242 function addFn(method, fn) {
243 Date$prototype[method] = fn
244 String$prototype[method] = Number$prototype[method] = function(a, b, c) {
245 return this.date()[method](a, b, c)
246 }
247 }
248
249 function makeSetter(method) {
250 Date[method] = Date$prototype[method] = function(value, mask) {
251 var date = this
252 date["_" + method] = value
253 return mask ? date.date(mask) : date
254 }
255 }
256
257 makeSetter("tz")
258 makeSetter("locale")
259}(Date, "prototype")
260!function(exports) {
261 var pointerCache = {}
262 , hasOwn = pointerCache.hasOwnProperty
263
264 exports.clone = clone
265 exports.mergePatch = mergePatch
266 exports.isObject = isObject
267
268 /**
269 * JSON Merge Patch
270 * @see https://tools.ietf.org/html/rfc7396
271 */
272
273 function mergePatch(target, patch, changed, previous, pointer) {
274 var undef, key, oldVal, val, len, nextPointer
275 if (isObject(patch)) {
276 if (!pointer) {
277 pointer = ""
278 }
279 if (!isObject(target)) {
280 target = {}
281 }
282 for (key in patch) if (
283 undef !== (oldVal = target[key], val = patch[key]) &&
284 hasOwn.call(patch, key) &&
285 (
286 undef == val ?
287 undef !== oldVal && delete target[key] :
288 target[key] !== val
289 )
290 ) {
291 nextPointer = pointer + "/" + key.replace(/~/g, "~0").replace(/\//g, "~1")
292 len = changed && isObject(target[key]) && changed.length
293 if (undef != val) {
294 target[key] = mergePatch(target[key], val, changed, previous, nextPointer)
295 }
296 if (len === false || changed && len != changed.length) {
297 changed.push(nextPointer)
298 if (previous && !isObject(oldVal)) {
299 previous[nextPointer] = oldVal
300 }
301 }
302 }
303 } else {
304 if (changed && isObject(target)) {
305 val = {}
306 for (key in target) if (hasOwn.call(target, key)) {
307 val[key] = null
308 }
309 mergePatch(target, val, changed, previous, pointer)
310 }
311 target = patch
312 }
313 return target
314 }
315
316 function clone(obj) {
317 var temp, key
318 if (obj && typeof obj == "object") {
319 // new Date().constructor() returns a string
320 temp = obj instanceof Date ? new Date(+obj) :
321 obj instanceof RegExp ? RegExp(obj.source, (""+obj).split("/").pop()) :
322 obj.constructor()
323 for (key in obj) if (hasOwn.call(obj, key)) {
324 temp[key] = clone(obj[key])
325 }
326 obj = temp
327 }
328 return obj
329 }
330
331 function isObject(obj) {
332 return !!obj && obj.constructor === Object
333 }
334
335// `this` refers to the `window` in browser and to the `exports` in Node.js.
336}(this.JSON || this)
337!function(F) {
338 // Time to live - Run *onTimeout* if Function not called on time
339 F.ttl = function(ms, onTimeout, scope) {
340 var fn = this
341 , tick = setTimeout(function() {
342 ms = 0
343 if (onTimeout) onTimeout()
344 }, ms)
345
346 return function() {
347 clearTimeout(tick)
348 if (ms) fn.apply(scope, arguments)
349 }
350 }
351
352 // Run Function one time after last call
353 F.once = function(ms, scope) {
354 var tick, args
355 , fn = this
356 return function() {
357 clearTimeout(tick)
358 args = arguments
359 tick = setTimeout(function() {
360 fn.apply(scope, args)
361 }, ms)
362 }
363 }
364
365 // Maximum call rate for Function
366 // leading edge, trailing edge
367 F.rate = function(ms, last_call, _scope) {
368 var tick, args
369 , fn = this
370 , scope = _scope
371 , next = 0
372 return function() {
373 var now = Date.now()
374 clearTimeout(tick)
375 if (_scope === void 0) scope = this
376 if (now >= next) {
377 next = now + ms
378 fn.apply(scope, arguments)
379 } else if (last_call) {
380 args = arguments
381 tick = setTimeout(function() {
382 fn.apply(scope, args)
383 }, next - now)
384 }
385 }
386 }
387}(Function.prototype)
388!function(exports, Object) {
389 var undef
390 , P = "prototype"
391 , A = Array[P]
392 , F = Function[P]
393 , S = String[P]
394 , N = Number[P]
395 , slice = F.call.bind(A.slice)
396 , fns = {}
397 , hasOwn = fns.hasOwnProperty
398 , fnRe = /('|")(?:\\?.)*?\1|\/(?:\\?.)+?\/[gim]*|\b(?:false|in|new|null|this|true|typeof|void|function|var|if)\b|\.\w+|\w+:/g
399 , formatRe = /{(?!\\)((?:("|')(?:\\?.)*?\2|\\}|[^}])*)}/g
400 , numbersRe = /-?\d+\.?\d*/g
401 , wordRe = /\b[a-z_$][\w$]*/ig
402 , unescapeRe = /{\\/g
403
404
405 exports.Fn = Fn
406 Fn.hold = hold
407 Fn.wait = wait
408
409
410 // Function extensions
411 // -------------------
412
413 F.extend = function() {
414 var arg
415 , fn = this
416 , i = 0
417
418 function wrapper() {
419 return fn.apply(this, arguments)
420 }
421
422 for (wrapper[P] = Object.create(fn[P]); arg = arguments[i++]; ) {
423 Object.assign(wrapper[P], arg)
424 }
425 wrapper[P].constructor = wrapper
426 return wrapper
427 }
428
429
430 // Non-standard
431 Object.each = function(obj, fn, scope, key) {
432 if (obj) for (key in obj) {
433 hasOwn.call(obj, key) && fn.call(scope, obj[key], key, obj)
434 }
435 }
436
437 // Chrome54, FF47, Edge14, Safari10.1
438 Object.values = function(obj) {
439 return Object.keys(obj || {}).map(function(e) {
440 return obj[e]
441 })
442 }
443
444 // Non-standard
445 // IE<9 bug: [1,2].splice(0).join("") == "" but should be "12"
446 A.remove = arrayRemove
447 function arrayRemove() {
448 var arr = this
449 , len = arr.length
450 , o = slice(arguments)
451 , lastId = -1
452
453 for (; len--; ) if (~o.indexOf(arr[len])) {
454 arr.splice(lastId = len, 1)
455 }
456 return lastId
457 }
458
459 A.each = A.forEach
460 // uniq
461 // first item preserved
462 A.uniq = function() {
463 for (var a = this, i = a.length; i--; ) {
464 if (a.indexOf(a[i]) !== i) a.splice(i, 1)
465 }
466 return a
467 }
468
469 A.pushUniq = function(item) {
470 return this.indexOf(item) < 0 && this.push(item)
471 }
472
473 // THANKS: Oliver Steele - Functional Javascript [http://www.osteele.com/sources/javascript/functional/]
474 function Fn(expr /*, scope, mask1, ..maskN */) {
475 var args = []
476 , arr = expr.match(/[^"']+?->|[\s\S]+$/g)
477 , scope = slice(arguments, 1)
478 , key = scope.length + ":" + expr
479 , fn = fns[key]
480
481 if (!fn) {
482 fn = expr.replace(fnRe, "").match(wordRe) || []
483 for (; arr.length > 1; ) {
484 expr = arr.pop()
485 args = arr.pop().match(/\w+/g) || []
486 arrayRemove.apply(fn, args)
487 if (arr.length) {
488 arr.push("function(" + args + "){return(" + expr + ")}" + (scope[0] ? ".bind(this)" : ""))
489 }
490 }
491 expr = "return(" + expr + ")"
492
493 if (scope[0]) {
494 arr = Object.keys(scope).map(Fn("a->'__'+a"))
495 arr[0] = "this"
496 expr = (
497 fn[0] ?
498 "var " + fn.uniq().join("='',") + "='';" :
499 ""
500 ) + "with(" + arr.join(")with(") + "){" + expr + "}"
501 args = arr.slice(1).concat(args)
502 }
503
504 fn = fns[key] = Function(args, expr)
505 }
506
507 return scope.length ? fn.bind.apply(fn, scope) : fn
508 }
509
510 Fn.keys = function(str) {
511 var i, tmp
512 , arr = []
513 , match = str.match(formatRe)
514 if (match) {
515 for (i = match.length; i--; ) {
516 if (tmp = match[i].replace(fnRe, "").match(wordRe)) {
517 arr.push.apply(arr, tmp)
518 }
519 }
520 }
521 return arr.uniq()
522 }
523
524 S.format = function() {
525 var args = A.slice.call(arguments)
526 args.unshift(0)
527 return this.replace(formatRe, function(_, arg) {
528 args[0] = arg.replace(/\\}/g, "}")
529 return Fn.apply(null, args)()
530 }).replace(unescapeRe, "{")
531 }
532
533 N.format = function(data) {
534 return "" + this
535 }
536
537 S.safe = function() {
538 return this
539 .replace(/&/g, "&amp;")
540 .replace(/</g, "&lt;")
541 .replace(/>/g, "&gt;")
542 .replace(/\"/g, "&quot;")
543 }
544
545 S.capitalize = function() {
546 return this.charAt(0).toUpperCase() + this.slice(1)
547 }
548
549 S.lower = S.toLowerCase
550 S.upper = S.toUpperCase
551
552 N.step = function(a, add) {
553 var x = ("" + a).split(".")
554 , steps = this / a
555 , n = ~~(steps + ((steps < 0 ? -1 : 1) * (add == undef ? .5 : add === 1 && steps == (steps|0) ? 0 : +add))) * a
556 return "" + (1 in x ? n.toFixed(x[1].length) : n)
557 }
558
559 S.step = function(a, add) {
560 return this.replace(numbersRe, function(num) {
561 return (+num).step(a, add)
562 })
563 }
564
565 N.scale = words([1000, 1000, 1000], ["","k","M","G"], {"default": "{n}{u}"})
566
567 S.scale = function() {
568 return this.replace(numbersRe, function(num) {
569 return (+num).scale()
570 })
571 }
572
573 S.pick = N.pick = function() {
574 var val = this + "="
575 for (var s, a = arguments, i = 0, len = a.length; i < len;) {
576 s = a[i++]
577 if (s.indexOf(val) == 0) {
578 s = s.slice(val.length)
579 i = len
580 }
581 }
582 return s.replace("#", this)
583 }
584
585 S.plural = N.plural = function() {
586 // Plural-Forms: nplurals=2; plural=n != 1;
587 // http://www.gnu.org/software/gettext/manual/html_mono/gettext.html#Plural-forms
588 return arguments[ +Fn("n->" + (String.plural || "n!=1"))( parseFloat(this) ) ].replace("#", this)
589 }
590
591 A.pluck = function(name) {
592 for (var arr = this, i = arr.length, out = []; i--; ) {
593 out[i] = arr[i][name]
594 }
595 return out
596 }
597
598 function words(steps, units, strings, overflow) {
599 return function(input) {
600 var n = +(arguments.length ? input : this)
601 , i = 0
602 , s = strings || {"default": "{n} {u}{s}"}
603
604 for (; n>=steps[i]; ) {
605 n /= steps[i++]
606 }
607 if (i == steps.length && overflow) {
608 return overflow(this)
609 }
610 i = units[i]
611 return (s[n < 2 ? i : i + "s"] || s["default"]).format({n: n, u: i, s: n < 2 ? "" : "s"})
612 }
613 }
614 Fn.words = words
615
616 function wait(fn) {
617 var pending = 1
618 function resume() {
619 if (!--pending && fn) fn.call(this)
620 }
621 resume.wait = function() {
622 pending++
623 return resume
624 }
625 return resume
626 }
627
628 function hold(ignore) {
629 var k
630 , obj = this
631 , hooks = []
632 , hooked = []
633 , _resume = wait(resume)
634 ignore = ignore || obj.syncMethods || []
635
636 for (k in obj) if (typeof obj[k] == "function" && ignore.indexOf(k) == -1) !function(k) {
637 hooked.push(k, hasOwn.call(obj, k) && obj[k])
638 obj[k] = function() {
639 hooks.push(k, arguments)
640 return obj
641 }
642 }(k)
643
644 /**
645 * `wait` is already in hooked array,
646 * so override hooked method
647 * that will be cleared on resume.
648 */
649 obj.wait = _resume.wait
650
651 return _resume
652
653 function resume() {
654 for (var v, scope = obj, i = hooked.length; i--; i--) {
655 if (hooked[i]) obj[hooked[i-1]] = hooked[i]
656 else delete obj[hooked[i-1]]
657 }
658 // i == -1 from previous loop
659 for (; v = hooks[++i]; ) {
660 scope = scope[v].apply(scope, hooks[++i]) || scope
661 }
662 hooks = hooked = null
663 }
664 }
665
666}(this, Object)
667!function(exports) {
668 var empty = []
669
670 exports.Emitter = EventEmitter
671 exports.asEmitter = asEmitter
672
673 function EventEmitter() {}
674
675 function asEmitter(obj) {
676 obj.on = on
677 obj.off = off
678 obj.one = one
679 obj.emit = emit
680 obj.listen = listen
681 obj.unlisten = unlisten
682 }
683 asEmitter(EventEmitter.prototype)
684
685 function on(type, fn, scope, _origin) {
686 var emitter = this === exports ? empty : this
687 , events = emitter._e || (emitter._e = Object.create(null))
688 if (type && fn) {
689 if (typeof fn === "string") fn = emit.bind(null, fn)
690 emit.call(emitter, "newListener", type, fn, scope, _origin)
691 ;(events[type] || (events[type] = [])).unshift(scope, _origin, fn)
692 }
693 return emitter
694 }
695
696 function off(type, fn, scope) {
697 var i, args
698 , emitter = this === exports ? empty : this
699 , events = emitter._e && emitter._e[type]
700 if (events) {
701 for (i = events.length - 2; i > 0; i -= 3) {
702 if ((events[i + 1] === fn || events[i] === fn) && events[i - 1] == scope) {
703 args = events.splice(i - 1, 3)
704 emit.call(emitter, "removeListener", type, args[2], args[0], args[1])
705 if (fn) break
706 }
707 }
708 }
709 return emitter
710 }
711
712 function one(type, fn, scope) {
713 var emitter = this === exports ? empty : this
714 function remove() {
715 emitter.off(type, fn, scope).off(type, remove, scope)
716 }
717 return emitter.on(type, remove, scope).on(type, fn, scope)
718 }
719
720 // emitNext
721 // emitLate
722
723 function emit(type) {
724 var args, i
725 , emitter = this === exports ? empty : this
726 , _e = emitter._e
727 , arr = _e ? (_e[type] || empty).concat(_e["*"] || empty) : empty
728 _e = 0
729 if (i = arr.length) {
730 for (args = arr.slice.call(arguments, 1); i--; ) {
731 arr[i--].apply(arr[--i] || emitter, args)
732 _e++
733 }
734 }
735 return _e
736 }
737
738 function listen(emitter, ev, fn, scope, _origin) {
739 if (emitter) {
740 emitter.on(ev, fn, scope)
741 ;(this._l || (this._l = [])).push([emitter, ev, fn, scope, _origin])
742 }
743 return this
744 }
745
746 function unlisten(key) {
747 var a, i
748 , listening = this._l
749 if (listening) for (i = listening.length; i--; ) {
750 a = listening[i]
751 if (key === "*" || a.indexOf(key) > -1) {
752 listening.splice(i, 1)
753 a[0].off(a[1], a[2], a[3])
754 }
755 }
756 return this
757 }
758
759// `this` refers to the `window` in browser and to the `exports` in Node.js.
760}(this.Event || this)
761/* litejs.com/MIT-LICENSE.txt */
762
763
764
765!function(window, document, history, location) {
766 var cb, base, lastRoute, iframe, tick, last
767 , cleanRe = /^[#\/\!]+|[\s\/]+$/g
768
769 // The JScript engine used in IE doesn't recognize vertical tabulation character
770 // http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
771 // oldIE = "\v" == "v"
772 //
773 // The documentMode is an IE only property, supported in IE8+.
774 //
775 // Starting in Internet Explorer 9 standards mode, Internet Explorer 10 standards mode,
776 // and win8_appname_long apps, you cannot identify the browser as Internet Explorer
777 // by testing for the equivalence of the vertical tab (\v) and the "v".
778 // In earlier versions, the expression "\v" === "v" returns true.
779 // In Internet Explorer 9 standards mode, Internet Explorer 10 standards mode,
780 // and win8_appname_long apps, the expression returns false.
781 , ie6_7 = !+"\v1" && (document.documentMode | 0) < 8
782
783 function getUrl(_loc) {
784 var url
785 /*** PUSH ***/
786 if (base) {
787 url = location.pathname.slice(base.length)
788 } else {
789 /**/
790 // bug in Firefox where location.hash is decoded
791 // bug in Safari where location.pathname is decoded
792
793 // var hash = location.href.split('#')[1] || '';
794 // https://bugs.webkit.org/show_bug.cgi?id=30225
795 // https://github.com/documentcloud/backbone/pull/967
796 url = (_loc || location).href.split("#")[1] || ""
797 /*** PUSH ***/
798 }
799 /**/
800 return url.replace(cleanRe, "")
801 }
802
803 function setUrl(url, replace) {
804 /*** PUSH ***/
805 if (base) {
806 history[replace ? "replaceState" : "pushState"](null, null, base + url)
807 } else {
808 /**/
809 location[replace ? "replace" : "assign"]("#" + url)
810 // Opening and closing the iframe tricks IE7 and earlier
811 // to push a history entry on hash-tag change.
812 if (iframe && getUrl() !== getUrl(iframe.location) ) {
813 iframe.location[replace ? "replace" : iframe.document.open().close(), "assign"]("#" + url)
814 }
815 /*** PUSH ***/
816 }
817 /**/
818 checkUrl()
819 }
820
821 function checkUrl() {
822 if (lastRoute != (lastRoute = getUrl()) && cb) {
823 cb(lastRoute)
824 }
825 }
826
827 history.getUrl = getUrl
828 history.setUrl = setUrl
829
830 history.start = function(_cb) {
831 cb = _cb
832 /*** PUSH ***/
833 // Chrome5, Firefox4, IE10, Safari5, Opera11.50
834 var url
835 , _base = document.documentElement.getElementsByTagName("base")[0]
836 if (_base) _base = _base.href.replace(/.*:\/\/[^/]*|[^\/]*$/g, "")
837 if (_base && !history.pushState) {
838 url = location.pathname.slice(_base.length)
839 if (url) {
840 location.replace(_base + "#" + url)
841 }
842 }
843 if (_base && history.pushState) {
844 base = _base
845
846 url = location.href.split("#")[1]
847 if (url && !getUrl()) {
848 setUrl(url, 1)
849 }
850
851 // Chrome and Safari emit a popstate event on page load, Firefox doesn't.
852 // Firing popstate after onload is as designed.
853 //
854 // See the discussion on https://bugs.webkit.org/show_bug.cgi?id=41372,
855 // https://code.google.com/p/chromium/issues/detail?id=63040
856 // and the change to the HTML5 spec that was made:
857 // http://html5.org/tools/web-apps-tracker?from=5345&to=5346.
858 window.onpopstate = checkUrl
859 } else
860 /**/
861 if ("onhashchange" in window && !ie6_7) {
862 // There are onhashchange in IE7 but its not get emitted
863 //
864 // Basic support:
865 // Chrome 5.0, Firefox 3.6, IE 8, Opera 10.6, Safari 5.0
866 window.onhashchange = checkUrl
867 } else {
868 if (ie6_7 && !iframe) {
869 // IE<9 encounters the Mixed Content warning when the URI javascript: is used.
870 // IE5/6 additionally encounters the Mixed Content warning when the URI about:blank is used.
871 // src="//:"
872 iframe = document.body.appendChild(document.createElement('<iframe class="hide" tabindex="-1">')).contentWindow
873 }
874 clearInterval(tick)
875 tick = setInterval(function(){
876 var cur = getUrl()
877 if (iframe && last === cur) cur = getUrl(iframe.location)
878 if (last !== cur) {
879 last = cur
880 iframe ? setUrl(cur) : checkUrl()
881 }
882 }, 60)
883 }
884 checkUrl()
885 }
886}(this, document, history, location)
887/* litejs.com/MIT-LICENSE.txt */
888
889
890
891!function(exports) {
892 var fn, lastView, lastParams, lastStr, lastUrl, syncResume
893 , isArray = Array.isArray
894 , capture = 1
895 , fnStr = ""
896 , reStr = ""
897 , views = View.views = {}
898 , paramCb = {}
899 , hasOwn = views.hasOwnProperty
900 , escapeRe = /[.*+?^=!:${}()|\[\]\/\\]/g
901 , parseRe = /\{([\w%.]+?)\}|.[^{\\]*?/g
902
903 exports.View = View
904
905 function View(route, el, parent) {
906 var view = views[route]
907 if (view) {
908 if (el) {
909 view.el = el
910 view.parent = parent && View(parent)
911 }
912 return view
913 }
914 view = this
915 if (!(view instanceof View)) return new View(route, el, parent)
916 views[view.route = route] = view
917 view.el = el
918 view.parent = parent && View(parent)
919
920 if (route.charAt(0) != "#") {
921 var params = "m[" + (view.seq = capture++) + "]?("
922 , _re = route.replace(parseRe, function(_, key) {
923 return key ?
924 (params += "o['" + key + "']=m[" + (capture++) + "],") && "([^/]+?)" :
925 _.replace(escapeRe, "\\$&")
926 })
927
928 fnStr += params + "'" + route + "'):"
929 reStr += (reStr ? "|(" : "(") + _re + ")"
930 fn = 0
931 }
932 }
933
934 View.prototype = {
935 show: function(_params) {
936 var parent
937 , params = lastParams = _params || {}
938 , view = lastView = this
939 , tmp = params._v || view
940 , close = view.isOpen && view
941
942 View.active = view.route
943
944 for (; tmp; tmp = parent) {
945 syncResume = params._v = tmp
946 tmp.emit("ping", params)
947 syncResume = null
948 if (lastParams != params) return
949 if (parent = tmp.parent) {
950 if (parent.child && parent.child != tmp) {
951 close = parent.child
952 }
953 parent.child = tmp
954 }
955 if (!tmp.el) {
956 if (tmp.file) {
957 xhr.load(
958 tmp.file
959 .replace(/^|,/g, "$&" + (View.base || ""))
960 .split(","),
961 view.wait()
962 )
963 tmp.file = null
964 } else {
965 View("404").show(Object.assign({}, params))
966 }
967 return
968 }
969 }
970
971 for (tmp in params) if (tmp.charAt(0) != "_") {
972 if (syncResume = hasOwn.call(paramCb, tmp) && paramCb[tmp] || paramCb["*"]) {
973 syncResume.call(view, params[tmp], tmp, params)
974 syncResume = null
975 }
976 }
977
978 bubbleDown(params, close)
979 },
980 wait: function() {
981 var params = lastParams
982 params._p = 1 + (params._p | 0)
983 return function() {
984 if (--params._p || lastParams != params || syncResume) return
985 if (params._d) {
986 bubbleDown(params)
987 } else if (params._v) {
988 lastView.show(params)
989 }
990 }
991 }
992 }
993
994 function bubbleDown(params, close) {
995 var tmp
996 , view = params._v
997 , parent = view && view.parent
998 if (!view || params._p && /{/.test(view.route)) {
999 return closeView(close)
1000 }
1001 if (parent && !view.isOpen || view === close) {
1002 closeView(close, view)
1003 El.scope(
1004 view.isOpen = view.el.cloneNode(true),
1005 El.scope(tmp = parent.isOpen || parent.el)
1006 )
1007 El.append(tmp, view.isOpen)
1008 El.render(view.isOpen)
1009 parent.emit("openChild", view, close)
1010 view.emit("open", params)
1011 View.emit("open", params, view)
1012 if (view.kb) El.addKb(view.kb)
1013 close = null
1014 }
1015 if (params._d = params._v = view.child) {
1016 bubbleDown(params, close)
1017 }
1018 if (lastView == view) {
1019 view.emit("show", params)
1020 View.emit("show", params, view)
1021 blur()
1022 }
1023 }
1024
1025 function closeView(view, open) {
1026 if (view && view.isOpen) {
1027 view.parent.emit("closeChild", view, open)
1028 closeView(view.child)
1029 El.kill(view.isOpen)
1030 view.isOpen = null
1031 if (view.kb) El.rmKb(view.kb)
1032 view.emit("close")
1033 }
1034 }
1035
1036 Event.asEmitter(View)
1037 Event.asEmitter(View.prototype)
1038
1039 View.base = "view/"
1040 View.home = "home"
1041
1042 View.get = get
1043 function get(url, params) {
1044 if (!fn) {
1045 fn = Function(
1046 "var r=/^\\/?(?:" + reStr + ")[\\/\\s]*$/;" +
1047 "return function(i,o,d){var m=r.exec(i);return m!==null?(" + fnStr + "d):d}"
1048 )()
1049 }
1050 return View(fn(url || View.home, params || {}, "404"))
1051 }
1052
1053 View.show = function(url, _params) {
1054 if (url === true) {
1055 url = lastUrl
1056 lastUrl = 0
1057 }
1058 var params = _params || {}
1059 , view = get(url, params)
1060 if (!view.isOpen || lastUrl != url) {
1061 params._u = lastUrl = url
1062 view.show(El.data.route = params)
1063 }
1064 }
1065
1066 View.param = function(name, cb, re) {
1067 ;(isArray(name) ? name : name.split(/\s+/)).forEach(function(n) {
1068 paramCb[n] = cb
1069 })
1070 }
1071
1072 View.def = function(str) {
1073 for (var match, re = /(\S+) (\S+)/g; match = re.exec(str);) {
1074 match[1].split(",").map(function(view) {
1075 view = View(defMap(view, lastStr))
1076 view.file = (view.file ? view.file + "," : "") +
1077 match[2].split(",").map(function(file) {
1078 return views[file] ? views[file].file : defMap(file, lastStr)
1079 })
1080 })
1081 }
1082 }
1083
1084 View.blur = blur
1085 function blur() {
1086 // When a View completes, blur focused link
1087 // IE8 can throw an exception for document.activeElement.
1088 try {
1089 var el = document.activeElement
1090 , tag = el && el.tagName
1091 if (tag === "A" || tag === "BUTTON") el.blur()
1092 } catch(e) {}
1093 }
1094
1095 View.url = defMap
1096 function defMap(str, _last) {
1097 var chr = str.charAt(0)
1098 , slice = str.slice(1)
1099 , last = _last || lastUrl
1100 return (
1101 chr === "+" ? last + slice :
1102 chr === "%" ? ((chr = last.lastIndexOf(slice.charAt(0))), (chr > 0 ? last.slice(0, chr) : last)) + slice :
1103 (lastStr = str)
1104 )
1105 }
1106
1107}(this)
1108/* litejs.com/MIT-LICENSE.txt */
1109
1110
1111
1112!function(window, document, Object, Event, protoStr) {
1113 var currentLang, styleNode
1114 , BIND_ATTR = "data-bind"
1115 , isArray = Array.isArray
1116 , seq = 0
1117 , elCache = El.cache = {}
1118 , wrapProto = []
1119 , slice = wrapProto.slice
1120 , hasOwn = elCache.hasOwnProperty
1121 , body = document.body
1122 , root = document.documentElement
1123 , txtAttr = El.T = "textContent" in body ? "textContent" : "innerText"
1124 , templateRe = /^([ \t]*)(@?)((?:("|')(?:\\?.)*?\4|[-\w:.#[\]]=?)*)[ \t]*([>&^|\\\/=]?)(([\])}]?).*?([[({]?))$/gm
1125 , renderRe = /[;\s]*(\w+)(?:\s*(:?):((?:(["'\/])(?:\\?.)*?\3|[^;])*))?/g
1126 , splitRe = /[,\s]+/
1127 , camelRe = /\-([a-z])/g
1128 , camelFn = function(_, a) {
1129 return a.toUpperCase()
1130 }
1131 , bindings = El.bindings = {
1132 attr: setAttr,
1133 cls: El.cls = acceptMany(cls),
1134 css: El.css = acceptMany(function(el, key, val) {
1135 el.style[key.replace(camelRe, camelFn)] = "" + val || ""
1136 }, function(el, key) {
1137 return getComputedStyle(el).getPropertyValue(key)
1138 }),
1139 data: function(el, key, val) {
1140 setAttr(el, "data-" + key, val)
1141 },
1142 html: function(el, html) {
1143 el.innerHTML = html
1144 },
1145 ref: function(el, name) {
1146 this[name] = el
1147 },
1148 txt: El.txt = function(el, txt) {
1149 // In Safari 2.x, innerText results an empty string
1150 // when style.display=="none" or node is not in dom
1151 //
1152 // innerText is implemented in IE4, textContent in IE9
1153 // Opera 9-10 have Node.text
1154
1155 if (el[txtAttr] !== txt) el[txtAttr] = txt
1156 },
1157 val: function(el, txt) {
1158 valFn(el, txt)
1159 },
1160 "with": function(el, map) {
1161 var scope = elScope(el, this)
1162 Object.assign(scope, map)
1163 if (scope !== this) {
1164 render(el)
1165 return true
1166 }
1167 }
1168 }
1169 , bindMatch = []
1170 , scopeData = El.data = {
1171 _: i18n,
1172 _b: bindings,
1173 El: El,
1174 history: history,
1175 View: View
1176 }
1177
1178 /*** ie8 ***/
1179
1180 // JScript engine in IE<9 does not recognize vertical tabulation character
1181 , ie678 = !+"\v1"
1182 , ie67 = ie678 && (document.documentMode | 0) < 8
1183
1184 , matches = El.matches = body.matches ?
1185 function(el, sel) {
1186 return el && el.matches(sel)
1187 } :
1188 function(el, sel) {
1189 return !!selectorFn(sel)(el)
1190 }
1191 , closest = El.closest = body.closest ?
1192 function(el, sel) {
1193 return (el.closest ? el : el.parentNode).closest(sel)
1194 } :
1195 function(el, sel) {
1196 return walk("parentNode", 1, el, sel)
1197 }
1198
1199
1200 , selectorRe = /([.#:[])([-\w]+)(?:\((.+?)\)|([~^$*|]?)=(("|')(?:\\?.)*?\6|[-\w]+))?]?/g
1201 , selectorLastRe = /([~\s>+]*)(?:("|')(?:\\?.)*?\2|\(.+?\)|[^\s+>])+$/
1202 , selectorSplitRe = /\s*,\s*(?=(?:[^'"()]|"(?:\\?.)*?"|'(?:\\?.)*?'|\(.+?\))+$)/
1203 , selectorCache = {}
1204 , selectorMap = {
1205 "first-child": "(a=_.parentNode)&&a.firstChild==_",
1206 "last-child": "(a=_.parentNode)&&a.lastChild==_",
1207 ".": "~_.className.split(/\\s+/).indexOf(a)",
1208 "#": "_.id==a",
1209 "^": "!a.indexOf(v)",
1210 "|": "a.split('-')[0]==v",
1211 "$": "a.slice(-v.length)==v",
1212 "~": "~a.split(/\\s+/).indexOf(v)",
1213 "*": "~a.indexOf(v)"
1214 }
1215
1216 function selectorFn(str) {
1217 // jshint evil:true
1218 return selectorCache[str] ||
1219 (selectorCache[str] = Function("m,c", "return function(_,v,a,b){return " +
1220 str.split(selectorSplitRe).map(function(sel) {
1221 var relation, from
1222 , rules = ["_&&_.nodeType==1"]
1223 , parentSel = sel.replace(selectorLastRe, function(_, _rel, a, start) {
1224 from = start + _rel.length
1225 relation = _rel.trim()
1226 return ""
1227 })
1228 , tag = sel.slice(from).replace(selectorRe, function(_, op, key, subSel, fn, val, quotation) {
1229 rules.push(
1230 "((v='" +
1231 (subSel || (quotation ? val.slice(1, -1) : val) || "").replace(/'/g, "\\'") +
1232 "'),(a='" + key + "'),1)"
1233 ,
1234 selectorMap[op == ":" ? key : op] ||
1235 "(a=_.getAttribute(a))" +
1236 (fn ? "&&" + selectorMap[fn] : val ? "==v" : "")
1237 )
1238 return ""
1239 })
1240
1241 if (tag && tag != "*") rules[0] += "&&_.tagName=='" + tag.toUpperCase() + "'"
1242 if (parentSel) rules.push("(v='" + parentSel + "')", selectorMap[relation + relation])
1243 return rules.join("&&")
1244 }).join("||") + "}"
1245 )(matches, closest))
1246 }
1247
1248 function walk(next, first, el, sel, nextFn) {
1249 var out = []
1250 if (typeof sel !== "function") sel = selectorFn(sel)
1251 for (; el; el = el[next] || nextFn && nextFn(el)) if (sel(el)) {
1252 if (first) return el
1253 out.push(el)
1254 }
1255 return first ? null : out
1256 }
1257
1258 function find(node, sel, first) {
1259 return walk("firstChild", first, node.firstChild, sel, function(el) {
1260 var next = el.nextSibling
1261 while (!next && ((el = el.parentNode) !== node)) next = el.nextSibling
1262 return next
1263 })
1264 }
1265
1266 // Note: querySelector in IE8 supports only CSS 2.1 selectors
1267 if (!ie678 && body.querySelector) {
1268 El.find = function(el, sel) {
1269 return el.querySelector(sel)
1270 }
1271 El.findAll = function(el, sel) {
1272 return new ElWrap(el.querySelectorAll(sel))
1273 }
1274 } else {
1275 El.find = function(el, sel) {
1276 return find(el, sel, true)
1277 }
1278 El.findAll = function(el, sel) {
1279 return new ElWrap(find(el, sel))
1280 }
1281 }
1282
1283 /*/
1284 El.matches = function(el, sel) {
1285 return el.matches(sel)
1286 }
1287 El.closest = function(el, sel) {
1288 return (el.closest ? el : el.parentNode).closest(sel)
1289 }
1290 El.find = function(el, sel) {
1291 return el.querySelector(sel)
1292 }
1293 El.findAll = function(el, sel) {
1294 return new ElWrap(el.querySelectorAll(sel))
1295 }
1296 /**/
1297
1298 /**
1299 * Turns CSS selector like syntax to DOM Node
1300 * @returns {Node}
1301 *
1302 * @example
1303 * El("input#12.nice[type=checkbox]:checked:disabled[data-lang=en].class")
1304 * <input id="12" class="nice class" type="checkbox" checked="checked" disabled="disabled" data-lang="en">
1305 */
1306
1307 window.El = El
1308
1309 function El(name) {
1310 if (typeof name != "string") {
1311 return new ElWrap(name)
1312 }
1313 var el, pres
1314 , pre = {}
1315 name = name.replace(selectorRe, function(_, op, key, _sub, fn, val, quotation) {
1316 pres = 1
1317 val = quotation ? val.slice(1, -1) : val || key
1318 pre[op =
1319 op == "." ?
1320 (fn = "~", "class") :
1321 op == "#" ?
1322 "id" :
1323 key
1324 ] = fn && pre[op] ?
1325 fn == "^" ? val + pre[op] :
1326 pre[op] + (fn == "~" ? " " : "") + val :
1327 val
1328 return ""
1329 }) || "div"
1330
1331 // NOTE: IE-s cloneNode consolidates the two text nodes together as one
1332 // http://brooknovak.wordpress.com/2009/08/23/ies-clonenode-doesnt-actually-clone/
1333 el = (elCache[name] || (elCache[name] = document.createElement(name))).cloneNode(true)
1334
1335 if (pres) {
1336 setAttr(el, pre)
1337 }
1338
1339 return el
1340 }
1341
1342 function ElWrap(nodes) {
1343 var wrap = this
1344 , i = nodes.length
1345 /**
1346 * 1. Extended array size will not updated
1347 * when array elements set directly in Android 2.2.
1348 */
1349 if (i) {
1350 wrap.length = i /* 1 */
1351 for (; i--; ) {
1352 wrap[i] = nodes[i]
1353 }
1354 } else if (i == null) {
1355 wrap.length = 1 /* 1 */
1356 wrap[0] = nodes
1357 }
1358 }
1359
1360 ElWrap[protoStr] = wrapProto
1361
1362 wrapProto.append = function(el) {
1363 var elWrap = this
1364 if (elWrap._childId != void 0) {
1365 append(elWrap[elWrap._childId], el)
1366 } else {
1367 elWrap.push(el)
1368 }
1369 return elWrap
1370 }
1371
1372 wrapProto.cloneNode = function(deep) {
1373 var clone = new ElWrap(this.map(function(el) {
1374 return el.cloneNode(deep)
1375 }))
1376 clone._childId = this._childId
1377 return clone
1378 }
1379
1380
1381 El.attr = function(el, key, val) {
1382 return arguments.length < 3 && key.constructor != Object ? getAttr(el, key) : setAttr(el, key, val)
1383 }
1384
1385 function getAttr(el, key) {
1386 return el && el.getAttribute && el.getAttribute(key)
1387 }
1388
1389 function setAttr(el, key, val) {
1390 var current
1391
1392 if (key && key.constructor == Object) {
1393 for (current in key) {
1394 setAttr(el, current, key[current])
1395 }
1396 return
1397 }
1398
1399 /* Accept namespaced arguments
1400 var namespaces = {
1401 xlink: "http://www.w3.org/1999/xlink",
1402 svg: "http://www.w3.org/2000/svg"
1403 }
1404
1405 current = key.split("|")
1406 if (current[1]) {
1407 el.setAttributeNS(namespaces[current[0]], current[1], val)
1408 return
1409 }
1410 */
1411
1412 current = el.getAttribute(key)
1413
1414 // Note: IE5-7 doesn't set styles and removes events when you try to set them.
1415 //
1416 // in IE6, a label with a for attribute linked to a select list
1417 // will cause a re-selection of the first option instead of just giving focus.
1418 // http://webbugtrack.blogspot.com/2007/09/bug-116-for-attribute-woes-in-ie6.html
1419
1420 // there are bug in IE<9 where changed 'name' param not accepted on form submit
1421 // IE8 and below support document.createElement('<P>')
1422 //
1423 // http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/
1424 // http://msdn.microsoft.com/en-us/library/ms536614(VS.85).aspx
1425
1426 /*** ie8 ***/
1427 // istanbul ignore next: IE fix
1428 if (ie67 && (key == "id" || key == "name" || key == "checked")) {
1429 el.mergeAttributes(document.createElement('<INPUT ' + key + '="' + val + '">'), false)
1430 } else
1431 /**/
1432 if (key == "class") {
1433 cls(el, val)
1434 } else if (val || val === 0) {
1435 if (current != val) {
1436 el.setAttribute(key, val)
1437 }
1438 } else if (current) {
1439 el.removeAttribute(key)
1440 }
1441 }
1442
1443 El.val = valFn
1444 function valFn(el, val) {
1445 var input, step, key, value
1446 , i = 0
1447 , type = el.type
1448 , opts = el.options
1449 , checkbox = type === "checkbox" || type === "radio"
1450
1451 if (el.tagName === "FORM") {
1452 opts = {}
1453
1454 // Disabled controls do not receive focus,
1455 // are skipped in tabbing navigation, cannot be successfully posted.
1456 //
1457 // Read-only elements receive focus but cannot be modified by the user,
1458 // are included in tabbing navigation, are successfully posted.
1459 //
1460 // Read-only checkboxes can be changed by the user
1461
1462 for (; input = el.elements[i++]; ) if (!input.disabled && (key = input.name || input.id)) {
1463 value = valFn(input)
1464 if (value !== void 0) {
1465 step = opts
1466 key.replace(/\[(.*?)\]/g, function(_, _key, offset) {
1467 if (step == opts) key = key.slice(0, offset)
1468 step = step[key] || (step[key] = _key && +_key != _key ? {} : [])
1469 key = _key
1470 })
1471 step[key || step.length] = value
1472 }
1473 }
1474
1475 return opts
1476 }
1477
1478 if (arguments.length > 1) {
1479 if (opts) {
1480 value = (isArray(val) ? val : [ val ]).map(String)
1481 for (; input = opts[i++]; ) {
1482 input.selected = value.indexOf(input.value) > -1
1483 }
1484 } else {
1485 checkbox ? (el.checked = !!val) : (el.value = val)
1486 }
1487 return
1488 }
1489
1490 if (opts) {
1491 if (type === "select-multiple") {
1492 for (val = []; input = opts[i++]; ) {
1493 if (input.selected && !input.disabled) {
1494 val.push(input.valObject || input.value)
1495 }
1496 }
1497 return val
1498 }
1499 // IE8 throws error when accessing to options[-1]
1500 value = el.selectedIndex
1501 el = value > -1 && opts[value] || el
1502 }
1503
1504 return checkbox && !el.checked ?
1505 (type === "radio" ? void 0 : null) :
1506 el.valObject || el.value
1507 }
1508
1509 function append(el, child, before) {
1510 if (!el.nodeType) {
1511 return el.append ? el.append(child, before) : el
1512 }
1513 var fragment
1514 , i = 0
1515 , tmp = typeof child
1516 if (child) {
1517 if (tmp == "string" || tmp == "number") child = document.createTextNode(child)
1518 else if ( !("nodeType" in child) && "length" in child ) {
1519 // document.createDocumentFragment is unsupported in IE5.5
1520 // fragment = "createDocumentFragment" in document ? document.createDocumentFragment() : El("div")
1521 for (
1522 tmp = child.length
1523 , fragment = document.createDocumentFragment();
1524 i < tmp; ) append(fragment, child[i++])
1525 child = fragment
1526 }
1527
1528 if (child.nodeType) {
1529 tmp = el.insertBefore ? el : el[el.length - 1]
1530 if (i = getAttr(tmp, "data-child")) {
1531 before = find(tmp, Fn("v->n->n.nodeType===8&&n.nodeValue==v")(i), 1) || tmp
1532 tmp = before.parentNode
1533 // TODO:2016-07-05:lauri:handle numeric befores
1534 }
1535 /*** debug ***//*
1536 if (tmp.namespaceURI && child.namespaceURI && tmp.namespaceURI !== child.namespaceURI && child.tagName !== "svg") {
1537 console.error("NAMESPACE CHANGE!", tmp.namespaceURI, child.namespaceURI, child)
1538 }
1539 /**/
1540 tmp.insertBefore(child,
1541 (before === true ? tmp.firstChild :
1542 typeof before == "number" ? tmp.childNodes[
1543 before < 0 ? tmp.childNodes.length - before - 2 : before
1544 ] : before) || null
1545 )
1546 }
1547 }
1548 return el
1549 }
1550
1551 function acceptMany(fn, getter) {
1552 return function f(el, name, val, delay) {
1553 if (el && name) {
1554 if (delay > 0) return setTimeout(f, delay, el, name, val)
1555 if (name.constructor === Object) {
1556 for (i in name) {
1557 if (hasOwn.call(name, i)) f(el, i, name[i])
1558 }
1559 return
1560 }
1561 var names = isArray(name) ? name : name.split(splitRe)
1562 , i = 0
1563 , len = names.length
1564
1565 if (arguments.length < 3) {
1566 if (getter) return getter(el, name)
1567 for (; i < len; ) fn(el, names[i++])
1568 } else {
1569 /*
1570 if (isArray(val)) {
1571 for (; i < len; ) fn(el, names[i], val[i++])
1572 } else {
1573 for (; i < len; ) fn(el, names[i++], val)
1574 }
1575 /*/
1576 for (; i < len; ) {
1577 fn(el, names[i++], isArray(val) ? val[i - 1] : val)
1578 }
1579 //*/
1580 }
1581 }
1582 }
1583 }
1584
1585 // setAttribute("class") is broken in IE7
1586 // className is object in SVGElements
1587
1588 El.hasClass = hasClass
1589 function hasClass(el, name) {
1590 var current = el.className || ""
1591
1592 if (typeof current !== "string") {
1593 current = el.getAttribute("class") || ""
1594 }
1595
1596 return !!current && current.split(splitRe).indexOf(name) > -1
1597 }
1598
1599 function cls(el, name, set) {
1600 var current = el.className || ""
1601 , useAttr = typeof current !== "string"
1602
1603 if (useAttr) {
1604 current = el.getAttribute("class") || ""
1605 }
1606
1607 if (arguments.length < 3 || set) {
1608 if (current) {
1609 name = current.split(splitRe).indexOf(name) > -1 ? current : current + " " + name
1610 }
1611 } else {
1612 name = current ? (" " + current + " ").replace(" " + name + " ", " ").trim() : current
1613 }
1614
1615 if (current != name) {
1616 if (useAttr) {
1617 el.setAttribute("class", name)
1618 } else {
1619 el.className = name
1620 }
1621 }
1622 }
1623
1624 // The addEventListener is supported in Internet Explorer from version 9.
1625 // https://developer.mozilla.org/en-US/docs/Web/Reference/Events/wheel
1626 // - IE8 always prevents the default of the mousewheel event.
1627
1628 var wheelDiff = 120
1629 , addEv = "addEventListener"
1630 , remEv = "removeEventListener"
1631 , prefix = window[addEv] ? "" : (addEv = "attachEvent", remEv = "detachEvent", "on")
1632 , fixEv = Event.fixEv = {
1633 wheel:
1634 "onwheel" in document ? "wheel" : // Modern browsers
1635 "onmousewheel" in document ? "mousewheel" : // Webkit and IE
1636 "DOMMouseScroll" // older Firefox
1637 }
1638 , fixFn = Event.fixFn = {
1639 wheel: function(el, _fn) {
1640 return function(e) {
1641 var delta = (e.wheelDelta || -e.detail || -e.deltaY) / wheelDiff
1642 if (delta) {
1643 if (delta < 1 && delta > -1) {
1644 var diff = (delta < 0 ? -1 : 1)/delta
1645 delta *= diff
1646 wheelDiff /= diff
1647 }
1648 //TODO: fix event
1649 // e.deltaY =
1650 // e.deltaX = - 1/40 * e.wheelDeltaX|0
1651 // e.target = e.target || e.srcElement
1652 _fn.call(el, e, delta)
1653 }
1654 }
1655 }
1656 }
1657 , passiveEvents = false
1658 try {
1659 window[addEv]("t", null, Object.defineProperty({}, "passive", {
1660 get: function() {
1661 passiveEvents = true
1662 }
1663 }))
1664 } catch (e) {}
1665 Event.passive = passiveEvents
1666
1667 var emitter = new Event.Emitter
1668
1669 function addEvent(el, ev, _fn) {
1670 var fn = fixFn[ev] && fixFn[ev](el, _fn, ev) || _fn
1671 , fix = prefix ? function() {
1672 var b, e = {}
1673 for (b in event) e[b] = event[b]
1674 e.target = e.srcElement
1675 b = e.buttons = e.button
1676 e.button = b == 1 ? 0: b == 4 ? 1 : b
1677 e.preventDefault = preventDefault
1678 e.stopPropagation = stopPropagation
1679 e.type = ev
1680 if (e.clientX !== void 0) {
1681 e.pageX = e.clientX + scrollLeft()
1682 e.pageY = e.clientY + scrollTop()
1683 }
1684 fn.call(el, e)
1685 } : fn
1686
1687 if (fixEv[ev] !== "") {
1688 el[addEv](prefix + (fixEv[ev] || ev), fix, false)
1689 }
1690
1691 emitter.on.call(el, ev, fix, el, _fn)
1692 }
1693
1694 function rmEvent(el, ev, fn) {
1695 var evs = el._e && el._e[ev]
1696 , id = evs && evs.indexOf(fn)
1697 if (id > -1) {
1698 if (fn !== evs[id + 1] && evs[id + 1]._rm) {
1699 evs[id + 1]._rm()
1700 }
1701 el[remEv](prefix + (fixEv[ev] || ev), evs[id + 1])
1702 evs.splice(id - 1, 3)
1703 }
1704 }
1705
1706 function preventDefault() {
1707 event.returnValue = false
1708 }
1709 function stopPropagation() {
1710 event.cancelBubble = event.cancel = true
1711 }
1712
1713 Event.stop = function(e) {
1714 if (e && e.preventDefault) {
1715 e.stopPropagation()
1716 e.preventDefault()
1717 }
1718 return false
1719 }
1720
1721 El.on = acceptMany(addEvent)
1722 El.off = acceptMany(rmEvent)
1723
1724 El.one = function(el, ev, fn) {
1725 function remove() {
1726 rmEvent(el, ev, fn)
1727 rmEvent(el, ev, remove)
1728 }
1729 addEvent(el, ev, fn)
1730 addEvent(el, ev, remove)
1731 return el
1732 }
1733
1734 El.emit = function(el, ev) {
1735 emitter.emit.apply(el, slice.call(arguments, 1))
1736 }
1737
1738 function empty(el) {
1739 for (var node; node = el.firstChild; ) {
1740 kill(node)
1741 }
1742 return el
1743 }
1744
1745 function kill(el) {
1746 var id
1747 if (el) {
1748 if (el._e) {
1749 emitter.emit.call(el, "kill")
1750 for (id in el._e) rmEvent(el, id)
1751 }
1752 if (el.parentNode) {
1753 el.parentNode.removeChild(el)
1754 }
1755 if (el.nodeType != 1) {
1756 return el.kill && el.kill()
1757 }
1758 empty(el)
1759 if (id = el._scope) {
1760 delete elScope[id]
1761 }
1762 if (el.valObject) {
1763 el.valObject = null
1764 }
1765 }
1766 }
1767
1768 function elScope(node, parent, fb) {
1769 return elScope[node._scope] || fb || (
1770 parent ?
1771 (((fb = elScope[node._scope = ++seq] = Object.create(parent))._super = parent), fb) :
1772 closestScope(node)
1773 ) || scopeData
1774
1775 }
1776
1777 function closestScope(node) {
1778 for (; node = node.parentNode; ) {
1779 if (node._scope) return elScope[node._scope]
1780 }
1781 }
1782
1783 function render(node, _scope) {
1784 var bind, fn
1785 , scope = elScope(node, 0, _scope)
1786 , i = 0
1787
1788 if (node.nodeType != 1) {
1789 node.render ? node.render(scope) : node
1790 return
1791 }
1792
1793 if (bind = getAttr(node, BIND_ATTR)) {
1794 scope._m = bindMatch
1795 scope._t = bind
1796 // i18n(bind, lang).format(scope)
1797 // document.documentElement.lang
1798 // document.getElementsByTagName('html')[0].getAttribute('lang')
1799
1800 fn = "data b s B r->data&&(" + bind.replace(renderRe, function(match, name, op, args) {
1801 scope._m[i] = match
1802 var fn = bindings[name]
1803 return (
1804 (op == ":" || fn && hasOwn.call(fn, "once")) ?
1805 "s(this,B,data._t=data._t.replace(data._m[" + (i++)+ "],''))||" :
1806 ""
1807 ) + (
1808 fn ?
1809 "b['" + name + "'].call(data,this" + (fn.raw ? ",'" + args + "'" : args ? "," + args : "") :
1810 "s(this,'" + name + "'," + args
1811 ) + ")||"
1812 }) + "r)"
1813
1814 try {
1815 if (Fn(fn, node, scope)(scope, bindings, setAttr, BIND_ATTR)) {
1816 return
1817 }
1818 } catch (e) {
1819 /*** debug ***//*
1820 e.message += "\nBINDING: " + bind
1821 console.error(e, node)
1822 /**/
1823 if (window.onerror) {
1824 window.onerror(e.message, e.fileName, e.lineNumber)
1825 }
1826 }
1827 }
1828
1829 for (bind = node.firstChild; bind; bind = fn) {
1830 fn = bind.nextSibling
1831 render(bind, scope)
1832 }
1833 /*** ie8 ***/
1834 if (ie678 && node.tagName == "SELECT") {
1835 node.parentNode.insertBefore(node, node)
1836 }
1837 /**/
1838 }
1839
1840 El.empty = empty
1841 El.kill = kill
1842 El.render = render
1843
1844 Object.each(El, function(fn, key) {
1845 if (!wrapProto[key]) {
1846 wrapProto[key] = function wrap() {
1847 var i = 0
1848 , self = this
1849 , len = self.length
1850 , arr = slice.call(arguments)
1851 arr.unshift(1)
1852 for (; i < len; ) {
1853 arr[0] = self[i++]
1854 fn.apply(null, arr)
1855 }
1856 return self
1857 }
1858 }
1859 })
1860
1861 El.append = append
1862 El.scope = elScope
1863
1864 function parseTemplate(str) {
1865 var parent = El("div")
1866 , stack = [-1]
1867 , parentStack = []
1868
1869 function work(all, indent, plugin, name, q, op, text, mapEnd, mapStart, offset) {
1870 if (offset && all === indent) return
1871
1872 for (q = indent.length; q <= stack[0]; ) {
1873 if (parent.plugin) {
1874 parent.plugin.done()
1875 }
1876 parent = parentStack.pop()
1877 stack.shift()
1878 }
1879
1880 if (parent._r) {
1881 parent.txt += all + "\n"
1882 } else if (plugin || mapStart && (name = "map")) {
1883 if (El.plugins[name]) {
1884 parentStack.push(parent)
1885 stack.unshift(q)
1886 parent = (new El.plugins[name](parent, op + text, mapEnd ? "" : ";")).el
1887 } else {
1888 append(parent, all)
1889 }
1890 } else if (mapEnd) {
1891 appendBind(parent, text, "")
1892 } else {
1893 if (name) {
1894 parentStack.push(parent)
1895 stack.unshift(q)
1896 q = El(name, 0, 1)
1897 append(parent, parent = q)
1898 }
1899 if (text && op != "/") {
1900 if (op == ">") {
1901 (indent + " " + text).replace(templateRe, work)
1902 } else if (op == "|" || op == "\\") {
1903 append(parent, text) // + "\n")
1904 } else {
1905 if (op != "&" && op != "^") {
1906 text = (parent.tagName == "INPUT" ? "val" : "txt") + (
1907 op == "=" ? ":" + text.replace(/'/g, "\\'") :
1908 ":_('" + text.replace(/'/g, "\\'") + "').format(data)"
1909 )
1910 }
1911 appendBind(parent, text, ";", op)
1912 }
1913 }
1914 }
1915 }
1916 str.replace(templateRe, work)
1917 work("", "")
1918 }
1919
1920 function appendBind(el, val, sep, q) {
1921 var current = getAttr(el, BIND_ATTR)
1922 setAttr(el, BIND_ATTR, (current ? (
1923 q == "^" ?
1924 val + sep + current :
1925 current + sep + val
1926 ) : val))
1927 }
1928
1929 function plugin(parent, name) {
1930 var t = this
1931 t.name = name
1932 t.parent = parent
1933 t.el = El("div")
1934 t.el.plugin = t
1935 }
1936
1937 plugin[protoStr] = {
1938 _done: function() {
1939 var el, childId
1940 , t = this
1941 , childNodes = t.el.childNodes
1942 , i = childNodes.length
1943
1944 for (; i--; ) {
1945 el = childNodes[i]
1946 if (el._childKey) {
1947 childId = i
1948 setAttr(el, "data-child", el._childKey)
1949 break
1950 }
1951 }
1952
1953 if (childNodes[1]) {
1954 el = new ElWrap(childNodes)
1955 el._childId = childId
1956 } else {
1957 el = childNodes[0]
1958 }
1959
1960 t.el.plugin = t.el = t.parent = null
1961 return el
1962 },
1963 done: function() {
1964 var t = this
1965 , parent = t.parent
1966 elCache[t.name] = t._done()
1967 return parent
1968 }
1969 }
1970
1971 function js(parent, params, attr1) {
1972 var t = this
1973 // Raw text mode
1974 t._r = t.parent = parent
1975 t.txt = ""
1976 t.plugin = t.el = t
1977 t.params = params
1978 t.a = attr1
1979 }
1980
1981 js[protoStr].done = Fn("Function(this.txt)()")
1982
1983 El.plugins = {
1984 binding: js.extend({
1985 done: function() {
1986 Object.assign(bindings, Function("return({" + this.txt + "})")())
1987 }
1988 }),
1989 child: plugin.extend({
1990 done: function() {
1991 var key = "@child-" + (++seq)
1992 , root = this.parent
1993 for (; (root.parentNode.parentNode || key).nodeType == 1; ) {
1994 root = root.parentNode
1995 }
1996 root._childKey = key
1997 append(this.parent, document.createComment(key))
1998 }
1999 }),
2000 css: js.extend({
2001 done: Fn("xhr.css(this.txt)")
2002 }),
2003 def: js.extend({
2004 done: Fn("View.def(this.params||this.txt)")
2005 }),
2006 each: js.extend({
2007 done: function() {
2008 var txt = this.txt
2009
2010 JSON.parse(this.params)
2011 .each(function(val) {
2012 if (!val || val.constructor != Object) {
2013 val = { item: val }
2014 }
2015 parseTemplate(txt.format(val))
2016 })
2017 }
2018 }),
2019 el: plugin,
2020 js: js,
2021 map: js.extend({
2022 done: function() {
2023 var self = this
2024 , txt = (self.params + self.txt)
2025 appendBind(
2026 self.parent,
2027 self.a ? txt.slice(1) : txt,
2028 self.a
2029 )
2030 }
2031 }),
2032 template: plugin,
2033 view: plugin.extend({
2034 done: function() {
2035 var fn
2036 , t = this
2037 , arr = t.name.split(splitRe)
2038 , bind = getAttr(t.el, BIND_ATTR)
2039 , view = View(arr[0], t._done(), arr[1], arr[2])
2040 if (bind) {
2041 fn = bind.replace(renderRe, function(match, name, op, args) {
2042 return "(this['" + name + "']" + (
2043 typeof view[name] == "function" ?
2044 "(" + (args || "") + ")" :
2045 "=" + args
2046 ) + "),"
2047 }) + "1"
2048 Fn(fn, view, scopeData)()
2049 }
2050 }
2051 }),
2052 "view-link": plugin.extend({
2053 done: function() {
2054 var t = this
2055 , arr = t.name.split(splitRe)
2056 View(arr[0], null, arr[2])
2057 .on("ping", function(opts) {
2058 View.show(arr[1].format(opts))
2059 })
2060 }
2061 })
2062 }
2063
2064 xhr.view = xhr.tpl = El.tpl = parseTemplate
2065 xhr.css = function(str) {
2066 if (!styleNode) {
2067 // Safari and IE6-8 requires dynamically created
2068 // <style> elements to be inserted into the <head>
2069 append(document.getElementsByTagName("head")[0], styleNode = El("style"))
2070 }
2071 if (styleNode.styleSheet) styleNode.styleSheet.cssText += str
2072 else append(styleNode, str)
2073 }
2074
2075 El.scrollLeft = scrollLeft
2076 function scrollLeft() {
2077 return window.pageXOffset || root.scrollLeft || body.scrollLeft || 0
2078 }
2079
2080 El.scrollTop = scrollTop
2081 function scrollTop() {
2082 return window.pageYOffset || root.scrollTop || body.scrollTop || 0
2083 }
2084
2085 /*** kb ***/
2086 var kbMaps = []
2087 , kbKeys = {
2088 8: "backspace", 9: "tab",
2089 13: "enter", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
2090 20: "caps", 27: "esc",
2091 33: "pgup", 34: "pgdown",
2092 35: "end", 36: "home",
2093 37: "left", 38: "up", 39: "right", 40: "down",
2094 45: "ins", 46: "del",
2095 91: "cmd",
2096 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6",
2097 118: "f7", 119: "f8", 120: "f9", 121: "f10", 122: "f11", 123: "f12"
2098 }
2099 , kbMod = El.kbMod = /^(Mac|iP)/.test(navigator.platform) ? "metaKey" : "ctrlKey"
2100
2101 function kbRun(e, code, chr) {
2102 var fn, map
2103 , i = 0
2104 , el = e.target || e.srcElement
2105 , input = /INPUT|TEXTAREA|SELECT/i.test((el.nodeType == 3 ? el.parentNode : el).tagName)
2106
2107 for (; map = kbMaps[i++]; ) {
2108 if (!input || map.input) {
2109 fn = map[code] ||
2110 map[chr] ||
2111 map.num && code > 47 && code < 58 && (chr|=0, map.num) ||
2112 map.all
2113 }
2114 if (fn || !map.bubble) break
2115 }
2116 if (fn) {
2117 typeof fn === "string" ? View.emit(fn, e, chr, el) : fn(e, chr, el)
2118 }
2119 }
2120
2121 function kbDown(e) {
2122 if (kbMaps[0]) {
2123 var c = e.keyCode || e.which
2124 , numpad = c > 95 && c < 106
2125 , code = numpad ? c - 48 : c
2126 , key = kbKeys[code] || String.fromCharCode(code).toLowerCase() || code
2127
2128 // Otherwise IE backspace navigates back
2129 if (code == 8 && kbMaps[0].backspace) {
2130 Event.stop(e)
2131 }
2132 kbRun(e, code, key)
2133 if (e.shiftKey && code != 16) kbRun(e, code, "shift+" + key)
2134 /**
2135 * people in Poland use Right Alt+S to type in Ś.
2136 * Right Alt+S is mapped internally to Ctrl+Alt+S.
2137 * https://medium.engineering/the-curious-case-of-disappearing-polish-s-fa398313d4df
2138 */
2139 if (e.altKey) {
2140 if (code != 18) kbRun(e, code, "alt+" + key)
2141 } else if (code != 17) {
2142 if (e.ctrlKey) kbRun(e, code, "ctrl+" + key)
2143 if (e[kbMod] && code != 91) kbRun(e, code, "mod+" + key)
2144 }
2145 }
2146 }
2147
2148 El.addKb = kbMaps.unshift.bind(kbMaps)
2149 El.rmKb = function(map) {
2150 var i = kbMaps.indexOf(map||kbMaps[0])
2151 if (i > -1) kbMaps.splice(i, 1)
2152 }
2153
2154 addEvent(document, "keydown", kbDown)
2155 /**/
2156
2157
2158 /*** responsive ***/
2159 var lastSize, lastOrient
2160 , breakpoints = {
2161 sm: 0,
2162 md: 601,
2163 lg: 1025
2164 }
2165 , setBreakpointsRated = function() {
2166 setBreakpoints()
2167 }.rate(100, true)
2168
2169 function setBreakpoints(_breakpoints) {
2170 // document.documentElement.clientWidth is 0 in IE5
2171 var key, next
2172 , width = root.offsetWidth
2173 , map = breakpoints = _breakpoints || breakpoints
2174
2175 for (key in map) {
2176 if (map[key] > width) break
2177 next = key
2178 }
2179
2180 if ( next != lastSize ) {
2181 cls(root, lastSize, 0)
2182 cls(root, lastSize = next)
2183 }
2184
2185 next = width > root.offsetHeight ? "landscape" : "portrait"
2186
2187 if ( next != lastOrient) {
2188 cls(root, lastOrient, 0)
2189 cls(root, lastOrient = next)
2190 }
2191
2192 if (next = window.View) next.emit("resize")
2193 }
2194 El.setBreakpoints = setBreakpoints
2195
2196 setBreakpointsRated()
2197
2198 addEvent(window, "resize", setBreakpointsRated)
2199 addEvent(window, "orientationchange", setBreakpointsRated)
2200 addEvent(window, "load", setBreakpointsRated)
2201 /**/
2202
2203
2204 /*** i18n ***/
2205 function i18n(text, lang) {
2206 lang = i18n[i18nGet(lang) || currentLang]
2207 return (
2208 lang[text] ||
2209 typeof text === "string" && lang[text = text.slice(text.indexOf(":") + 1) || text] ||
2210 text || ""
2211 )
2212 }
2213 El.i18n = i18n
2214
2215 function i18nGet(lang) {
2216 return lang && (
2217 i18n[lang = ("" + lang).toLowerCase()] ||
2218 i18n[lang = lang.split("-")[0]]
2219 ) && lang
2220 }
2221
2222 function i18nUse(lang) {
2223 lang = i18nGet(lang)
2224 if (lang && currentLang != lang) {
2225 i18n[currentLang = i18n.current = lang] = i18n[currentLang] || {}
2226 }
2227 return currentLang
2228 }
2229
2230 function i18nAdd(lang, texts) {
2231 if (i18n.list.indexOf(lang) == -1) i18n.list.push(lang)
2232 Object.assign(i18n[lang] || (i18n[lang] = {}), texts)
2233 if (!currentLang) i18nUse(lang)
2234 }
2235
2236 i18n.list = []
2237 i18n.get = i18nGet
2238 i18n.use = i18nUse
2239 i18n.add = i18nAdd
2240 i18n.def = function(map, key) {
2241 for (key in map) {
2242 i18nAdd(key, map)
2243 }
2244 }
2245 // navigator.userLanguage for IE, navigator.language for others
2246 // var lang = navigator.language || navigator.userLanguage;
2247 // i18nUse("en")
2248 /**/
2249
2250}(window, document, Object, Event, "prototype")
2251/* litejs.com/MIT-LICENSE.txt */
2252
2253
2254
2255!function(bindings) {
2256 var hasOwn = Object.prototype.hasOwnProperty
2257 , slice = Array.prototype.slice
2258
2259 bindingEvery.once =
2260 emitForm.once =
2261 bindingFn.once =
2262 bindingOn.once =
2263 bindingsEach.raw = bindingsEach.once =
2264 true
2265
2266 bindings.every = bindingEvery
2267 function bindingEvery(el, list, attrName) {
2268 var len = 0
2269 , data = this
2270 , parent = el.parentNode
2271 , comm = document.createComment("every " + (list.name || list.length))
2272
2273 parent.replaceChild(comm, el)
2274
2275 if (list) {
2276 if (typeof list === "string") {
2277 data.model.on("change:" + list, render)
2278 render()
2279 } else if (list.eachLive) {
2280 list.eachLive(add, remove)
2281 } else {
2282 comm.render = render
2283 render()
2284 }
2285 }
2286 return true
2287
2288 function render() {
2289 for (; len; len--) {
2290 El.kill(comm.previousSibling)
2291 }
2292 Object.each(typeof list === "string" ? data.model.get(list) : list, add)
2293 }
2294
2295 function add(item, i) {
2296 len++
2297 var up
2298 , clone = el.cloneNode(true)
2299 , scope = El.scope(clone, data)
2300 scope.i = i
2301 scope[attrName || "item"] = item
2302 El.append(parent, clone, comm)
2303 El.render(clone, scope)
2304 if (typeof item.on === "function") {
2305 item.on("change", up = El.render.bind(clone, clone))
2306 El.on(clone, "kill", function() {
2307 item.off("change", up)
2308 })
2309 }
2310 }
2311
2312 function remove(pos) {
2313 for (var el = comm, i = pos + 1; i--; ) {
2314 el = el.previousSibling
2315 }
2316 El.kill(el)
2317 }
2318 }
2319
2320 bindings.fn = bindingFn
2321 function bindingFn(el, fn) {
2322 return fn.apply(el, slice.call(arguments, 3))
2323 }
2324
2325 bindings["if"] = bindingsIf
2326 function bindingsIf(el, enabled) {
2327 var parent = el.parentNode
2328 , scope = this
2329 if (enabled) {
2330 parent || el._ifComm && el._ifComm.parentNode.replaceChild(el, el._ifComm)
2331 } else {
2332 if (parent) {
2333 if (!el._ifComm) {
2334 El.on(el, "kill", El.kill.bind(el, el._ifComm = document.createComment("if")))
2335 el._ifComm.render = function() {
2336 El.render(el, scope)
2337 }
2338 }
2339 parent.replaceChild(el._ifComm, el)
2340 }
2341 return true
2342 }
2343 }
2344
2345 bindings.is = function bindingIs(node, model, path, list, state) {
2346 var i, match, val
2347 , scope = this
2348 if (typeof model === "string") {
2349 state = list
2350 list = path
2351 path = model
2352 model = scope.model
2353 }
2354 if (model && path) {
2355 match = val = state || model.get(path)
2356 if (list) {
2357 if (!Array.isArray(list)) {
2358 list = list.split(",")
2359 }
2360 i = list.length & -2
2361
2362 for (; i > -1; i -= 2) {
2363 if (i == 0 || list[i - 1] == "" + val || +list[i - 1] <= val) {
2364 match = list[i]
2365 break
2366 }
2367 }
2368 }
2369 El.cls(node, scope["_is-" + path], 0)
2370 El.cls(node, scope["_is-" + path] = match && "is-" + match)
2371 }
2372 }
2373
2374 bindings.on = bindingOn
2375 // .on( events [, selector ] [, data ], handler )
2376 function bindingOn(el, events, selector, data, handler) {
2377 var argi = arguments.length
2378 if (argi == 4) {
2379 handler = data
2380 if (typeof selector == "string") {
2381 data = null
2382 } else {
2383 data = selector
2384 selector = null
2385 }
2386 }
2387 if (argi == 3) {
2388 handler = selector
2389 selector = data = null
2390 }
2391 El.on(el, events, (
2392 typeof handler == "string" ? function(e) {
2393 var target = selector ? El.closest(e.target, selector) : el
2394 if (!target) return
2395 var args = [handler, e, target]
2396 args.push.apply(args, data)
2397 View.emit.apply(View, args)
2398 } :
2399 selector ? function(e) {
2400 if (El.matches(e.target, selector)) handler(e)
2401 } :
2402 handler
2403 ))
2404 }
2405
2406 bindings.emitForm = emitForm
2407 function emitForm(el, ev, a1, a2, a3, a4) {
2408 El.on(el, "submit", function(e) {
2409 var data = El.val(el)
2410 View.emit(ev, e, data, a1, a2, a3, a4)
2411 return Event.stop(e)
2412 })
2413 }
2414
2415 function getChilds(node) {
2416 var child
2417 , childs = node._childs
2418 if (!childs) {
2419 for (node._childs = childs = []; child = node.firstChild;) {
2420 childs.push(child);
2421 node.removeChild(child)
2422 }
2423 }
2424 return childs
2425 }
2426
2427 bindings.each = bindingsEach
2428
2429 function bindingsEach(el, expr) {
2430 var node = el
2431 , child = getChilds(node)[0]
2432 , match = /^\s*(\w+) in (\w*)(.*)/.exec(expr)
2433 , fn = "with(data){var out=[],loop={i:0,offset:0},_1,_2=" + match[2]
2434 + match[3].replace(/ (limit|offset):\s*(\d+)/ig, ";loop.$1=$2")
2435 + ";if(_2)for(_1 in _2)if(hasOwn.call(_2,_1)&&!(loop.offset&&loop.offset--)){"
2436 + "loop.i++;"
2437 + "if(loop.limit&&loop.i-loop.offset>loop.limit)break;"
2438 + "var clone=el.cloneNode(true)"
2439 + ",scope=El.scope(clone,data);"
2440 + "scope.loopKey=loop.key=_1;"
2441 + "scope.loop=loop;"
2442 + "scope." + match[1] + "=_2[_1];"
2443 + "out.push(clone);"
2444 + "};return out}"
2445
2446 var childs = Function("hasOwn,el,data", fn)(hasOwn, child, this)
2447
2448 El.append(El.empty(node), childs)
2449 El.render(node)
2450 return node
2451 }
2452
2453 bindings.focus = function(el) {
2454 el.focus()
2455 }
2456
2457 bindings.href = function(el, url) {
2458 if (url) {
2459 var chr = url.charAt(0)
2460 el.href = chr === "+" || chr === "%" ? "#" + View.url(url) : url
2461 }
2462 }
2463}(El.bindings)
2464/* litejs.com/MIT-LICENSE.txt */
2465
2466
2467
2468El.bindings.list = function(node, list, extra, val) {
2469 var child = node._child
2470 , data = this
2471 , extraLen = 0
2472
2473 if (!child) {
2474 child = node._child = node.removeChild(node.firstChild)
2475 }
2476
2477 if (!list || node._list == list) return
2478
2479 if (node._list) clear()
2480
2481 node._list = data.list = list
2482
2483 El.on(node, "kill", clear)
2484
2485 El.cls(node, "loading")
2486
2487 if (extra) {
2488 extra.each(clone)
2489 extraLen = extra.length
2490 }
2491
2492 list
2493 .each(clone)
2494 .on("add", clone).on("remove", remove)
2495 .on("startLoading", function(){
2496 El.cls(node, "loading")
2497 })
2498 .on("endLoading", function(){
2499 El.cls(node, "loading", 0)
2500 })
2501 .then(function() {
2502 if (val !== void 0 && El.val(node) !== val) {
2503 if (!this.get(val)) {
2504 clone({id:val,name:val}, extraLen)
2505 extraLen++
2506 }
2507 El.val(node, val)
2508 }
2509 El.cls(node, "loading", 0)
2510 })
2511
2512 // Do not render childs when list initialized
2513 return true
2514
2515 function clone(item, pos) {
2516 var clone = child.cloneNode(true)
2517 , scope = El.scope(clone, data)
2518 scope.item = item.data || item || {id:item,name:item}
2519 scope.model = item
2520 scope.pos = pos
2521 function up() {
2522 El.render(clone, scope)
2523 }
2524 if (item.on) {
2525 item.on("change", up)
2526 El.on(clone, "kill", function(){
2527 item.off("change", up)
2528 })
2529 }
2530 El.append(node, clone, extraLen + pos)
2531 return El.render(clone, scope)
2532 }
2533
2534 function remove(item, pos) {
2535 El.kill(node.childNodes[extraLen + pos])
2536 }
2537
2538 function clear() {
2539 var list = node._list
2540 El.empty(node)
2541 if (list) {
2542 node._list = null
2543 list.off("add", clone).off("remove", remove)
2544 }
2545 }
2546}
\No newline at end of file