aboutsummaryrefslogtreecommitdiff
path: root/node_modules/utila/scripts
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
commitde98e0b232509d5f40c135d540a70e415272ff85 (patch)
treea79222a5b58484ab3b80d18efcaaa7ccc4769b33 /node_modules/utila/scripts
parente0c9d480a73fa629c1e4a47d3e721f1d2d345406 (diff)
downloadwallet-core-de98e0b232509d5f40c135d540a70e415272ff85.tar.xz
node_modules
Diffstat (limited to 'node_modules/utila/scripts')
-rw-r--r--node_modules/utila/scripts/coffee/lib/Emitter.coffee145
-rw-r--r--node_modules/utila/scripts/coffee/lib/_common.coffee99
-rw-r--r--node_modules/utila/scripts/coffee/lib/array.coffee186
-rw-r--r--node_modules/utila/scripts/coffee/lib/classic.coffee87
-rw-r--r--node_modules/utila/scripts/coffee/lib/object.coffee170
-rw-r--r--node_modules/utila/scripts/coffee/lib/string.coffee16
-rw-r--r--node_modules/utila/scripts/coffee/lib/utila.coffee7
-rw-r--r--node_modules/utila/scripts/coffee/test/_prepare.coffee5
-rw-r--r--node_modules/utila/scripts/coffee/test/array.coffee143
-rw-r--r--node_modules/utila/scripts/coffee/test/object.coffee233
-rw-r--r--node_modules/utila/scripts/js/lib/Emitter.js144
-rw-r--r--node_modules/utila/scripts/js/lib/_common.js112
-rw-r--r--node_modules/utila/scripts/js/lib/array.js166
-rw-r--r--node_modules/utila/scripts/js/lib/classic.js87
-rw-r--r--node_modules/utila/scripts/js/lib/object.js158
-rw-r--r--node_modules/utila/scripts/js/lib/string.js15
-rw-r--r--node_modules/utila/scripts/js/lib/utila.js11
-rw-r--r--node_modules/utila/scripts/js/test/_prepare.js9
-rw-r--r--node_modules/utila/scripts/js/test/array.js115
-rw-r--r--node_modules/utila/scripts/js/test/object.js220
20 files changed, 2128 insertions, 0 deletions
diff --git a/node_modules/utila/scripts/coffee/lib/Emitter.coffee b/node_modules/utila/scripts/coffee/lib/Emitter.coffee
new file mode 100644
index 000000000..585a924ed
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/lib/Emitter.coffee
@@ -0,0 +1,145 @@
+array = require './array'
+
+module.exports = class Emitter
+
+ constructor: ->
+
+ @_listeners = {}
+
+ @_listenersForAnyEvent = []
+
+ @_disabledEmitters = {}
+
+ on: (eventName, listener) ->
+
+ unless @_listeners[eventName]?
+
+ @_listeners[eventName] = []
+
+ @_listeners[eventName].push listener
+
+ @
+
+ once: (eventName, listener) ->
+
+ ran = no
+
+ cb = =>
+
+ return if ran
+
+ ran = yes
+
+ do listener
+
+ setTimeout =>
+
+ @removeEvent eventName, cb
+
+ , 0
+
+ @on eventName, cb
+
+ @
+
+ onAnyEvent: (listener) ->
+
+ @_listenersForAnyEvent.push listener
+
+ @
+
+ removeEvent: (eventName, listener) ->
+
+ return @ unless @_listeners[eventName]?
+
+ array.pluckOneItem @_listeners[eventName], listener
+
+ @
+
+ removeListeners: (eventName) ->
+
+ return @ unless @_listeners[eventName]?
+
+ @_listeners[eventName].length = 0
+
+ @
+
+ removeAllListeners: ->
+
+ for name, listeners of @_listeners
+
+ listeners.length = 0
+
+ @
+
+ _emit: (eventName, data) ->
+
+ for listener in @_listenersForAnyEvent
+
+ listener.call @, data, eventName
+
+ return unless @_listeners[eventName]?
+
+ for listener in @_listeners[eventName]
+
+ listener.call @, data
+
+ return
+
+ # this makes sure that all the calls to this class's method 'fnName'
+ # are throttled
+ _throttleEmitterMethod: (fnName, time = 1000) ->
+
+ originalFn = @[fnName]
+
+ if typeof originalFn isnt 'function'
+
+ throw Error "this class does not have a method called '#{fnName}'"
+
+ lastCallArgs = null
+ pending = no
+ timer = null
+
+ @[fnName] = =>
+
+ lastCallArgs = arguments
+
+ do pend
+
+ pend = =>
+
+ if pending
+
+ clearTimeout timer
+
+ timer = setTimeout runIt, time
+
+ pending = yes
+
+ runIt = =>
+
+ pending = no
+
+ originalFn.apply @, lastCallArgs
+
+ _disableEmitter: (fnName) ->
+
+ if @_disabledEmitters[fnName]?
+
+ throw Error "#{fnName} is already a disabled emitter"
+
+ @_disabledEmitters[fnName] = @[fnName]
+
+ @[fnName] = ->
+
+ _enableEmitter: (fnName) ->
+
+ fn = @_disabledEmitters[fnName]
+
+ unless fn?
+
+ throw Error "#{fnName} is not a disabled emitter"
+
+ @[fnName] = fn
+
+ delete @_disabledEmitters[fnName] \ No newline at end of file
diff --git a/node_modules/utila/scripts/coffee/lib/_common.coffee b/node_modules/utila/scripts/coffee/lib/_common.coffee
new file mode 100644
index 000000000..b120937f4
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/lib/_common.coffee
@@ -0,0 +1,99 @@
+module.exports = common =
+
+ ###
+ Checks to see if o is an object, and it isn't an instance
+ of some class.
+ ###
+ isBareObject: (o) ->
+
+ if o? and o.constructor is Object
+
+ return true
+
+ false
+
+ ###
+ Returns type of an object, including:
+ undefined, null, string, number, array,
+ arguments, element, textnode, whitespace, and object
+ ###
+ typeOf: (item) ->
+
+ return 'null' if item is null
+
+ return typeof item if typeof item isnt 'object'
+
+ return 'array' if Array.isArray item
+
+ # From MooTools
+ # - do we even need this?
+ if item.nodeName
+
+ if item.nodeType is 1 then return 'element'
+ if item.nodeType is 3 then return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace'
+
+ else if typeof item.length is 'number'
+
+ if item.callee then return 'arguments'
+
+ return typeof item
+
+ # Deep clone of any variable.
+ # From MooTools
+ clone: (item, includePrototype = false) ->
+
+ switch common.typeOf item
+
+ when 'array' then return common._cloneArray item, includePrototype
+
+ when 'object' then return common._cloneObject item, includePrototype
+
+ else return item
+
+ ###
+ Deep clone of an object.
+ From MooTools
+ ###
+ _cloneObject: (o, includePrototype = false) ->
+
+ if common.isBareObject o
+
+ clone = {}
+
+ for key of o
+
+ clone[key] = common.clone o[key], includePrototype
+
+ return clone
+
+ else
+
+ return o unless includePrototype
+
+ return o if o instanceof Function
+
+ clone = Object.create o.constructor.prototype
+
+ for key of o
+
+ if o.hasOwnProperty key
+
+ clone[key] = common.clone o[key], includePrototype
+
+ clone
+
+ ###
+ Deep clone of an array.
+ From MooTools
+ ###
+ _cloneArray: (a, includePrototype = false) ->
+
+ i = a.length
+
+ clone = new Array i
+
+ while i--
+
+ clone[i] = common.clone a[i], includePrototype
+
+ clone \ No newline at end of file
diff --git a/node_modules/utila/scripts/coffee/lib/array.coffee b/node_modules/utila/scripts/coffee/lib/array.coffee
new file mode 100644
index 000000000..429bf6dc6
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/lib/array.coffee
@@ -0,0 +1,186 @@
+module.exports = array =
+
+ ###
+ Tries to turn anything into an array.
+ ###
+ from: (r) ->
+
+ Array::slice.call r
+
+ ###
+ Clone of an array. Properties will be shallow copies.
+ ###
+ simpleClone: (a) ->
+
+ a.slice 0
+
+ shallowEqual: (a1, a2) ->
+
+ return no unless Array.isArray(a1) and Array.isArray(a2) and a1.length is a2.length
+
+ for val, i in a1
+
+ return no unless a2[i] is val
+
+ yes
+
+ pluck: (a, i) ->
+
+ return a if a.length < 1
+
+
+ for value, index in a
+
+ if index > i
+
+ a[index - 1] = a[index]
+
+ a.length = a.length - 1
+
+ a
+
+ pluckItem: (a, item) ->
+
+ return a if a.length < 1
+
+
+ removed = 0
+
+ for value, index in a
+
+ if value is item
+
+ removed++
+
+ continue
+
+ if removed isnt 0
+
+ a[index - removed] = a[index]
+
+ a.length = a.length - removed if removed > 0
+
+ a
+
+ pluckOneItem: (a, item) ->
+
+ return a if a.length < 1
+
+ reached = no
+
+ for value, index in a
+
+ if not reached
+
+ if value is item
+
+ reached = yes
+
+ continue
+
+ else
+
+ a[index - 1] = a[index]
+
+ a.length = a.length - 1 if reached
+
+ a
+
+ pluckByCallback: (a, cb) ->
+
+ return a if a.length < 1
+
+ removed = 0
+
+ for value, index in a
+
+ if cb value, index
+
+ removed++
+
+ continue
+
+ if removed isnt 0
+
+ a[index - removed] = a[index]
+
+ if removed > 0
+
+ a.length = a.length - removed
+
+ a
+
+ pluckMultiple: (array, indexesToRemove) ->
+
+ return array if array.length < 1
+
+ removedSoFar = 0
+
+ indexesToRemove.sort()
+
+ for i in indexesToRemove
+
+ @pluck array, i - removedSoFar
+
+ removedSoFar++
+
+ array
+
+ injectByCallback: (a, toInject, shouldInject) ->
+
+ valA = null
+
+ valB = null
+
+ len = a.length
+
+ if len < 1
+
+ a.push toInject
+
+ return a
+
+
+ for val, i in a
+
+ valA = valB
+
+ valB = val
+
+ if shouldInject valA, valB, toInject
+
+ return a.splice i, 0, toInject
+
+ a.push toInject
+
+ a
+
+ injectInIndex: (a, index, toInject) ->
+
+ len = a.length
+
+ i = index
+
+ if len < 1
+
+ a.push toInject
+
+ return a
+
+ toPut = toInject
+
+ toPutNext = null
+
+ `for(; i <= len; i++){
+
+ toPutNext = a[i];
+
+ a[i] = toPut;
+
+ toPut = toPutNext;
+
+ }`
+
+ # a[i] = toPut
+
+ null \ No newline at end of file
diff --git a/node_modules/utila/scripts/coffee/lib/classic.coffee b/node_modules/utila/scripts/coffee/lib/classic.coffee
new file mode 100644
index 000000000..5b3f9c82e
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/lib/classic.coffee
@@ -0,0 +1,87 @@
+module.exports = classic = {}
+
+# Little helper for mixins from CoffeeScript FAQ,
+# courtesy of Sethaurus (http://github.com/sethaurus)
+classic.implement = (mixins..., classReference) ->
+
+ for mixin in mixins
+
+ classProto = classReference::
+
+ for member of mixin::
+
+ unless Object.getOwnPropertyDescriptor classProto, member
+
+ desc = Object.getOwnPropertyDescriptor mixin::, member
+
+ Object.defineProperty classProto, member, desc
+
+ classReference
+
+classic.mix = (mixins..., classReference) ->
+
+ classProto = classReference::
+
+ classReference.__mixinCloners = []
+
+ classReference.__applyClonersFor = (instance, args = null) ->
+
+ for cloner in classReference.__mixinCloners
+
+ cloner.apply instance, args
+
+ return
+
+ classReference.__mixinInitializers = []
+
+ classReference.__initMixinsFor = (instance, args = null) ->
+
+ for initializer in classReference.__mixinInitializers
+
+ initializer.apply instance, args
+
+ return
+
+ classReference.__mixinQuitters = []
+
+ classReference.__applyQuittersFor = (instance, args = null) ->
+
+ for quitter in classReference.__mixinQuitters
+
+ quitter.apply instance, args
+
+ return
+
+ for mixin in mixins
+
+ unless mixin.constructor instanceof Function
+
+ throw Error "Mixin should be a function"
+
+ for member of mixin::
+
+ if member.substr(0, 11) is '__initMixin'
+
+ classReference.__mixinInitializers.push mixin::[member]
+
+ continue
+
+ else if member.substr(0, 11) is '__clonerFor'
+
+ classReference.__mixinCloners.push mixin::[member]
+
+ continue
+
+ else if member.substr(0, 12) is '__quitterFor'
+
+ classReference.__mixinQuitters.push mixin::[member]
+
+ continue
+
+ unless Object.getOwnPropertyDescriptor classProto, member
+
+ desc = Object.getOwnPropertyDescriptor mixin::, member
+
+ Object.defineProperty classProto, member, desc
+
+ classReference \ No newline at end of file
diff --git a/node_modules/utila/scripts/coffee/lib/object.coffee b/node_modules/utila/scripts/coffee/lib/object.coffee
new file mode 100644
index 000000000..79977b3ac
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/lib/object.coffee
@@ -0,0 +1,170 @@
+_common = require './_common'
+
+module.exports = object =
+
+ isBareObject: _common.isBareObject.bind _common
+
+ ###
+ if object is an instance of a class
+ ###
+ isInstance: (what) ->
+
+ not @isBareObject what
+
+ ###
+ Alias to _common.typeOf
+ ###
+ typeOf: _common.typeOf.bind _common
+
+ ###
+ Alias to _common.clone
+ ###
+ clone: _common.clone.bind _common
+
+ ###
+ Empties an object of its properties.
+ ###
+ empty: (o) ->
+
+ for prop of o
+
+ delete o[prop] if o.hasOwnProperty prop
+
+ o
+
+ ###
+ Empties an object. Doesn't check for hasOwnProperty, so it's a tiny
+ bit faster. Use it for plain objects.
+ ###
+ fastEmpty: (o) ->
+
+ delete o[property] for property of o
+
+ o
+
+ ###
+ Overrides values fomr `newValues` on `base`, as long as they
+ already exist in base.
+ ###
+ overrideOnto: (base, newValues) ->
+
+ return base if not @isBareObject(newValues) or not @isBareObject(base)
+
+ for key, oldVal of base
+
+ newVal = newValues[key]
+
+ continue if newVal is undefined
+
+ if typeof newVal isnt 'object' or @isInstance newVal
+
+ base[key] = @clone newVal
+
+ # newVal is a plain object
+ else
+
+ if typeof oldVal isnt 'object' or @isInstance oldVal
+
+ base[key] = @clone newVal
+
+ else
+
+ @overrideOnto oldVal, newVal
+ base
+
+ ###
+ Takes a clone of 'base' and runs #overrideOnto on it
+ ###
+ override: (base, newValues) ->
+
+ @overrideOnto @clone(base), newValues
+
+ append: (base, toAppend) ->
+
+ @appendOnto @clone(base), toAppend
+
+ # Deep appends values from `toAppend` to `base`
+ appendOnto: (base, toAppend) ->
+
+ return base if not @isBareObject(toAppend) or not @isBareObject(base)
+
+ for own key, newVal of toAppend
+
+ continue unless newVal isnt undefined
+
+ if typeof newVal isnt 'object' or @isInstance newVal
+
+ base[key] = newVal
+
+ else
+
+ # newVal is a bare object
+
+ oldVal = base[key]
+
+ if typeof oldVal isnt 'object' or @isInstance oldVal
+
+ base[key] = @clone newVal
+
+ else
+
+ @appendOnto oldVal, newVal
+
+ base
+
+ # Groups
+ groupProps: (obj, groups) ->
+
+ grouped = {}
+
+ for name, defs of groups
+
+ grouped[name] = {}
+
+ grouped['rest'] = {}
+
+ `top: //`
+ for key, val of obj
+
+ shouldAdd = no
+
+ for name, defs of groups
+
+ unless Array.isArray defs
+
+ defs = [defs]
+
+ for def in defs
+
+ if typeof def is 'string'
+
+ if key is def
+
+ shouldAdd = yes
+
+ else if def instanceof RegExp
+
+ if def.test key
+
+ shouldAdd = yes
+
+ else if def instanceof Function
+
+ if def key
+
+ shouldAdd = yes
+
+ else
+
+ throw Error 'Group definitions must either
+ be strings, regexes, or functions.'
+
+ if shouldAdd
+
+ grouped[name][key] = val
+
+ `continue top`
+
+ grouped['rest'][key] = val
+
+ grouped \ No newline at end of file
diff --git a/node_modules/utila/scripts/coffee/lib/string.coffee b/node_modules/utila/scripts/coffee/lib/string.coffee
new file mode 100644
index 000000000..9515c648f
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/lib/string.coffee
@@ -0,0 +1,16 @@
+module.exports =
+
+ # pads a number with leading zeroes
+ #
+ # http://stackoverflow.com/a/10073788/607997
+ pad: (n, width, z = '0') ->
+
+ n = n + ''
+
+ if n.length >= width
+
+ n
+
+ else
+
+ new Array(width - n.length + 1).join(z) + n \ No newline at end of file
diff --git a/node_modules/utila/scripts/coffee/lib/utila.coffee b/node_modules/utila/scripts/coffee/lib/utila.coffee
new file mode 100644
index 000000000..5d68529e4
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/lib/utila.coffee
@@ -0,0 +1,7 @@
+module.exports = utila =
+
+ array: require './array'
+ classic: require './classic'
+ object: require './object'
+ string: require './string'
+ Emitter: require './Emitter' \ No newline at end of file
diff --git a/node_modules/utila/scripts/coffee/test/_prepare.coffee b/node_modules/utila/scripts/coffee/test/_prepare.coffee
new file mode 100644
index 000000000..b602a464e
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/test/_prepare.coffee
@@ -0,0 +1,5 @@
+path = require 'path'
+
+pathToLib = path.resolve __dirname, '../lib'
+
+require('little-popo')(pathToLib) \ No newline at end of file
diff --git a/node_modules/utila/scripts/coffee/test/array.coffee b/node_modules/utila/scripts/coffee/test/array.coffee
new file mode 100644
index 000000000..a244861be
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/test/array.coffee
@@ -0,0 +1,143 @@
+require './_prepare'
+
+array = mod 'array'
+
+test 'from', ->
+
+ array.from([1]).should.be.an.instanceOf Array
+ array.from([1])[0].should.equal 1
+
+# test 'clone', ->
+
+# a = [0, 1, 2]
+
+# b = array.clone a
+
+# b[0].should.equal 0
+# b[1].should.equal 1
+
+# b[0] = 3
+
+# a[0].should.equal 0
+
+test 'pluck', ->
+
+ a = [0, 1, 2, 3]
+
+ after = array.pluck a, 1
+
+ after.length.should.equal 3
+
+ after[0].should.equal 0
+ after[1].should.equal 2
+ after[2].should.equal 3
+ after.should.equal a
+
+test 'pluckMultiple', ->
+
+ a = [0, 1, 2, 3, 4, 5, 6]
+
+ array.pluckMultiple a, [0, 4, 2, 6]
+
+ a.length.should.equal 3
+ a[0].should.equal 1
+ a[1].should.equal 3
+ a[2].should.equal 5
+
+test 'pluckItem', ->
+
+ a = [0, 1, 2, 3, 2, 4, 2]
+
+ array.pluckItem a, 2
+
+ a[0].should.equal 0
+ a[1].should.equal 1
+ a[2].should.equal 3
+ a[3].should.equal 4
+
+ array.pluckItem([1], 2).length.should.equal 1
+
+
+test 'pluckOneItem', ->
+
+ a = [0, 1, 2, 3, 2, 4, 2]
+
+ array.pluckOneItem a, 2
+
+ a[0].should.equal 0
+ a[1].should.equal 1
+ a[2].should.equal 3
+ a[3].should.equal 2
+ a[4].should.equal 4
+ a[5].should.equal 2
+
+ a = [1, 2]
+
+ array.pluckOneItem a, 1
+
+ a.length.should.equal 1
+ a[0].should.equal 2
+
+ array.pluckOneItem([], 1).length.should.equal 0
+
+ array.pluckOneItem([1], 2).length.should.equal 1
+
+test 'plcukByCallback', ->
+
+ a = [0, 1, 2, 3]
+
+ array.pluckByCallback a, (val, i) ->
+
+ return yes if val is 2
+
+ return no
+
+ a[0].should.equal 0
+ a[1].should.equal 1
+ a[2].should.equal 3
+
+test 'injectByCallback', ->
+
+ shouldInject = (valA, valB, toInject) ->
+
+ unless valA?
+
+ return yes if toInject <= valB
+
+ return no
+
+ unless valB?
+
+ return yes if valA <= toInject
+
+ return no
+
+ return yes if valA <= toInject <= valB
+
+ return no
+
+ a = [0.5, 1, 2.5, 2.5, 2.75, 2.75, 3]
+
+ array.injectByCallback a, 0, shouldInject
+
+ a[0].should.equal 0
+ a[1].should.equal 0.5
+ a[7].should.equal 3
+
+ a = [0.5, 1, 2.5, 2.5, 2.75, 2.75, 3]
+
+ array.injectByCallback a, 2.7, shouldInject
+
+ a[0].should.equal 0.5
+ a[4].should.equal 2.7
+ a[5].should.equal 2.75
+ a[7].should.equal 3
+
+ a = [0.5, 1, 2.5, 2.5, 2.75, 2.75, 3]
+
+ array.injectByCallback a, 3.2, shouldInject
+
+ a[0].should.equal 0.5
+ a[4].should.equal 2.75
+ a[6].should.equal 3
+ a[7].should.equal 3.2 \ No newline at end of file
diff --git a/node_modules/utila/scripts/coffee/test/object.coffee b/node_modules/utila/scripts/coffee/test/object.coffee
new file mode 100644
index 000000000..e36140c8d
--- /dev/null
+++ b/node_modules/utila/scripts/coffee/test/object.coffee
@@ -0,0 +1,233 @@
+require './_prepare'
+
+object = mod 'object'
+
+test 'isBareObject', ->
+
+ object.isBareObject('a').should.equal false
+
+ object.isBareObject({'a': 'a'}).should.equal true
+
+test 'typeOf', ->
+
+ object.typeOf('s').should.equal 'string'
+ object.typeOf(0).should.equal 'number'
+ object.typeOf(false).should.equal 'boolean'
+ object.typeOf({}).should.equal 'object'
+ object.typeOf(arguments).should.equal 'arguments'
+ object.typeOf([]).should.equal 'array'
+
+test 'empty', ->
+
+ o =
+
+ a: 1
+ b: 2
+
+
+ object.empty o
+
+ o.should.not.have.property 'a'
+ o.should.not.have.property 'b'
+
+test 'fastEmpty', ->
+
+ o =
+ a: 1
+ b: 2
+
+
+ object.fastEmpty o
+
+ o.should.not.have.property 'a'
+ o.should.not.have.property 'b'
+
+test 'clone', ->
+
+ object.clone([1])[0].should.equal 1
+ object.clone({a:1}).a.should.equal 1
+
+ o = {a: 1}
+
+ object.clone(o).should.not.equal o
+
+test 'clone [include prototype]', ->
+
+ class C
+
+ constructor: (@a) ->
+
+ sayA: -> @a + 'a'
+
+ a = new C 'a'
+
+ a.sayA().should.equal 'aa'
+
+ b = object.clone a, yes
+
+ b.should.not.equal a
+
+ b.constructor.should.equal C
+
+ b.a.should.equal 'a'
+
+ b.a = 'a2'
+
+ b.sayA().should.equal 'a2a'
+
+test 'clone [without prototype]', ->
+
+ class C
+
+ constructor: (@a) ->
+
+ sayA: -> @a + 'a'
+
+ a = new C 'a'
+
+ a.sayA().should.equal 'aa'
+
+ b = object.clone a, no
+
+ b.should.equal a
+
+test 'overrideOnto [basic]', ->
+
+ onto =
+ a: 'a'
+ b:
+ c: 'c'
+ d:
+ e: 'e'
+
+ what =
+ a: 'a2'
+ b:
+ c: 'c2'
+ d:
+ f: 'f2'
+
+ object.overrideOnto onto, what
+
+ onto.a.should.equal 'a2'
+ onto.b.should.have.property 'c'
+ onto.b.c.should.equal 'c2'
+ onto.b.d.should.not.have.property 'f'
+ onto.b.d.e.should.equal 'e'
+
+test 'override', ->
+
+ onto =
+
+ a: 'a'
+
+ b:
+
+ c: 'c'
+
+ d:
+
+ e: 'e'
+
+ what =
+
+ a: 'a2'
+
+ b:
+
+ c: 'c2'
+
+ d:
+
+ f: 'f2'
+
+
+ onto2 = object.override onto, what
+
+ onto2.a.should.equal 'a2'
+ onto2.b.should.have.property 'c'
+ onto2.b.c.should.equal 'c2'
+ onto2.b.d.should.not.have.property 'f'
+ onto2.b.d.e.should.equal 'e'
+
+ onto.should.not.equal onto2
+
+do ->
+
+ what =
+
+ a: 'a2'
+
+ c: ->
+
+ z: 'z'
+
+ y:
+
+ a: 'a'
+
+ onto =
+
+ a: 'a'
+
+ b: 'b'
+
+ test 'appendOnto [basic]', ->
+
+ object.appendOnto onto, what
+
+ onto.a.should.equal 'a2'
+ onto.b.should.equal 'b'
+ onto.z.should.equal 'z'
+
+ test "appendOnto [shallow copies instances]", ->
+
+ onto.c.should.be.instanceof Function
+ onto.c.should.equal what.c
+
+
+ test "appendOnto [clones objects]", ->
+
+ onto.should.have.property 'y'
+ onto.y.a.should.equal 'a'
+ onto.y.should.not.equal what.y
+
+test 'groupProps', ->
+
+ obj =
+
+ a1: '1'
+ a2: '2'
+
+ b1: '1'
+ b2: '2'
+
+ c1: '1'
+ c2: '2'
+
+ rest1: '1'
+ rest2: '2'
+
+ groups = object.groupProps obj,
+
+ a: ['a1', 'a2']
+
+ b: [/^b[0-9]+$/]
+
+ c: (key) -> key[0] is 'c'
+
+ groups.a.should.have.property 'a1'
+ groups.a.a1.should.equal '1'
+
+ groups.a.should.have.property 'a2'
+
+ groups.b.should.have.property 'b1'
+ groups.b.should.have.property 'b2'
+
+ groups.c.should.have.property 'c1'
+ groups.c.should.have.property 'c2'
+
+ groups.rest.should.have.property 'rest1'
+ groups.rest.should.have.property 'rest1'
+
+ groups.rest.should.not.have.property 'c1' \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/lib/Emitter.js b/node_modules/utila/scripts/js/lib/Emitter.js
new file mode 100644
index 000000000..8386c819c
--- /dev/null
+++ b/node_modules/utila/scripts/js/lib/Emitter.js
@@ -0,0 +1,144 @@
+var Emitter, array;
+
+array = require('./array');
+
+module.exports = Emitter = (function() {
+ function Emitter() {
+ this._listeners = {};
+ this._listenersForAnyEvent = [];
+ this._disabledEmitters = {};
+ }
+
+ Emitter.prototype.on = function(eventName, listener) {
+ if (this._listeners[eventName] == null) {
+ this._listeners[eventName] = [];
+ }
+ this._listeners[eventName].push(listener);
+ return this;
+ };
+
+ Emitter.prototype.once = function(eventName, listener) {
+ var cb, ran;
+ ran = false;
+ cb = (function(_this) {
+ return function() {
+ if (ran) {
+ return;
+ }
+ ran = true;
+ listener();
+ return setTimeout(function() {
+ return _this.removeEvent(eventName, cb);
+ }, 0);
+ };
+ })(this);
+ this.on(eventName, cb);
+ return this;
+ };
+
+ Emitter.prototype.onAnyEvent = function(listener) {
+ this._listenersForAnyEvent.push(listener);
+ return this;
+ };
+
+ Emitter.prototype.removeEvent = function(eventName, listener) {
+ if (this._listeners[eventName] == null) {
+ return this;
+ }
+ array.pluckOneItem(this._listeners[eventName], listener);
+ return this;
+ };
+
+ Emitter.prototype.removeListeners = function(eventName) {
+ if (this._listeners[eventName] == null) {
+ return this;
+ }
+ this._listeners[eventName].length = 0;
+ return this;
+ };
+
+ Emitter.prototype.removeAllListeners = function() {
+ var listeners, name, _ref;
+ _ref = this._listeners;
+ for (name in _ref) {
+ listeners = _ref[name];
+ listeners.length = 0;
+ }
+ return this;
+ };
+
+ Emitter.prototype._emit = function(eventName, data) {
+ var listener, _i, _j, _len, _len1, _ref, _ref1;
+ _ref = this._listenersForAnyEvent;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ listener = _ref[_i];
+ listener.call(this, data, eventName);
+ }
+ if (this._listeners[eventName] == null) {
+ return;
+ }
+ _ref1 = this._listeners[eventName];
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ listener = _ref1[_j];
+ listener.call(this, data);
+ }
+ };
+
+ Emitter.prototype._throttleEmitterMethod = function(fnName, time) {
+ var lastCallArgs, originalFn, pend, pending, runIt, timer;
+ if (time == null) {
+ time = 1000;
+ }
+ originalFn = this[fnName];
+ if (typeof originalFn !== 'function') {
+ throw Error("this class does not have a method called '" + fnName + "'");
+ }
+ lastCallArgs = null;
+ pending = false;
+ timer = null;
+ this[fnName] = (function(_this) {
+ return function() {
+ lastCallArgs = arguments;
+ return pend();
+ };
+ })(this);
+ pend = (function(_this) {
+ return function() {
+ if (pending) {
+ clearTimeout(timer);
+ }
+ timer = setTimeout(runIt, time);
+ return pending = true;
+ };
+ })(this);
+ return runIt = (function(_this) {
+ return function() {
+ pending = false;
+ return originalFn.apply(_this, lastCallArgs);
+ };
+ })(this);
+ };
+
+ Emitter.prototype._disableEmitter = function(fnName) {
+ if (this._disabledEmitters[fnName] != null) {
+ throw Error("" + fnName + " is already a disabled emitter");
+ }
+ this._disabledEmitters[fnName] = this[fnName];
+ return this[fnName] = function() {};
+ };
+
+ Emitter.prototype._enableEmitter = function(fnName) {
+ var fn;
+ fn = this._disabledEmitters[fnName];
+ if (fn == null) {
+ throw Error("" + fnName + " is not a disabled emitter");
+ }
+ this[fnName] = fn;
+ return delete this._disabledEmitters[fnName];
+ };
+
+ return Emitter;
+
+})();
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW1pdHRlci5qcyIsInNvdXJjZVJvb3QiOiIuLlxcLi4iLCJzb3VyY2VzIjpbImNvZmZlZVxcbGliXFxFbWl0dGVyLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFBLGNBQUE7O0FFQUEsS0VBQSxHRUFRLE9FQUEsQ0VBUSxTRUFSLENBQVIsQ0FBQTs7QUVFQSxNRUFNLENFQUMsT0VBUCxHRUF1QjtBRUVULEVFQUEsaUJFQUEsR0VBQTtBRUVaLElFQUEsSUVBQyxDRUFBLFVFQUQsR0VBYyxFRUFkLENFQUE7QUVBQSxJRUVBLElFQUMsQ0VBQSxxQkVBRCxHRUF5QixFRUZ6QixDRUFBO0FFQUEsSUVJQSxJRUFDLENFQUEsaUJFQUQsR0VBcUIsRUVKckIsQ0VGWTtFRUFBLENFQWI7O0FFQUEsb0JFUUEsRUVBQSxHRUFJLFNFQUMsU0VBRCxFRUFZLFFFQVosR0VBQTtBRUVILElFQUEsSUVBTyxrQ0VBUDtBRUVDLE1FQUEsSUVBQyxDRUFBLFVFQVcsQ0VBQSxTRUFBLENFQVosR0VBeUIsRUVBekIsQ0VGRDtLRUFBO0FFQUEsSUVJQSxJRUFDLENFQUEsVUVBVyxDRUFBLFNFQUEsQ0VBVSxDRUFDLElFQXZCLENFQTRCLFFFQTVCLENFSkEsQ0VBQTtXRU1BLEtFUkc7RUVBQSxDRVJKLENFQUE7O0FFQUEsb0JFa0JBLElFQUEsR0VBTSxTRUFDLFNFQUQsRUVBWSxRRUFaLEdFQUE7QUVFTCxRRUFBLE9FQUE7QUVBQSxJRUFBLEdFQUEsR0VBTSxLRUFOLENFQUE7QUVBQSxJRUVBLEVFQUEsR0VBSyxDRUFBLFNFQUEsS0VBQSxHRUFBO2FFQUEsU0VBQSxHRUFBO0FFRUosUUVBQSxJRUFVLEdFQVY7QUVBQSxnQkVBQSxDRUFBO1NFQUE7QUVBQSxRRUVBLEdFQUEsR0VBTSxJRUZOLENFQUE7QUVBQSxRRUlHLFFFQUgsQ0VBQSxDRUpBLENFQUE7ZUVNQSxVRUFBLENFQVcsU0VBQSxHRUFBO2lCRUVWLEtFQUMsQ0VBQSxXRUFELENFQWEsU0VBYixFRUF3QixFRUF4QixFRUZVO1FFQUEsQ0VBWCxFRUlFLENFSkYsRUVSSTtNRUFBLEVFQUE7SUVBQSxDRUFBLENFQUEsQ0VBQSxJRUFBLENFRkwsQ0VBQTtBRUFBLElFZ0JBLElFQUMsQ0VBQSxFRUFELENFQUksU0VBSixFRUFlLEVFQWYsQ0VoQkEsQ0VBQTtXRWtCQSxLRXBCSztFRUFBLENFbEJOLENFQUE7O0FFQUEsb0JFd0NBLFVFQUEsR0VBWSxTRUFDLFFFQUQsR0VBQTtBRUVYLElFQUEsSUVBQyxDRUFBLHFCRUFxQixDRUFDLElFQXZCLENFQTRCLFFFQTVCLENFQUEsQ0VBQTtXRUVBLEtFSlc7RUVBQSxDRXhDWixDRUFBOztBRUFBLG9CRThDQSxXRUFBLEdFQWEsU0VBQyxTRUFELEVFQVksUUVBWixHRUFBO0FFRVosSUVBQSxJRUFnQixrQ0VBaEI7QUVBQSxhRUFPLElFQVAsQ0VBQTtLRUFBO0FFQUEsSUVFQSxLRUFLLENFQUMsWUVBTixDRUFtQixJRUFDLENFQUEsVUVBVyxDRUFBLFNFQUEsQ0VBL0IsRUVBMkMsUUVBM0MsQ0VGQSxDRUFBO1dFSUEsS0VOWTtFRUFBLENFOUNiLENFQUE7O0FFQUEsb0JFc0RBLGVFQUEsR0VBaUIsU0VBQyxTRUFELEdFQUE7QUVFaEIsSUVBQSxJRUFnQixrQ0VBaEI7QUVBQSxhRUFPLElFQVAsQ0VBQTtLRUFBO0FFQUEsSUVFQSxJRUFDLENFQUEsVUVBVyxDRUFBLFNFQUEsQ0VBVSxDRUFDLE1FQXZCLEdFQWdDLENFRmhDLENFQUE7V0VJQSxLRU5nQjtFRUFBLENFdERqQixDRUFBOztBRUFBLG9CRThEQSxrQkVBQSxHRUFvQixTRUFBLEdFQUE7QUVFbkIsUUVBQSxxQkVBQTtBRUFBO0FFQUEsU0VBQSxZRUFBOzZCRUFBO0FFRUMsTUVBQSxTRUFTLENFQUMsTUVBVixHRUFtQixDRUFuQixDRUZEO0FFQUEsS0VBQTtXRUlBLEtFTm1CO0VFQUEsQ0U5RHBCLENFQUE7O0FFQUEsb0JFc0VBLEtFQUEsR0VBTyxTRUFDLFNFQUQsRUVBWSxJRUFaLEdFQUE7QUVFTixRRUFBLDBDRUFBO0FFQUE7QUVBQSxTRUFBLDJDRUFBOzBCRUFBO0FFRUMsTUVBQSxRRUFRLENFQUMsSUVBVCxDRUFjLElFQWQsRUVBaUIsSUVBakIsRUVBdUIsU0VBdkIsQ0VBQSxDRUZEO0FFQUEsS0VBQTtBRUlBLElFQUEsSUVBYyxrQ0VBZDtBRUFBLFlFQUEsQ0VBQTtLRUpBO0FFTUE7QUVBQSxTRUFBLDhDRUFBOzJCRUFBO0FFRUMsTUVBQSxRRUFRLENFQUMsSUVBVCxDRUFjLElFQWQsRUVBaUIsSUVBakIsQ0VBQSxDRUZEO0FFQUEsS0VSTTtFRUFBLENFdEVQLENFQUE7O0FFQUEsb0JFc0ZBLHNCRUFBLEdFQXdCLFNFQUMsTUVBRCxFRUFTLElFQVQsR0VBQTtBRUV2QixRRUFBLHFERUFBOztNRUZnQyxPRUFPO0tFRXZDO0FFQUEsSUVBQSxVRUFBLEdFQWEsSUVBRSxDRUFBLE1FQUEsQ0VBZixDRUFBO0FFRUEsSUVBQSxJRUFHLE1FQUEsQ0VBTyxVRUFQLEtFQXVCLFVFQTFCO0FFRUMsWUVBTSxLRUFBLENFQU8sNENFQUEsR0VBMkMsTUVBM0MsR0VBbUQsR0VBMUQsQ0VBTixDRUZEO0tFRkE7QUVBQSxJRU1BLFlFQUEsR0VBZSxJRU5mLENFQUE7QUVBQSxJRU9BLE9FQUEsR0VBVSxLRVBWLENFQUE7QUVBQSxJRVFBLEtFQUEsR0VBUSxJRVJSLENFQUE7QUVBQSxJRVVBLElFQUUsQ0VBQSxNRUFBLENFQUYsR0VBWSxDRUFBLFNFQUEsS0VBQSxHRUFBO2FFQUEsU0VBQSxHRUFBO0FFRVgsUUVBQSxZRUFBLEdFQWUsU0VBZixDRUFBO2VFRUcsSUVBSCxDRUFBLEVFSlc7TUVBQSxFRUFBO0lFQUEsQ0VBQSxDRUFBLENFQUEsSUVBQSxDRVZaLENFQUE7QUVBQSxJRWdCQSxJRUFBLEdFQU8sQ0VBQSxTRUFBLEtFQUEsR0VBQTthRUFBLFNFQUEsR0VBQTtBRUVOLFFFQUEsSUVBRyxPRUFIO0FFRUMsVUVBQSxZRUFBLENFQWEsS0VBYixDRUFBLENFRkQ7U0VBQTtBRUFBLFFFSUEsS0VBQSxHRUFRLFVFQUEsQ0VBVyxLRUFYLEVFQWtCLElFQWxCLENFSlIsQ0VBQTtlRU1BLE9FQUEsR0VBVSxLRVJKO01FQUEsRUVBQTtJRUFBLENFQUEsQ0VBQSxDRUFBLElFQUEsQ0VoQlAsQ0VBQTtXRTBCQSxLRUFBLEdFQVEsQ0VBQSxTRUFBLEtFQUEsR0VBQTthRUFBLFNFQUEsR0VBQTtBRUVQLFFFQUEsT0VBQSxHRUFVLEtFQVYsQ0VBQTtlRUVBLFVFQVUsQ0VBQyxLRUFYLENFQWlCLEtFQWpCLEVFQW9CLFlFQXBCLEVFSk87TUVBQSxFRUFBO0lFQUEsQ0VBQSxDRUFBLENFQUEsSUVBQSxFRTVCZTtFRUFBLENFdEZ4QixDRUFBOztBRUFBLG9CRXdIQSxlRUFBLEdFQWlCLFNFQUMsTUVBRCxHRUFBO0FFRWhCLElFQUEsSUVBRyxzQ0VBSDtBRUVDLFlFQU0sS0VBQSxDRUFNLEVFQUEsR0VBRSxNRUFGLEdFQVUsZ0NFQWhCLENFQU4sQ0VGRDtLRUFBO0FFQUEsSUVJQSxJRUFDLENFQUEsaUJFQWtCLENFQUEsTUVBQSxDRUFuQixHRUE2QixJRUFFLENFQUEsTUVBQSxDRUovQixDRUFBO1dFTUEsSUVBRSxDRUFBLE1FQUEsQ0VBRixHRUFZLFNFQUEsR0VBQSxFRVJJO0VFQUEsQ0V4SGpCLENFQUE7O0FFQUEsb0JFa0lBLGNFQUEsR0VBZ0IsU0VBQyxNRUFELEdFQUE7QUVFZixRRUFBLEVFQUE7QUVBQSxJRUFBLEVFQUEsR0VBSyxJRUFDLENFQUEsaUJFQWtCLENFQUEsTUVBQSxDRUF4QixDRUFBO0FFRUEsSUVBQSxJRUFPLFVFQVA7QUVFQyxZRUFNLEtFQUEsQ0VBTSxFRUFBLEdFQUUsTUVBRixHRUFVLDRCRUFoQixDRUFOLENFRkQ7S0VGQTtBRUFBLElFTUEsSUVBRSxDRUFBLE1FQUEsQ0VBRixHRUFZLEVFTlosQ0VBQTtXRVFBLE1FQUEsQ0VBTyxJRUFDLENFQUEsaUJFQWtCLENFQUEsTUVBQSxFRVZYO0VFQUEsQ0VsSWhCLENFQUE7O2lCRUFBOztJQUpELENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IGFycmF5ID1cblxuXHQjIyNcblx0VHJpZXMgdG8gdHVybiBhbnl0aGluZyBpbnRvIGFuIGFycmF5LlxuXHQjIyNcblx0ZnJvbTogKHIpIC0+XG5cblx0XHRBcnJheTo6c2xpY2UuY2FsbCByXG5cblx0IyMjXG5cdENsb25lIG9mIGFuIGFycmF5LiBQcm9wZXJ0aWVzIHdpbGwgYmUgc2hhbGxvdyBjb3BpZXMuXG5cdCMjI1xuXHRzaW1wbGVDbG9uZTogKGEpIC0+XG5cblx0XHRhLnNsaWNlIDBcblxuXHRzaGFsbG93RXF1YWw6IChhMSwgYTIpIC0+XG5cblx0XHRyZXR1cm4gbm8gdW5sZXNzIEFycmF5LmlzQXJyYXkoYTEpIGFuZCBBcnJheS5pc0FycmF5KGEyKSBhbmQgYTEubGVuZ3RoIGlzIGEyLmxlbmd0aFxuXG5cdFx0Zm9yIHZhbCwgaSBpbiBhMVxuXG5cdFx0XHRyZXR1cm4gbm8gdW5sZXNzIGEyW2ldIGlzIHZhbFxuXG5cdFx0eWVzXG5cblx0cGx1Y2s6IChhLCBpKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBpbmRleCA+IGlcblxuXHRcdFx0XHRhW2luZGV4IC0gMV0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIDFcblxuXHRcdGFcblxuXHRwbHVja0l0ZW06IChhLCBpdGVtKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblxuXHRcdHJlbW92ZWQgPSAwXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgdmFsdWUgaXMgaXRlbVxuXG5cdFx0XHRcdHJlbW92ZWQrK1xuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGlmIHJlbW92ZWQgaXNudCAwXG5cblx0XHRcdFx0YVtpbmRleCAtIHJlbW92ZWRdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSByZW1vdmVkIGlmIHJlbW92ZWQgPiAwXG5cblx0XHRhXG5cblx0cGx1Y2tPbmVJdGVtOiAoYSwgaXRlbSkgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cdFx0cmVhY2hlZCA9IG5vXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgbm90IHJlYWNoZWRcblxuXHRcdFx0XHRpZiB2YWx1ZSBpcyBpdGVtXG5cblx0XHRcdFx0XHRyZWFjaGVkID0geWVzXG5cblx0XHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRlbHNlXG5cblx0XHRcdFx0YVtpbmRleCAtIDFdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSAxIGlmIHJlYWNoZWRcblxuXHRcdGFcblxuXHRwbHVja0J5Q2FsbGJhY2s6IChhLCBjYikgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cdFx0cmVtb3ZlZCA9IDBcblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBjYiB2YWx1ZSwgaW5kZXhcblxuXHRcdFx0XHRyZW1vdmVkKytcblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRpZiByZW1vdmVkIGlzbnQgMFxuXG5cdFx0XHRcdGFbaW5kZXggLSByZW1vdmVkXSA9IGFbaW5kZXhdXG5cblx0XHRpZiByZW1vdmVkID4gMFxuXG5cdFx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gcmVtb3ZlZFxuXG5cdFx0YVxuXG5cdHBsdWNrTXVsdGlwbGU6IChhcnJheSwgaW5kZXhlc1RvUmVtb3ZlKSAtPlxuXG5cdFx0cmV0dXJuIGFycmF5IGlmIGFycmF5Lmxlbmd0aCA8IDFcblxuXHRcdHJlbW92ZWRTb0ZhciA9IDBcblxuXHRcdGluZGV4ZXNUb1JlbW92ZS5zb3J0KClcblxuXHRcdGZvciBpIGluIGluZGV4ZXNUb1JlbW92ZVxuXG5cdFx0XHRAcGx1Y2sgYXJyYXksIGkgLSByZW1vdmVkU29GYXJcblxuXHRcdFx0cmVtb3ZlZFNvRmFyKytcblxuXHRcdGFycmF5XG5cblx0aW5qZWN0QnlDYWxsYmFjazogKGEsIHRvSW5qZWN0LCBzaG91bGRJbmplY3QpIC0+XG5cblx0XHR2YWxBID0gbnVsbFxuXG5cdFx0dmFsQiA9IG51bGxcblxuXHRcdGxlbiA9IGEubGVuZ3RoXG5cblx0XHRpZiBsZW4gPCAxXG5cblx0XHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0XHRyZXR1cm4gYVxuXG5cblx0XHRmb3IgdmFsLCBpIGluIGFcblxuXHRcdFx0dmFsQSA9IHZhbEJcblxuXHRcdFx0dmFsQiA9IHZhbFxuXG5cdFx0XHRpZiBzaG91bGRJbmplY3QgdmFsQSwgdmFsQiwgdG9JbmplY3RcblxuXHRcdFx0XHRyZXR1cm4gYS5zcGxpY2UgaSwgMCwgdG9JbmplY3RcblxuXHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0YVxuXG5cdGluamVjdEluSW5kZXg6IChhLCBpbmRleCwgdG9JbmplY3QpIC0+XG5cblx0XHRsZW4gPSBhLmxlbmd0aFxuXG5cdFx0aSA9IGluZGV4XG5cblx0XHRpZiBsZW4gPCAxXG5cblx0XHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0XHRyZXR1cm4gYVxuXG5cdFx0dG9QdXQgPSB0b0luamVjdFxuXG5cdFx0dG9QdXROZXh0ID0gbnVsbFxuXG5cdFx0YGZvcig7IGkgPD0gbGVuOyBpKyspe1xuXG5cdFx0XHR0b1B1dE5leHQgPSBhW2ldO1xuXG5cdFx0XHRhW2ldID0gdG9QdXQ7XG5cblx0XHRcdHRvUHV0ID0gdG9QdXROZXh0O1xuXG5cdFx0fWBcblxuXHRcdCMgYVtpXSA9IHRvUHV0XG5cblx0XHRudWxsIiwibW9kdWxlLmV4cG9ydHMgPSBjbGFzc2ljID0ge31cblxuIyBMaXR0bGUgaGVscGVyIGZvciBtaXhpbnMgZnJvbSBDb2ZmZWVTY3JpcHQgRkFRLFxuIyBjb3VydGVzeSBvZiBTZXRoYXVydXMgKGh0dHA6Ly9naXRodWIuY29tL3NldGhhdXJ1cylcbmNsYXNzaWMuaW1wbGVtZW50ID0gKG1peGlucy4uLiwgY2xhc3NSZWZlcmVuY2UpIC0+XG5cblx0Zm9yIG1peGluIGluIG1peGluc1xuXG5cdFx0Y2xhc3NQcm90byA9IGNsYXNzUmVmZXJlbmNlOjpcblxuXHRcdGZvciBtZW1iZXIgb2YgbWl4aW46OlxuXG5cdFx0XHR1bmxlc3MgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBjbGFzc1Byb3RvLCBtZW1iZXJcblxuXHRcdFx0XHRkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBtaXhpbjo6LCBtZW1iZXJcblxuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkgY2xhc3NQcm90bywgbWVtYmVyLCBkZXNjXG5cblx0Y2xhc3NSZWZlcmVuY2VcblxuY2xhc3NpYy5taXggPSAobWl4aW5zLi4uLCBjbGFzc1JlZmVyZW5jZSkgLT5cblxuXHRjbGFzc1Byb3RvID0gY2xhc3NSZWZlcmVuY2U6OlxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzID0gW11cblxuXHRjbGFzc1JlZmVyZW5jZS5fX2FwcGx5Q2xvbmVyc0ZvciA9IChpbnN0YW5jZSwgYXJncyA9IG51bGwpIC0+XG5cblx0XHRmb3IgY2xvbmVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzXG5cblx0XHRcdGNsb25lci5hcHBseSBpbnN0YW5jZSwgYXJnc1xuXG5cdFx0cmV0dXJuXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkluaXRpYWxpemVycyA9IFtdXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19pbml0TWl4aW5zRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBpbml0aWFsaXplciBpbiBjbGFzc1JlZmVyZW5jZS5fX21peGluSW5pdGlhbGl6ZXJzXG5cblx0XHRcdGluaXRpYWxpemVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRjbGFzc1JlZmVyZW5jZS5fX21peGluUXVpdHRlcnMgPSBbXVxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fYXBwbHlRdWl0dGVyc0ZvciA9IChpbnN0YW5jZSwgYXJncyA9IG51bGwpIC0+XG5cblx0XHRmb3IgcXVpdHRlciBpbiBjbGFzc1JlZmVyZW5jZS5fX21peGluUXVpdHRlcnNcblxuXHRcdFx0cXVpdHRlci5hcHBseSBpbnN0YW5jZSwgYXJnc1xuXG5cdFx0cmV0dXJuXG5cblx0Zm9yIG1peGluIGluIG1peGluc1xuXG5cdFx0dW5sZXNzIG1peGluLmNvbnN0cnVjdG9yIGluc3RhbmNlb2YgRnVuY3Rpb25cblxuXHRcdFx0dGhyb3cgRXJyb3IgXCJNaXhpbiBzaG91bGQgYmUgYSBmdW5jdGlvblwiXG5cblx0XHRmb3IgbWVtYmVyIG9mIG1peGluOjpcblxuXHRcdFx0aWYgbWVtYmVyLnN1YnN0cigwLCAxMSkgaXMgJ19faW5pdE1peGluJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5Jbml0aWFsaXplcnMucHVzaCBtaXhpbjo6W21lbWJlcl1cblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRlbHNlIGlmIG1lbWJlci5zdWJzdHIoMCwgMTEpIGlzICdfX2Nsb25lckZvcidcblxuXHRcdFx0XHRjbGFzc1JlZmVyZW5jZS5fX21peGluQ2xvbmVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2UgaWYgbWVtYmVyLnN1YnN0cigwLCAxMikgaXMgJ19fcXVpdHRlckZvcidcblxuXHRcdFx0XHRjbGFzc1JlZmVyZW5jZS5fX21peGluUXVpdHRlcnMucHVzaCBtaXhpbjo6W21lbWJlcl1cblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHR1bmxlc3MgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBjbGFzc1Byb3RvLCBtZW1iZXJcblxuXHRcdFx0XHRkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBtaXhpbjo6LCBtZW1iZXJcblxuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkgY2xhc3NQcm90bywgbWVtYmVyLCBkZXNjXG5cblx0Y2xhc3NSZWZlcmVuY2UiLCJhcnJheSA9IHJlcXVpcmUgJy4vYXJyYXknXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYXNzIEVtaXR0ZXJcclxuXHJcblx0Y29uc3RydWN0b3I6IC0+XHJcblxyXG5cdFx0QF9saXN0ZW5lcnMgPSB7fVxyXG5cclxuXHRcdEBfbGlzdGVuZXJzRm9yQW55RXZlbnQgPSBbXVxyXG5cclxuXHRcdEBfZGlzYWJsZWRFbWl0dGVycyA9IHt9XHJcblxyXG5cdG9uOiAoZXZlbnROYW1lLCBsaXN0ZW5lcikgLT5cclxuXHJcblx0XHR1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRcdEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0gPSBbXVxyXG5cclxuXHRcdEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0ucHVzaCBsaXN0ZW5lclxyXG5cclxuXHRcdEBcclxuXHJcblx0b25jZTogKGV2ZW50TmFtZSwgbGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0cmFuID0gbm9cclxuXHJcblx0XHRjYiA9ID0+XHJcblxyXG5cdFx0XHRyZXR1cm4gaWYgcmFuXHJcblxyXG5cdFx0XHRyYW4gPSB5ZXNcclxuXHJcblx0XHRcdGRvIGxpc3RlbmVyXHJcblxyXG5cdFx0XHRzZXRUaW1lb3V0ID0+XHJcblxyXG5cdFx0XHRcdEByZW1vdmVFdmVudCBldmVudE5hbWUsIGNiXHJcblxyXG5cdFx0XHQsIDBcclxuXHJcblx0XHRAb24gZXZlbnROYW1lLCBjYlxyXG5cclxuXHRcdEBcclxuXHJcblx0b25BbnlFdmVudDogKGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdEBfbGlzdGVuZXJzRm9yQW55RXZlbnQucHVzaCBsaXN0ZW5lclxyXG5cclxuXHRcdEBcclxuXHJcblx0cmVtb3ZlRXZlbnQ6IChldmVudE5hbWUsIGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdHJldHVybiBAIHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdGFycmF5LnBsdWNrT25lSXRlbSBAX2xpc3RlbmVyc1tldmVudE5hbWVdLCBsaXN0ZW5lclxyXG5cclxuXHRcdEBcclxuXHJcblx0cmVtb3ZlTGlzdGVuZXJzOiAoZXZlbnROYW1lKSAtPlxyXG5cclxuXHRcdHJldHVybiBAIHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0ubGVuZ3RoID0gMFxyXG5cclxuXHRcdEBcclxuXHJcblx0cmVtb3ZlQWxsTGlzdGVuZXJzOiAtPlxyXG5cclxuXHRcdGZvciBuYW1lLCBsaXN0ZW5lcnMgb2YgQF9saXN0ZW5lcnNcclxuXHJcblx0XHRcdGxpc3RlbmVycy5sZW5ndGggPSAwXHJcblxyXG5cdFx0QFxyXG5cclxuXHRfZW1pdDogKGV2ZW50TmFtZSwgZGF0YSkgLT5cclxuXHJcblx0XHRmb3IgbGlzdGVuZXIgaW4gQF9saXN0ZW5lcnNGb3JBbnlFdmVudFxyXG5cclxuXHRcdFx0bGlzdGVuZXIuY2FsbCBALCBkYXRhLCBldmVudE5hbWVcclxuXHJcblx0XHRyZXR1cm4gdW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0Zm9yIGxpc3RlbmVyIGluIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV1cclxuXHJcblx0XHRcdGxpc3RlbmVyLmNhbGwgQCwgZGF0YVxyXG5cclxuXHRcdHJldHVyblxyXG5cclxuXHQjIHRoaXMgbWFrZXMgc3VyZSB0aGF0IGFsbCB0aGUgY2FsbHMgdG8gdGhpcyBjbGFzcydzIG1ldGhvZCAnZm5OYW1lJ1xyXG5cdCMgYXJlIHRocm90dGxlZFxyXG5cdF90aHJvdHRsZUVtaXR0ZXJNZXRob2Q6IChmbk5hbWUsIHRpbWUgPSAxMDAwKSAtPlxyXG5cclxuXHRcdG9yaWdpbmFsRm4gPSBAW2ZuTmFtZV1cclxuXHJcblx0XHRpZiB0eXBlb2Ygb3JpZ2luYWxGbiBpc250ICdmdW5jdGlvbidcclxuXHJcblx0XHRcdHRocm93IEVycm9yIFwidGhpcyBjbGFzcyBkb2VzIG5vdCBoYXZlIGEgbWV0aG9kIGNhbGxlZCAnI3tmbk5hbWV9J1wiXHJcblxyXG5cdFx0bGFzdENhbGxBcmdzID0gbnVsbFxyXG5cdFx0cGVuZGluZyA9IG5vXHJcblx0XHR0aW1lciA9IG51bGxcclxuXHJcblx0XHRAW2ZuTmFtZV0gPSA9PlxyXG5cclxuXHRcdFx0bGFzdENhbGxBcmdzID0gYXJndW1lbnRzXHJcblxyXG5cdFx0XHRkbyBwZW5kXHJcblxyXG5cdFx0cGVuZCA9ID0+XHJcblxyXG5cdFx0XHRpZiBwZW5kaW5nXHJcblxyXG5cdFx0XHRcdGNsZWFyVGltZW91dCB0aW1lclxyXG5cclxuXHRcdFx0dGltZXIgPSBzZXRUaW1lb3V0IHJ1bkl0LCB0aW1lXHJcblxyXG5cdFx0XHRwZW5kaW5nID0geWVzXHJcblxyXG5cdFx0cnVuSXQgPSA9PlxyXG5cclxuXHRcdFx0cGVuZGluZyA9IG5vXHJcblxyXG5cdFx0XHRvcmlnaW5hbEZuLmFwcGx5IEAsIGxhc3RDYWxsQXJnc1xyXG5cclxuXHRfZGlzYWJsZUVtaXR0ZXI6IChmbk5hbWUpIC0+XHJcblxyXG5cdFx0aWYgQF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV0/XHJcblxyXG5cdFx0XHR0aHJvdyBFcnJvciBcIiN7Zm5OYW1lfSBpcyBhbHJlYWR5IGEgZGlzYWJsZWQgZW1pdHRlclwiXHJcblxyXG5cdFx0QF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV0gPSBAW2ZuTmFtZV1cclxuXHJcblx0XHRAW2ZuTmFtZV0gPSAtPlxyXG5cclxuXHRfZW5hYmxlRW1pdHRlcjogKGZuTmFtZSkgLT5cclxuXHJcblx0XHRmbiA9IEBfZGlzYWJsZWRFbWl0dGVyc1tmbk5hbWVdXHJcblxyXG5cdFx0dW5sZXNzIGZuP1xyXG5cclxuXHRcdFx0dGhyb3cgRXJyb3IgXCIje2ZuTmFtZX0gaXMgbm90IGEgZGlzYWJsZWQgZW1pdHRlclwiXHJcblxyXG5cdFx0QFtmbk5hbWVdID0gZm5cclxuXHJcblx0XHRkZWxldGUgQF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV0iXX0= \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/lib/_common.js b/node_modules/utila/scripts/js/lib/_common.js
new file mode 100644
index 000000000..c9747ddb8
--- /dev/null
+++ b/node_modules/utila/scripts/js/lib/_common.js
@@ -0,0 +1,112 @@
+var common;
+
+module.exports = common = {
+
+ /*
+ Checks to see if o is an object, and it isn't an instance
+ of some class.
+ */
+ isBareObject: function(o) {
+ if ((o != null) && o.constructor === Object) {
+ return true;
+ }
+ return false;
+ },
+
+ /*
+ Returns type of an object, including:
+ undefined, null, string, number, array,
+ arguments, element, textnode, whitespace, and object
+ */
+ typeOf: function(item) {
+ var _ref;
+ if (item === null) {
+ return 'null';
+ }
+ if (typeof item !== 'object') {
+ return typeof item;
+ }
+ if (Array.isArray(item)) {
+ return 'array';
+ }
+ if (item.nodeName) {
+ if (item.nodeType === 1) {
+ return 'element';
+ }
+ if (item.nodeType === 3) {
+ return (_ref = /\S/.test(item.nodeValue)) != null ? _ref : {
+ 'textnode': 'whitespace'
+ };
+ }
+ } else if (typeof item.length === 'number') {
+ if (item.callee) {
+ return 'arguments';
+ }
+ }
+ return typeof item;
+ },
+ clone: function(item, includePrototype) {
+ if (includePrototype == null) {
+ includePrototype = false;
+ }
+ switch (common.typeOf(item)) {
+ case 'array':
+ return common._cloneArray(item, includePrototype);
+ case 'object':
+ return common._cloneObject(item, includePrototype);
+ default:
+ return item;
+ }
+ },
+
+ /*
+ Deep clone of an object.
+ From MooTools
+ */
+ _cloneObject: function(o, includePrototype) {
+ var clone, key;
+ if (includePrototype == null) {
+ includePrototype = false;
+ }
+ if (common.isBareObject(o)) {
+ clone = {};
+ for (key in o) {
+ clone[key] = common.clone(o[key], includePrototype);
+ }
+ return clone;
+ } else {
+ if (!includePrototype) {
+ return o;
+ }
+ if (o instanceof Function) {
+ return o;
+ }
+ clone = Object.create(o.constructor.prototype);
+ for (key in o) {
+ if (o.hasOwnProperty(key)) {
+ clone[key] = common.clone(o[key], includePrototype);
+ }
+ }
+ return clone;
+ }
+ },
+
+ /*
+ Deep clone of an array.
+ From MooTools
+ */
+ _cloneArray: function(a, includePrototype) {
+ var clone, i;
+ if (includePrototype == null) {
+ includePrototype = false;
+ }
+ i = a.length;
+ clone = new Array(i);
+ while (i--) {
+ clone[i] = common.clone(a[i], includePrototype);
+ }
+ return clone;
+ }
+};
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NvbW1vbi5qcyIsInNvdXJjZVJvb3QiOiIuLlxcLi4iLCJzb3VyY2VzIjpbImNvZmZlZVxcbGliXFxfY29tbW9uLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFBLE1BQUE7O0FNQUEsTU1BTSxDTUFDLE9NQVAsR01BaUIsTU1BQSxHTUVoQjtBTUFBO0FNQUE7OztLTUFBO0FNQUEsRU1JQSxZTUFBLEVNQWMsU01BQyxDTUFELEdNQUE7QU1FYixJTUFBLElNQUcsV01BQSxJTUFPLENNQUMsQ01BQyxXTUFGLEtNQWlCLE1NQTNCO0FNRUMsYU1BTyxJTUFQLENNRkQ7S01BQTtXTUlBLE1NTmE7RU1BQSxDTUpkO0FNWUE7QU1BQTs7OztLTVpBO0FNQUEsRU1pQkEsTU1BQSxFTUFRLFNNQUMsSU1BRCxHTUFBO0FNRVAsUU1BQSxJTUFBO0FNQUEsSU1BQSxJTUFpQixJTUFBLEtNQVEsSU1BekI7QU1BQSxhTUFPLE1NQVAsQ01BQTtLTUFBO0FNRUEsSU1BQSxJTUFzQixNTUFBLENNQU8sSU1BUCxLTUFpQixRTUF2QztBTUFBLGFNQU8sTU1BQSxDTUFPLElNQWQsQ01BQTtLTUZBO0FNSUEsSU1BQSxJTUFrQixLTUFLLENNQUMsT01BTixDTUFjLElNQWQsQ01BbEI7QU1BQSxhTUFPLE9NQVAsQ01BQTtLTUpBO0FNUUEsSU1BQSxJTUFHLElNQUksQ01BQyxRTUFSO0FNRUMsTU1BQSxJTUFHLElNQUksQ01BQyxRTUFMLEtNQWlCLENNQXBCO0FNQTJCLGVNQU8sU01BUCxDTUEzQjtPTUFBO0FNQ0EsTU1BQSxJTUFHLElNQUksQ01BQyxRTUFMLEtNQWlCLENNQXBCO0FNQTJCLG1FTUFxQztBTUFBLFVNQUEsVU1BQSxFTUFhLFlNQWI7U01BckMsQ01BM0I7T01IRDtLTUFBLE1NS0ssSU1BRyxNTUFBLENNQU8sSU1BSSxDTUFDLE1NQVosS01Bc0IsUU1BekI7QU1FSixNTUFBLElNQUcsSU1BSSxDTUFDLE1NQVI7QU1Bb0IsZU1BTyxXTUFQLENNQXBCO09NRkk7S01iTDtBTWlCQSxXTUFPLE1NQUEsQ01BTyxJTUFkLENNbkJPO0VNQUEsQ01qQlI7QU1BQSxFTXdDQSxLTUFBLEVNQU8sU01BQyxJTUFELEVNQU8sZ0JNQVAsR01BQTs7TU1BTyxtQk1BbUI7S01FaEM7QU1BQSxZTUFPLE1NQU0sQ01BQyxNTUFQLENNQWMsSU1BZCxDTUFQO0FNQUEsV01FTSxPTUZOO0FNRW1CLGVNQU8sTU1BTSxDTUFDLFdNQVAsQ01BbUIsSU1BbkIsRU1BeUIsZ0JNQXpCLENNQVAsQ01GbkI7QU1BQSxXTUlNLFFNSk47QU1Jb0IsZU1BTyxNTUFNLENNQUMsWU1BUCxDTUFvQixJTUFwQixFTUEwQixnQk1BMUIsQ01BUCxDTUpwQjtBTUFBO0FNTU0sZU1BTyxJTUFQLENNTk47QU1BQSxLTUZNO0VNQUEsQ014Q1A7QU1rREE7QU1BQTs7O0tNbERBO0FNQUEsRU1zREEsWU1BQSxFTUFjLFNNQUMsQ01BRCxFTUFJLGdCTUFKLEdNQUE7QU1FYixRTUFBLFVNQUE7O01NRmlCLG1CTUFtQjtLTUVwQztBTUFBLElNQUEsSU1BRyxNTUFNLENNQUMsWU1BUCxDTUFvQixDTUFwQixDTUFIO0FNRUMsTU1BQSxLTUFBLEdNQVEsRU1BUixDTUFBO0FNRUEsV01BQSxRTUFBLEdNQUE7QU1FQyxRTUFBLEtNQU0sQ01BQSxHTUFBLENNQU4sR01BYSxNTUFNLENNQUMsS01BUCxDTUFhLENNQUUsQ01BQSxHTUFBLENNQWYsRU1BcUIsZ0JNQXJCLENNQWIsQ01GRDtBTUFBLE9NRkE7QU1NQSxhTUFPLEtNQVAsQ01SRDtLTUFBLE1NQUE7QU1ZQyxNTUFBLElNQUEsQ01BZ0IsZ0JNQWhCO0FNQUEsZU1BTyxDTUFQLENNQUE7T01BQTtBTUVBLE1NQUEsSU1BWSxDTUFBLFlNQWEsUU1BekI7QU1BQSxlTUFPLENNQVAsQ01BQTtPTUZBO0FNQUEsTU1JQSxLTUFBLEdNQVEsTU1BTSxDTUFDLE1NQVAsQ01BYyxDTUFDLENNQUMsV01BVyxDTUFDLFNNQTVCLENNSlIsQ01BQTtBTU1BLFdNQUEsUU1BQSxHTUFBO0FNRUMsUU1BQSxJTUFHLENNQUMsQ01BQyxjTUFGLENNQWlCLEdNQWpCLENNQUg7QU1FQyxVTUFBLEtNQU0sQ01BQSxHTUFBLENNQU4sR01BYSxNTUFNLENNQUMsS01BUCxDTUFhLENNQUUsQ01BQSxHTUFBLENNQWYsRU1BcUIsZ0JNQXJCLENNQWIsQ01GRDtTTUZEO0FNQUEsT01OQTthTVlBLE1NeEJEO0tNRmE7RU1BQSxDTXREZDtBTWtGQTtBTUFBOzs7S01sRkE7QU1BQSxFTXNGQSxXTUFBLEVNQWEsU01BQyxDTUFELEVNQUksZ0JNQUosR01BQTtBTUVaLFFNQUEsUU1BQTs7TU1GZ0IsbUJNQW1CO0tNRW5DO0FNQUEsSU1BQSxDTUFBLEdNQUksQ01BQyxDTUFDLE1NQU4sQ01BQTtBTUFBLElNRUEsS01BQSxHTUFZLElNQUEsS01BQSxDTUFNLENNQU4sQ01GWixDTUFBO0FNSUEsV01BTSxDTUFBLEVNQU4sR01BQTtBTUVDLE1NQUEsS01BTSxDTUFBLENNQUEsQ01BTixHTUFXLE1NQU0sQ01BQyxLTUFQLENNQWEsQ01BRSxDTUFBLENNQUEsQ01BZixFTUFtQixnQk1BbkIsQ01BWCxDTUZEO0lNQUEsQ01KQTtXTVFBLE1NVlk7RU1BQSxDTXRGYjtDQUZELENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IGFycmF5ID1cblxuXHQjIyNcblx0VHJpZXMgdG8gdHVybiBhbnl0aGluZyBpbnRvIGFuIGFycmF5LlxuXHQjIyNcblx0ZnJvbTogKHIpIC0+XG5cblx0XHRBcnJheTo6c2xpY2UuY2FsbCByXG5cblx0IyMjXG5cdENsb25lIG9mIGFuIGFycmF5LiBQcm9wZXJ0aWVzIHdpbGwgYmUgc2hhbGxvdyBjb3BpZXMuXG5cdCMjI1xuXHRzaW1wbGVDbG9uZTogKGEpIC0+XG5cblx0XHRhLnNsaWNlIDBcblxuXHRzaGFsbG93RXF1YWw6IChhMSwgYTIpIC0+XG5cblx0XHRyZXR1cm4gbm8gdW5sZXNzIEFycmF5LmlzQXJyYXkoYTEpIGFuZCBBcnJheS5pc0FycmF5KGEyKSBhbmQgYTEubGVuZ3RoIGlzIGEyLmxlbmd0aFxuXG5cdFx0Zm9yIHZhbCwgaSBpbiBhMVxuXG5cdFx0XHRyZXR1cm4gbm8gdW5sZXNzIGEyW2ldIGlzIHZhbFxuXG5cdFx0eWVzXG5cblx0cGx1Y2s6IChhLCBpKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBpbmRleCA+IGlcblxuXHRcdFx0XHRhW2luZGV4IC0gMV0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIDFcblxuXHRcdGFcblxuXHRwbHVja0l0ZW06IChhLCBpdGVtKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblxuXHRcdHJlbW92ZWQgPSAwXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgdmFsdWUgaXMgaXRlbVxuXG5cdFx0XHRcdHJlbW92ZWQrK1xuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGlmIHJlbW92ZWQgaXNudCAwXG5cblx0XHRcdFx0YVtpbmRleCAtIHJlbW92ZWRdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSByZW1vdmVkIGlmIHJlbW92ZWQgPiAwXG5cblx0XHRhXG5cblx0cGx1Y2tPbmVJdGVtOiAoYSwgaXRlbSkgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cdFx0cmVhY2hlZCA9IG5vXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgbm90IHJlYWNoZWRcblxuXHRcdFx0XHRpZiB2YWx1ZSBpcyBpdGVtXG5cblx0XHRcdFx0XHRyZWFjaGVkID0geWVzXG5cblx0XHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRlbHNlXG5cblx0XHRcdFx0YVtpbmRleCAtIDFdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSAxIGlmIHJlYWNoZWRcblxuXHRcdGFcblxuXHRwbHVja0J5Q2FsbGJhY2s6IChhLCBjYikgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cdFx0cmVtb3ZlZCA9IDBcblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBjYiB2YWx1ZSwgaW5kZXhcblxuXHRcdFx0XHRyZW1vdmVkKytcblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRpZiByZW1vdmVkIGlzbnQgMFxuXG5cdFx0XHRcdGFbaW5kZXggLSByZW1vdmVkXSA9IGFbaW5kZXhdXG5cblx0XHRpZiByZW1vdmVkID4gMFxuXG5cdFx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gcmVtb3ZlZFxuXG5cdFx0YVxuXG5cdHBsdWNrTXVsdGlwbGU6IChhcnJheSwgaW5kZXhlc1RvUmVtb3ZlKSAtPlxuXG5cdFx0cmV0dXJuIGFycmF5IGlmIGFycmF5Lmxlbmd0aCA8IDFcblxuXHRcdHJlbW92ZWRTb0ZhciA9IDBcblxuXHRcdGluZGV4ZXNUb1JlbW92ZS5zb3J0KClcblxuXHRcdGZvciBpIGluIGluZGV4ZXNUb1JlbW92ZVxuXG5cdFx0XHRAcGx1Y2sgYXJyYXksIGkgLSByZW1vdmVkU29GYXJcblxuXHRcdFx0cmVtb3ZlZFNvRmFyKytcblxuXHRcdGFycmF5XG5cblx0aW5qZWN0QnlDYWxsYmFjazogKGEsIHRvSW5qZWN0LCBzaG91bGRJbmplY3QpIC0+XG5cblx0XHR2YWxBID0gbnVsbFxuXG5cdFx0dmFsQiA9IG51bGxcblxuXHRcdGxlbiA9IGEubGVuZ3RoXG5cblx0XHRpZiBsZW4gPCAxXG5cblx0XHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0XHRyZXR1cm4gYVxuXG5cblx0XHRmb3IgdmFsLCBpIGluIGFcblxuXHRcdFx0dmFsQSA9IHZhbEJcblxuXHRcdFx0dmFsQiA9IHZhbFxuXG5cdFx0XHRpZiBzaG91bGRJbmplY3QgdmFsQSwgdmFsQiwgdG9JbmplY3RcblxuXHRcdFx0XHRyZXR1cm4gYS5zcGxpY2UgaSwgMCwgdG9JbmplY3RcblxuXHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0YVxuXG5cdGluamVjdEluSW5kZXg6IChhLCBpbmRleCwgdG9JbmplY3QpIC0+XG5cblx0XHRsZW4gPSBhLmxlbmd0aFxuXG5cdFx0aSA9IGluZGV4XG5cblx0XHRpZiBsZW4gPCAxXG5cblx0XHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0XHRyZXR1cm4gYVxuXG5cdFx0dG9QdXQgPSB0b0luamVjdFxuXG5cdFx0dG9QdXROZXh0ID0gbnVsbFxuXG5cdFx0YGZvcig7IGkgPD0gbGVuOyBpKyspe1xuXG5cdFx0XHR0b1B1dE5leHQgPSBhW2ldO1xuXG5cdFx0XHRhW2ldID0gdG9QdXQ7XG5cblx0XHRcdHRvUHV0ID0gdG9QdXROZXh0O1xuXG5cdFx0fWBcblxuXHRcdCMgYVtpXSA9IHRvUHV0XG5cblx0XHRudWxsIiwibW9kdWxlLmV4cG9ydHMgPSBjbGFzc2ljID0ge31cblxuIyBMaXR0bGUgaGVscGVyIGZvciBtaXhpbnMgZnJvbSBDb2ZmZWVTY3JpcHQgRkFRLFxuIyBjb3VydGVzeSBvZiBTZXRoYXVydXMgKGh0dHA6Ly9naXRodWIuY29tL3NldGhhdXJ1cylcbmNsYXNzaWMuaW1wbGVtZW50ID0gKG1peGlucy4uLiwgY2xhc3NSZWZlcmVuY2UpIC0+XG5cblx0Zm9yIG1peGluIGluIG1peGluc1xuXG5cdFx0Y2xhc3NQcm90byA9IGNsYXNzUmVmZXJlbmNlOjpcblxuXHRcdGZvciBtZW1iZXIgb2YgbWl4aW46OlxuXG5cdFx0XHR1bmxlc3MgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBjbGFzc1Byb3RvLCBtZW1iZXJcblxuXHRcdFx0XHRkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBtaXhpbjo6LCBtZW1iZXJcblxuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkgY2xhc3NQcm90bywgbWVtYmVyLCBkZXNjXG5cblx0Y2xhc3NSZWZlcmVuY2VcblxuY2xhc3NpYy5taXggPSAobWl4aW5zLi4uLCBjbGFzc1JlZmVyZW5jZSkgLT5cblxuXHRjbGFzc1Byb3RvID0gY2xhc3NSZWZlcmVuY2U6OlxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzID0gW11cblxuXHRjbGFzc1JlZmVyZW5jZS5fX2FwcGx5Q2xvbmVyc0ZvciA9IChpbnN0YW5jZSwgYXJncyA9IG51bGwpIC0+XG5cblx0XHRmb3IgY2xvbmVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzXG5cblx0XHRcdGNsb25lci5hcHBseSBpbnN0YW5jZSwgYXJnc1xuXG5cdFx0cmV0dXJuXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkluaXRpYWxpemVycyA9IFtdXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19pbml0TWl4aW5zRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBpbml0aWFsaXplciBpbiBjbGFzc1JlZmVyZW5jZS5fX21peGluSW5pdGlhbGl6ZXJzXG5cblx0XHRcdGluaXRpYWxpemVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRjbGFzc1JlZmVyZW5jZS5fX21peGluUXVpdHRlcnMgPSBbXVxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fYXBwbHlRdWl0dGVyc0ZvciA9IChpbnN0YW5jZSwgYXJncyA9IG51bGwpIC0+XG5cblx0XHRmb3IgcXVpdHRlciBpbiBjbGFzc1JlZmVyZW5jZS5fX21peGluUXVpdHRlcnNcblxuXHRcdFx0cXVpdHRlci5hcHBseSBpbnN0YW5jZSwgYXJnc1xuXG5cdFx0cmV0dXJuXG5cblx0Zm9yIG1peGluIGluIG1peGluc1xuXG5cdFx0dW5sZXNzIG1peGluLmNvbnN0cnVjdG9yIGluc3RhbmNlb2YgRnVuY3Rpb25cblxuXHRcdFx0dGhyb3cgRXJyb3IgXCJNaXhpbiBzaG91bGQgYmUgYSBmdW5jdGlvblwiXG5cblx0XHRmb3IgbWVtYmVyIG9mIG1peGluOjpcblxuXHRcdFx0aWYgbWVtYmVyLnN1YnN0cigwLCAxMSkgaXMgJ19faW5pdE1peGluJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5Jbml0aWFsaXplcnMucHVzaCBtaXhpbjo6W21lbWJlcl1cblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRlbHNlIGlmIG1lbWJlci5zdWJzdHIoMCwgMTEpIGlzICdfX2Nsb25lckZvcidcblxuXHRcdFx0XHRjbGFzc1JlZmVyZW5jZS5fX21peGluQ2xvbmVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2UgaWYgbWVtYmVyLnN1YnN0cigwLCAxMikgaXMgJ19fcXVpdHRlckZvcidcblxuXHRcdFx0XHRjbGFzc1JlZmVyZW5jZS5fX21peGluUXVpdHRlcnMucHVzaCBtaXhpbjo6W21lbWJlcl1cblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHR1bmxlc3MgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBjbGFzc1Byb3RvLCBtZW1iZXJcblxuXHRcdFx0XHRkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBtaXhpbjo6LCBtZW1iZXJcblxuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkgY2xhc3NQcm90bywgbWVtYmVyLCBkZXNjXG5cblx0Y2xhc3NSZWZlcmVuY2UiLCJhcnJheSA9IHJlcXVpcmUgJy4vYXJyYXknXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYXNzIEVtaXR0ZXJcclxuXHJcblx0Y29uc3RydWN0b3I6IC0+XHJcblxyXG5cdFx0QF9saXN0ZW5lcnMgPSB7fVxyXG5cclxuXHRcdEBfbGlzdGVuZXJzRm9yQW55RXZlbnQgPSBbXVxyXG5cclxuXHRcdEBfZGlzYWJsZWRFbWl0dGVycyA9IHt9XHJcblxyXG5cdG9uOiAoZXZlbnROYW1lLCBsaXN0ZW5lcikgLT5cclxuXHJcblx0XHR1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRcdEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0gPSBbXVxyXG5cclxuXHRcdEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0ucHVzaCBsaXN0ZW5lclxyXG5cclxuXHRcdEBcclxuXHJcblx0b25jZTogKGV2ZW50TmFtZSwgbGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0cmFuID0gbm9cclxuXHJcblx0XHRjYiA9ID0+XHJcblxyXG5cdFx0XHRyZXR1cm4gaWYgcmFuXHJcblxyXG5cdFx0XHRyYW4gPSB5ZXNcclxuXHJcblx0XHRcdGRvIGxpc3RlbmVyXHJcblxyXG5cdFx0XHRzZXRUaW1lb3V0ID0+XHJcblxyXG5cdFx0XHRcdEByZW1vdmVFdmVudCBldmVudE5hbWUsIGNiXHJcblxyXG5cdFx0XHQsIDBcclxuXHJcblx0XHRAb24gZXZlbnROYW1lLCBjYlxyXG5cclxuXHRcdEBcclxuXHJcblx0b25BbnlFdmVudDogKGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdEBfbGlzdGVuZXJzRm9yQW55RXZlbnQucHVzaCBsaXN0ZW5lclxyXG5cclxuXHRcdEBcclxuXHJcblx0cmVtb3ZlRXZlbnQ6IChldmVudE5hbWUsIGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdHJldHVybiBAIHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdGFycmF5LnBsdWNrT25lSXRlbSBAX2xpc3RlbmVyc1tldmVudE5hbWVdLCBsaXN0ZW5lclxyXG5cclxuXHRcdEBcclxuXHJcblx0cmVtb3ZlTGlzdGVuZXJzOiAoZXZlbnROYW1lKSAtPlxyXG5cclxuXHRcdHJldHVybiBAIHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0ubGVuZ3RoID0gMFxyXG5cclxuXHRcdEBcclxuXHJcblx0cmVtb3ZlQWxsTGlzdGVuZXJzOiAtPlxyXG5cclxuXHRcdGZvciBuYW1lLCBsaXN0ZW5lcnMgb2YgQF9saXN0ZW5lcnNcclxuXHJcblx0XHRcdGxpc3RlbmVycy5sZW5ndGggPSAwXHJcblxyXG5cdFx0QFxyXG5cclxuXHRfZW1pdDogKGV2ZW50TmFtZSwgZGF0YSkgLT5cclxuXHJcblx0XHRmb3IgbGlzdGVuZXIgaW4gQF9saXN0ZW5lcnNGb3JBbnlFdmVudFxyXG5cclxuXHRcdFx0bGlzdGVuZXIuY2FsbCBALCBkYXRhLCBldmVudE5hbWVcclxuXHJcblx0XHRyZXR1cm4gdW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0Zm9yIGxpc3RlbmVyIGluIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV1cclxuXHJcblx0XHRcdGxpc3RlbmVyLmNhbGwgQCwgZGF0YVxyXG5cclxuXHRcdHJldHVyblxyXG5cclxuXHQjIHRoaXMgbWFrZXMgc3VyZSB0aGF0IGFsbCB0aGUgY2FsbHMgdG8gdGhpcyBjbGFzcydzIG1ldGhvZCAnZm5OYW1lJ1xyXG5cdCMgYXJlIHRocm90dGxlZFxyXG5cdF90aHJvdHRsZUVtaXR0ZXJNZXRob2Q6IChmbk5hbWUsIHRpbWUgPSAxMDAwKSAtPlxyXG5cclxuXHRcdG9yaWdpbmFsRm4gPSBAW2ZuTmFtZV1cclxuXHJcblx0XHRpZiB0eXBlb2Ygb3JpZ2luYWxGbiBpc250ICdmdW5jdGlvbidcclxuXHJcblx0XHRcdHRocm93IEVycm9yIFwidGhpcyBjbGFzcyBkb2VzIG5vdCBoYXZlIGEgbWV0aG9kIGNhbGxlZCAnI3tmbk5hbWV9J1wiXHJcblxyXG5cdFx0bGFzdENhbGxBcmdzID0gbnVsbFxyXG5cdFx0cGVuZGluZyA9IG5vXHJcblx0XHR0aW1lciA9IG51bGxcclxuXHJcblx0XHRAW2ZuTmFtZV0gPSA9PlxyXG5cclxuXHRcdFx0bGFzdENhbGxBcmdzID0gYXJndW1lbnRzXHJcblxyXG5cdFx0XHRkbyBwZW5kXHJcblxyXG5cdFx0cGVuZCA9ID0+XHJcblxyXG5cdFx0XHRpZiBwZW5kaW5nXHJcblxyXG5cdFx0XHRcdGNsZWFyVGltZW91dCB0aW1lclxyXG5cclxuXHRcdFx0dGltZXIgPSBzZXRUaW1lb3V0IHJ1bkl0LCB0aW1lXHJcblxyXG5cdFx0XHRwZW5kaW5nID0geWVzXHJcblxyXG5cdFx0cnVuSXQgPSA9PlxyXG5cclxuXHRcdFx0cGVuZGluZyA9IG5vXHJcblxyXG5cdFx0XHRvcmlnaW5hbEZuLmFwcGx5IEAsIGxhc3RDYWxsQXJnc1xyXG5cclxuXHRfZGlzYWJsZUVtaXR0ZXI6IChmbk5hbWUpIC0+XHJcblxyXG5cdFx0aWYgQF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV0/XHJcblxyXG5cdFx0XHR0aHJvdyBFcnJvciBcIiN7Zm5OYW1lfSBpcyBhbHJlYWR5IGEgZGlzYWJsZWQgZW1pdHRlclwiXHJcblxyXG5cdFx0QF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV0gPSBAW2ZuTmFtZV1cclxuXHJcblx0XHRAW2ZuTmFtZV0gPSAtPlxyXG5cclxuXHRfZW5hYmxlRW1pdHRlcjogKGZuTmFtZSkgLT5cclxuXHJcblx0XHRmbiA9IEBfZGlzYWJsZWRFbWl0dGVyc1tmbk5hbWVdXHJcblxyXG5cdFx0dW5sZXNzIGZuP1xyXG5cclxuXHRcdFx0dGhyb3cgRXJyb3IgXCIje2ZuTmFtZX0gaXMgbm90IGEgZGlzYWJsZWQgZW1pdHRlclwiXHJcblxyXG5cdFx0QFtmbk5hbWVdID0gZm5cclxuXHJcblx0XHRkZWxldGUgQF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV0iLCJfY29tbW9uID0gcmVxdWlyZSAnLi9fY29tbW9uJ1xuXG5tb2R1bGUuZXhwb3J0cyA9IG9iamVjdCA9XG5cblx0aXNCYXJlT2JqZWN0OiBfY29tbW9uLmlzQmFyZU9iamVjdC5iaW5kIF9jb21tb25cblxuXHQjIyNcblx0aWYgb2JqZWN0IGlzIGFuIGluc3RhbmNlIG9mIGEgY2xhc3Ncblx0IyMjXG5cdGlzSW5zdGFuY2U6ICh3aGF0KSAtPlxuXG5cdFx0bm90IEBpc0JhcmVPYmplY3Qgd2hhdFxuXG5cdCMjI1xuXHRBbGlhcyB0byBfY29tbW9uLnR5cGVPZlxuXHQjIyNcblx0dHlwZU9mOiBfY29tbW9uLnR5cGVPZi5iaW5kIF9jb21tb25cblxuXHQjIyNcblx0QWxpYXMgdG8gX2NvbW1vbi5jbG9uZVxuXHQjIyNcblx0Y2xvbmU6IF9jb21tb24uY2xvbmUuYmluZCBfY29tbW9uXG5cblx0IyMjXG5cdEVtcHRpZXMgYW4gb2JqZWN0IG9mIGl0cyBwcm9wZXJ0aWVzLlxuXHQjIyNcblx0ZW1wdHk6IChvKSAtPlxuXG5cdFx0Zm9yIHByb3Agb2Ygb1xuXG5cdFx0XHRkZWxldGUgb1twcm9wXSBpZiBvLmhhc093blByb3BlcnR5IHByb3BcblxuXHRcdG9cblxuXHQjIyNcblx0RW1wdGllcyBhbiBvYmplY3QuIERvZXNuJ3QgY2hlY2sgZm9yIGhhc093blByb3BlcnR5LCBzbyBpdCdzIGEgdGlueVxuXHRiaXQgZmFzdGVyLiBVc2UgaXQgZm9yIHBsYWluIG9iamVjdHMuXG5cdCMjI1xuXHRmYXN0RW1wdHk6IChvKSAtPlxuXG5cdFx0ZGVsZXRlIG9bcHJvcGVydHldIGZvciBwcm9wZXJ0eSBvZiBvXG5cblx0XHRvXG5cblx0IyMjXG5cdE92ZXJyaWRlcyB2YWx1ZXMgZm9tciBgbmV3VmFsdWVzYCBvbiBgYmFzZWAsIGFzIGxvbmcgYXMgdGhleVxuXHRhbHJlYWR5IGV4aXN0IGluIGJhc2UuXG5cdCMjI1xuXHRvdmVycmlkZU9udG86IChiYXNlLCBuZXdWYWx1ZXMpIC0+XG5cblx0XHRyZXR1cm4gYmFzZSBpZiBub3QgQGlzQmFyZU9iamVjdChuZXdWYWx1ZXMpIG9yIG5vdCBAaXNCYXJlT2JqZWN0KGJhc2UpXG5cblx0XHRmb3Iga2V5LCBvbGRWYWwgb2YgYmFzZVxuXG5cdFx0XHRuZXdWYWwgPSBuZXdWYWx1ZXNba2V5XVxuXG5cdFx0XHRjb250aW51ZSBpZiBuZXdWYWwgaXMgdW5kZWZpbmVkXG5cblx0XHRcdGlmIHR5cGVvZiBuZXdWYWwgaXNudCAnb2JqZWN0JyBvciBAaXNJbnN0YW5jZSBuZXdWYWxcblxuXHRcdFx0XHRiYXNlW2tleV0gPSBAY2xvbmUgbmV3VmFsXG5cblx0XHRcdCMgbmV3VmFsIGlzIGEgcGxhaW4gb2JqZWN0XG5cdFx0XHRlbHNlXG5cblx0XHRcdFx0aWYgdHlwZW9mIG9sZFZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG9sZFZhbFxuXG5cdFx0XHRcdFx0YmFzZVtrZXldID0gQGNsb25lIG5ld1ZhbFxuXG5cdFx0XHRcdGVsc2VcblxuXHRcdFx0XHRcdEBvdmVycmlkZU9udG8gb2xkVmFsLCBuZXdWYWxcblx0XHRiYXNlXG5cblx0IyMjXG5cdFRha2VzIGEgY2xvbmUgb2YgJ2Jhc2UnIGFuZCBydW5zICNvdmVycmlkZU9udG8gb24gaXRcblx0IyMjXG5cdG92ZXJyaWRlOiAoYmFzZSwgbmV3VmFsdWVzKSAtPlxuXG5cdFx0QG92ZXJyaWRlT250byBAY2xvbmUoYmFzZSksIG5ld1ZhbHVlc1xuXG5cdGFwcGVuZDogKGJhc2UsIHRvQXBwZW5kKSAtPlxuXG5cdFx0QGFwcGVuZE9udG8gQGNsb25lKGJhc2UpLCB0b0FwcGVuZFxuXG5cdCMgRGVlcCBhcHBlbmRzIHZhbHVlcyBmcm9tIGB0b0FwcGVuZGAgdG8gYGJhc2VgXG5cdGFwcGVuZE9udG86IChiYXNlLCB0b0FwcGVuZCkgLT5cblxuXHRcdHJldHVybiBiYXNlIGlmIG5vdCBAaXNCYXJlT2JqZWN0KHRvQXBwZW5kKSBvciBub3QgQGlzQmFyZU9iamVjdChiYXNlKVxuXG5cdFx0Zm9yIG93biBrZXksIG5ld1ZhbCBvZiB0b0FwcGVuZFxuXG5cdFx0XHRjb250aW51ZSB1bmxlc3MgbmV3VmFsIGlzbnQgdW5kZWZpbmVkXG5cblx0XHRcdGlmIHR5cGVvZiBuZXdWYWwgaXNudCAnb2JqZWN0JyBvciBAaXNJbnN0YW5jZSBuZXdWYWxcblxuXHRcdFx0XHRiYXNlW2tleV0gPSBuZXdWYWxcblxuXHRcdFx0ZWxzZVxuXG5cdFx0XHRcdCMgbmV3VmFsIGlzIGEgYmFyZSBvYmplY3RcblxuXHRcdFx0XHRvbGRWYWwgPSBiYXNlW2tleV1cblxuXHRcdFx0XHRpZiB0eXBlb2Ygb2xkVmFsIGlzbnQgJ29iamVjdCcgb3IgQGlzSW5zdGFuY2Ugb2xkVmFsXG5cblx0XHRcdFx0XHRiYXNlW2tleV0gPSBAY2xvbmUgbmV3VmFsXG5cblx0XHRcdFx0ZWxzZVxuXG5cdFx0XHRcdFx0QGFwcGVuZE9udG8gb2xkVmFsLCBuZXdWYWxcblxuXHRcdGJhc2VcblxuXHQjIEdyb3Vwc1xuXHRncm91cFByb3BzOiAob2JqLCBncm91cHMpIC0+XG5cblx0XHRncm91cGVkID0ge31cblxuXHRcdGZvciBuYW1lLCBkZWZzIG9mIGdyb3Vwc1xuXG5cdFx0XHRncm91cGVkW25hbWVdID0ge31cblxuXHRcdGdyb3VwZWRbJ3Jlc3QnXSA9IHt9XG5cblx0XHRgdG9wOiAvL2Bcblx0XHRmb3Iga2V5LCB2YWwgb2Ygb2JqXG5cblx0XHRcdHNob3VsZEFkZCA9IG5vXG5cblx0XHRcdGZvciBuYW1lLCBkZWZzIG9mIGdyb3Vwc1xuXG5cdFx0XHRcdHVubGVzcyBBcnJheS5pc0FycmF5IGRlZnNcblxuXHRcdFx0XHRcdGRlZnMgPSBbZGVmc11cblxuXHRcdFx0XHRmb3IgZGVmIGluIGRlZnNcblxuXHRcdFx0XHRcdGlmIHR5cGVvZiBkZWYgaXMgJ3N0cmluZydcblxuXHRcdFx0XHRcdFx0aWYga2V5IGlzIGRlZlxuXG5cdFx0XHRcdFx0XHRcdHNob3VsZEFkZCA9IHllc1xuXG5cdFx0XHRcdFx0ZWxzZSBpZiBkZWYgaW5zdGFuY2VvZiBSZWdFeHBcblxuXHRcdFx0XHRcdFx0aWYgZGVmLnRlc3Qga2V5XG5cblx0XHRcdFx0XHRcdFx0c2hvdWxkQWRkID0geWVzXG5cblx0XHRcdFx0XHRlbHNlIGlmIGRlZiBpbnN0YW5jZW9mIEZ1bmN0aW9uXG5cblx0XHRcdFx0XHRcdGlmIGRlZiBrZXlcblxuXHRcdFx0XHRcdFx0XHRzaG91bGRBZGQgPSB5ZXNcblxuXHRcdFx0XHRcdGVsc2VcblxuXHRcdFx0XHRcdFx0dGhyb3cgRXJyb3IgJ0dyb3VwIGRlZmluaXRpb25zIG11c3QgZWl0aGVyXG5cdFx0XHRcdFx0XHRiZSBzdHJpbmdzLCByZWdleGVzLCBvciBmdW5jdGlvbnMuJ1xuXG5cdFx0XHRcdFx0aWYgc2hvdWxkQWRkXG5cblx0XHRcdFx0XHRcdGdyb3VwZWRbbmFtZV1ba2V5XSA9IHZhbFxuXG5cdFx0XHRcdFx0XHRgY29udGludWUgdG9wYFxuXG5cdFx0XHRncm91cGVkWydyZXN0J11ba2V5XSA9IHZhbFxuXG5cdFx0Z3JvdXBlZCIsIm1vZHVsZS5leHBvcnRzID1cclxuXHJcblx0IyBwYWRzIGEgbnVtYmVyIHdpdGggbGVhZGluZyB6ZXJvZXNcclxuXHQjXHJcblx0IyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xMDA3Mzc4OC82MDc5OTdcclxuXHRwYWQ6IChuLCB3aWR0aCwgeiA9ICcwJykgLT5cclxuXHJcblx0XHRuID0gbiArICcnXHJcblxyXG5cdFx0aWYgbi5sZW5ndGggPj0gd2lkdGhcclxuXHJcblx0XHRcdG5cclxuXHJcblx0XHRlbHNlXHJcblxyXG5cdFx0XHRuZXcgQXJyYXkod2lkdGggLSBuLmxlbmd0aCArIDEpLmpvaW4oeikgKyBuIiwibW9kdWxlLmV4cG9ydHMgPSB1dGlsYSA9XG5cblx0YXJyYXk6IHJlcXVpcmUgJy4vYXJyYXknXG5cdGNsYXNzaWM6IHJlcXVpcmUgJy4vY2xhc3NpYydcblx0b2JqZWN0OiByZXF1aXJlICcuL29iamVjdCdcblx0c3RyaW5nOiByZXF1aXJlICcuL3N0cmluZydcblx0RW1pdHRlcjogcmVxdWlyZSAnLi9FbWl0dGVyJyIsIm1vZHVsZS5leHBvcnRzID0gY29tbW9uID1cblxuXHQjIyNcblx0Q2hlY2tzIHRvIHNlZSBpZiBvIGlzIGFuIG9iamVjdCwgYW5kIGl0IGlzbid0IGFuIGluc3RhbmNlXG5cdG9mIHNvbWUgY2xhc3MuXG5cdCMjI1xuXHRpc0JhcmVPYmplY3Q6IChvKSAtPlxuXG5cdFx0aWYgbz8gYW5kIG8uY29uc3RydWN0b3IgaXMgT2JqZWN0XG5cblx0XHRcdHJldHVybiB0cnVlXG5cblx0XHRmYWxzZVxuXG5cdCMjI1xuXHRSZXR1cm5zIHR5cGUgb2YgYW4gb2JqZWN0LCBpbmNsdWRpbmc6XG5cdHVuZGVmaW5lZCwgbnVsbCwgc3RyaW5nLCBudW1iZXIsIGFycmF5LFxuXHRhcmd1bWVudHMsIGVsZW1lbnQsIHRleHRub2RlLCB3aGl0ZXNwYWNlLCBhbmQgb2JqZWN0XG5cdCMjI1xuXHR0eXBlT2Y6IChpdGVtKSAtPlxuXG5cdFx0cmV0dXJuICdudWxsJyBpZiBpdGVtIGlzIG51bGxcblxuXHRcdHJldHVybiB0eXBlb2YgaXRlbSBpZiB0eXBlb2YgaXRlbSBpc250ICdvYmplY3QnXG5cblx0XHRyZXR1cm4gJ2FycmF5JyBpZiBBcnJheS5pc0FycmF5IGl0ZW1cblxuXHRcdCMgRnJvbSBNb29Ub29sc1xuXHRcdCMgLSBkbyB3ZSBldmVuIG5lZWQgdGhpcz9cblx0XHRpZiBpdGVtLm5vZGVOYW1lXG5cblx0XHRcdGlmIGl0ZW0ubm9kZVR5cGUgaXMgMSB0aGVuIHJldHVybiAnZWxlbWVudCdcblx0XHRcdGlmIGl0ZW0ubm9kZVR5cGUgaXMgMyB0aGVuIHJldHVybiAoL1xcUy8pLnRlc3QoaXRlbS5ub2RlVmFsdWUpID8gJ3RleHRub2RlJyA6ICd3aGl0ZXNwYWNlJ1xuXG5cdFx0ZWxzZSBpZiB0eXBlb2YgaXRlbS5sZW5ndGggaXMgJ251bWJlcidcblxuXHRcdFx0aWYgaXRlbS5jYWxsZWUgdGhlbiByZXR1cm4gJ2FyZ3VtZW50cydcblxuXHRcdHJldHVybiB0eXBlb2YgaXRlbVxuXG5cdCMgRGVlcCBjbG9uZSBvZiBhbnkgdmFyaWFibGUuXG5cdCMgRnJvbSBNb29Ub29sc1xuXHRjbG9uZTogKGl0ZW0sIGluY2x1ZGVQcm90b3R5cGUgPSBmYWxzZSkgLT5cblxuXHRcdHN3aXRjaCBjb21tb24udHlwZU9mIGl0ZW1cblxuXHRcdFx0d2hlbiAnYXJyYXknIHRoZW4gcmV0dXJuIGNvbW1vbi5fY2xvbmVBcnJheSBpdGVtLCBpbmNsdWRlUHJvdG90eXBlXG5cblx0XHRcdHdoZW4gJ29iamVjdCcgdGhlbiByZXR1cm4gY29tbW9uLl9jbG9uZU9iamVjdCBpdGVtLCBpbmNsdWRlUHJvdG90eXBlXG5cblx0XHRcdGVsc2UgcmV0dXJuIGl0ZW1cblxuXHQjIyNcblx0RGVlcCBjbG9uZSBvZiBhbiBvYmplY3QuXG5cdEZyb20gTW9vVG9vbHNcblx0IyMjXG5cdF9jbG9uZU9iamVjdDogKG8sIGluY2x1ZGVQcm90b3R5cGUgPSBmYWxzZSkgLT5cblxuXHRcdGlmIGNvbW1vbi5pc0JhcmVPYmplY3Qgb1xuXG5cdFx0XHRjbG9uZSA9IHt9XG5cblx0XHRcdGZvciBrZXkgb2Ygb1xuXG5cdFx0XHRcdGNsb25lW2tleV0gPSBjb21tb24uY2xvbmUgb1trZXldLCBpbmNsdWRlUHJvdG90eXBlXG5cblx0XHRcdHJldHVybiBjbG9uZVxuXG5cdFx0ZWxzZVxuXG5cdFx0XHRyZXR1cm4gbyB1bmxlc3MgaW5jbHVkZVByb3RvdHlwZVxuXG5cdFx0XHRyZXR1cm4gbyBpZiBvIGluc3RhbmNlb2YgRnVuY3Rpb25cblxuXHRcdFx0Y2xvbmUgPSBPYmplY3QuY3JlYXRlIG8uY29uc3RydWN0b3IucHJvdG90eXBlXG5cblx0XHRcdGZvciBrZXkgb2Ygb1xuXG5cdFx0XHRcdGlmIG8uaGFzT3duUHJvcGVydHkga2V5XG5cblx0XHRcdFx0XHRjbG9uZVtrZXldID0gY29tbW9uLmNsb25lIG9ba2V5XSwgaW5jbHVkZVByb3RvdHlwZVxuXG5cdFx0XHRjbG9uZVxuXG5cdCMjI1xuXHREZWVwIGNsb25lIG9mIGFuIGFycmF5LlxuXHRGcm9tIE1vb1Rvb2xzXG5cdCMjI1xuXHRfY2xvbmVBcnJheTogKGEsIGluY2x1ZGVQcm90b3R5cGUgPSBmYWxzZSkgLT5cblxuXHRcdGkgPSBhLmxlbmd0aFxuXG5cdFx0Y2xvbmUgPSBuZXcgQXJyYXkgaVxuXG5cdFx0d2hpbGUgaS0tXG5cblx0XHRcdGNsb25lW2ldID0gY29tbW9uLmNsb25lIGFbaV0sIGluY2x1ZGVQcm90b3R5cGVcblxuXHRcdGNsb25lIl19 \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/lib/array.js b/node_modules/utila/scripts/js/lib/array.js
new file mode 100644
index 000000000..44a7c68db
--- /dev/null
+++ b/node_modules/utila/scripts/js/lib/array.js
@@ -0,0 +1,166 @@
+var array;
+
+module.exports = array = {
+
+ /*
+ Tries to turn anything into an array.
+ */
+ from: function(r) {
+ return Array.prototype.slice.call(r);
+ },
+
+ /*
+ Clone of an array. Properties will be shallow copies.
+ */
+ simpleClone: function(a) {
+ return a.slice(0);
+ },
+ shallowEqual: function(a1, a2) {
+ var i, val, _i, _len;
+ if (!(Array.isArray(a1) && Array.isArray(a2) && a1.length === a2.length)) {
+ return false;
+ }
+ for (i = _i = 0, _len = a1.length; _i < _len; i = ++_i) {
+ val = a1[i];
+ if (a2[i] !== val) {
+ return false;
+ }
+ }
+ return true;
+ },
+ pluck: function(a, i) {
+ var index, value, _i, _len;
+ if (a.length < 1) {
+ return a;
+ }
+ for (index = _i = 0, _len = a.length; _i < _len; index = ++_i) {
+ value = a[index];
+ if (index > i) {
+ a[index - 1] = a[index];
+ }
+ }
+ a.length = a.length - 1;
+ return a;
+ },
+ pluckItem: function(a, item) {
+ var index, removed, value, _i, _len;
+ if (a.length < 1) {
+ return a;
+ }
+ removed = 0;
+ for (index = _i = 0, _len = a.length; _i < _len; index = ++_i) {
+ value = a[index];
+ if (value === item) {
+ removed++;
+ continue;
+ }
+ if (removed !== 0) {
+ a[index - removed] = a[index];
+ }
+ }
+ if (removed > 0) {
+ a.length = a.length - removed;
+ }
+ return a;
+ },
+ pluckOneItem: function(a, item) {
+ var index, reached, value, _i, _len;
+ if (a.length < 1) {
+ return a;
+ }
+ reached = false;
+ for (index = _i = 0, _len = a.length; _i < _len; index = ++_i) {
+ value = a[index];
+ if (!reached) {
+ if (value === item) {
+ reached = true;
+ continue;
+ }
+ } else {
+ a[index - 1] = a[index];
+ }
+ }
+ if (reached) {
+ a.length = a.length - 1;
+ }
+ return a;
+ },
+ pluckByCallback: function(a, cb) {
+ var index, removed, value, _i, _len;
+ if (a.length < 1) {
+ return a;
+ }
+ removed = 0;
+ for (index = _i = 0, _len = a.length; _i < _len; index = ++_i) {
+ value = a[index];
+ if (cb(value, index)) {
+ removed++;
+ continue;
+ }
+ if (removed !== 0) {
+ a[index - removed] = a[index];
+ }
+ }
+ if (removed > 0) {
+ a.length = a.length - removed;
+ }
+ return a;
+ },
+ pluckMultiple: function(array, indexesToRemove) {
+ var i, removedSoFar, _i, _len;
+ if (array.length < 1) {
+ return array;
+ }
+ removedSoFar = 0;
+ indexesToRemove.sort();
+ for (_i = 0, _len = indexesToRemove.length; _i < _len; _i++) {
+ i = indexesToRemove[_i];
+ this.pluck(array, i - removedSoFar);
+ removedSoFar++;
+ }
+ return array;
+ },
+ injectByCallback: function(a, toInject, shouldInject) {
+ var i, len, val, valA, valB, _i, _len;
+ valA = null;
+ valB = null;
+ len = a.length;
+ if (len < 1) {
+ a.push(toInject);
+ return a;
+ }
+ for (i = _i = 0, _len = a.length; _i < _len; i = ++_i) {
+ val = a[i];
+ valA = valB;
+ valB = val;
+ if (shouldInject(valA, valB, toInject)) {
+ return a.splice(i, 0, toInject);
+ }
+ }
+ a.push(toInject);
+ return a;
+ },
+ injectInIndex: function(a, index, toInject) {
+ var i, len, toPut, toPutNext;
+ len = a.length;
+ i = index;
+ if (len < 1) {
+ a.push(toInject);
+ return a;
+ }
+ toPut = toInject;
+ toPutNext = null;
+ for(; i <= len; i++){
+
+ toPutNext = a[i];
+
+ a[i] = toPut;
+
+ toPut = toPutNext;
+
+ };
+ return null;
+ }
+};
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXkuanMiLCJzb3VyY2VSb290IjoiLi5cXC4uIiwic291cmNlcyI6WyJjb2ZmZWVcXGxpYlxcYXJyYXkuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLElBQUEsS0FBQTs7QUFBQSxNQUFNLENBQUMsT0FBUCxHQUFpQixLQUFBLEdBRWhCO0FBQUE7QUFBQTs7S0FBQTtBQUFBLEVBR0EsSUFBQSxFQUFNLFNBQUMsQ0FBRCxHQUFBO1dBRUwsS0FBSyxDQUFBLFNBQUUsQ0FBQSxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFsQixFQUZLO0VBQUEsQ0FITjtBQU9BO0FBQUE7O0tBUEE7QUFBQSxFQVVBLFdBQUEsRUFBYSxTQUFDLENBQUQsR0FBQTtXQUVaLENBQUMsQ0FBQyxLQUFGLENBQVEsQ0FBUixFQUZZO0VBQUEsQ0FWYjtBQUFBLEVBY0EsWUFBQSxFQUFjLFNBQUMsRUFBRCxFQUFLLEVBQUwsR0FBQTtBQUViLFFBQUEsZ0JBQUE7QUFBQSxJQUFBLElBQUEsQ0FBQSxDQUFpQixLQUFLLENBQUMsT0FBTixDQUFjLEVBQWQsQ0FBQSxJQUFzQixLQUFLLENBQUMsT0FBTixDQUFjLEVBQWQsQ0FBdEIsSUFBNEMsRUFBRSxDQUFDLE1BQUgsS0FBYSxFQUFFLENBQUMsTUFBN0UsQ0FBQTtBQUFBLGFBQU8sS0FBUCxDQUFBO0tBQUE7QUFFQSxTQUFBLGlEQUFBO2tCQUFBO0FBRUMsTUFBQSxJQUFpQixFQUFHLENBQUEsQ0FBQSxDQUFILEtBQVMsR0FBMUI7QUFBQSxlQUFPLEtBQVAsQ0FBQTtPQUZEO0FBQUEsS0FGQTtXQU1BLEtBUmE7RUFBQSxDQWRkO0FBQUEsRUF3QkEsS0FBQSxFQUFPLFNBQUMsQ0FBRCxFQUFJLENBQUosR0FBQTtBQUVOLFFBQUEsc0JBQUE7QUFBQSxJQUFBLElBQVksQ0FBQyxDQUFDLE1BQUYsR0FBVyxDQUF2QjtBQUFBLGFBQU8sQ0FBUCxDQUFBO0tBQUE7QUFHQSxTQUFBLHdEQUFBO3VCQUFBO0FBRUMsTUFBQSxJQUFHLEtBQUEsR0FBUSxDQUFYO0FBRUMsUUFBQSxDQUFFLENBQUEsS0FBQSxHQUFRLENBQVIsQ0FBRixHQUFlLENBQUUsQ0FBQSxLQUFBLENBQWpCLENBRkQ7T0FGRDtBQUFBLEtBSEE7QUFBQSxJQVNBLENBQUMsQ0FBQyxNQUFGLEdBQVcsQ0FBQyxDQUFDLE1BQUYsR0FBVyxDQVR0QixDQUFBO1dBV0EsRUFiTTtFQUFBLENBeEJQO0FBQUEsRUF1Q0EsU0FBQSxFQUFXLFNBQUMsQ0FBRCxFQUFJLElBQUosR0FBQTtBQUVWLFFBQUEsK0JBQUE7QUFBQSxJQUFBLElBQVksQ0FBQyxDQUFDLE1BQUYsR0FBVyxDQUF2QjtBQUFBLGFBQU8sQ0FBUCxDQUFBO0tBQUE7QUFBQSxJQUdBLE9BQUEsR0FBVSxDQUhWLENBQUE7QUFLQSxTQUFBLHdEQUFBO3VCQUFBO0FBRUMsTUFBQSxJQUFHLEtBQUEsS0FBUyxJQUFaO0FBRUMsUUFBQSxPQUFBLEVBQUEsQ0FBQTtBQUVBLGlCQUpEO09BQUE7QUFNQSxNQUFBLElBQUcsT0FBQSxLQUFhLENBQWhCO0FBRUMsUUFBQSxDQUFFLENBQUEsS0FBQSxHQUFRLE9BQVIsQ0FBRixHQUFxQixDQUFFLENBQUEsS0FBQSxDQUF2QixDQUZEO09BUkQ7QUFBQSxLQUxBO0FBaUJBLElBQUEsSUFBaUMsT0FBQSxHQUFVLENBQTNDO0FBQUEsTUFBQSxDQUFDLENBQUMsTUFBRixHQUFXLENBQUMsQ0FBQyxNQUFGLEdBQVcsT0FBdEIsQ0FBQTtLQWpCQTtXQW1CQSxFQXJCVTtFQUFBLENBdkNYO0FBQUEsRUE4REEsWUFBQSxFQUFjLFNBQUMsQ0FBRCxFQUFJLElBQUosR0FBQTtBQUViLFFBQUEsK0JBQUE7QUFBQSxJQUFBLElBQVksQ0FBQyxDQUFDLE1BQUYsR0FBVyxDQUF2QjtBQUFBLGFBQU8sQ0FBUCxDQUFBO0tBQUE7QUFBQSxJQUVBLE9BQUEsR0FBVSxLQUZWLENBQUE7QUFJQSxTQUFBLHdEQUFBO3VCQUFBO0FBRUMsTUFBQSxJQUFHLENBQUksT0FBUDtBQUVDLFFBQUEsSUFBRyxLQUFBLEtBQVMsSUFBWjtBQUVDLFVBQUEsT0FBQSxHQUFVLElBQVYsQ0FBQTtBQUVBLG1CQUpEO1NBRkQ7T0FBQSxNQUFBO0FBVUMsUUFBQSxDQUFFLENBQUEsS0FBQSxHQUFRLENBQVIsQ0FBRixHQUFlLENBQUUsQ0FBQSxLQUFBLENBQWpCLENBVkQ7T0FGRDtBQUFBLEtBSkE7QUFrQkEsSUFBQSxJQUEyQixPQUEzQjtBQUFBLE1BQUEsQ0FBQyxDQUFDLE1BQUYsR0FBVyxDQUFDLENBQUMsTUFBRixHQUFXLENBQXRCLENBQUE7S0FsQkE7V0FvQkEsRUF0QmE7RUFBQSxDQTlEZDtBQUFBLEVBc0ZBLGVBQUEsRUFBaUIsU0FBQyxDQUFELEVBQUksRUFBSixHQUFBO0FBRWhCLFFBQUEsK0JBQUE7QUFBQSxJQUFBLElBQVksQ0FBQyxDQUFDLE1BQUYsR0FBVyxDQUF2QjtBQUFBLGFBQU8sQ0FBUCxDQUFBO0tBQUE7QUFBQSxJQUVBLE9BQUEsR0FBVSxDQUZWLENBQUE7QUFJQSxTQUFBLHdEQUFBO3VCQUFBO0FBRUMsTUFBQSxJQUFHLEVBQUEsQ0FBRyxLQUFILEVBQVUsS0FBVixDQUFIO0FBRUMsUUFBQSxPQUFBLEVBQUEsQ0FBQTtBQUVBLGlCQUpEO09BQUE7QUFNQSxNQUFBLElBQUcsT0FBQSxLQUFhLENBQWhCO0FBRUMsUUFBQSxDQUFFLENBQUEsS0FBQSxHQUFRLE9BQVIsQ0FBRixHQUFxQixDQUFFLENBQUEsS0FBQSxDQUF2QixDQUZEO09BUkQ7QUFBQSxLQUpBO0FBZ0JBLElBQUEsSUFBRyxPQUFBLEdBQVUsQ0FBYjtBQUVDLE1BQUEsQ0FBQyxDQUFDLE1BQUYsR0FBVyxDQUFDLENBQUMsTUFBRixHQUFXLE9BQXRCLENBRkQ7S0FoQkE7V0FvQkEsRUF0QmdCO0VBQUEsQ0F0RmpCO0FBQUEsRUE4R0EsYUFBQSxFQUFlLFNBQUMsS0FBRCxFQUFRLGVBQVIsR0FBQTtBQUVkLFFBQUEseUJBQUE7QUFBQSxJQUFBLElBQWdCLEtBQUssQ0FBQyxNQUFOLEdBQWUsQ0FBL0I7QUFBQSxhQUFPLEtBQVAsQ0FBQTtLQUFBO0FBQUEsSUFFQSxZQUFBLEdBQWUsQ0FGZixDQUFBO0FBQUEsSUFJQSxlQUFlLENBQUMsSUFBaEIsQ0FBQSxDQUpBLENBQUE7QUFNQSxTQUFBLHNEQUFBOzhCQUFBO0FBRUMsTUFBQSxJQUFDLENBQUEsS0FBRCxDQUFPLEtBQVAsRUFBYyxDQUFBLEdBQUksWUFBbEIsQ0FBQSxDQUFBO0FBQUEsTUFFQSxZQUFBLEVBRkEsQ0FGRDtBQUFBLEtBTkE7V0FZQSxNQWRjO0VBQUEsQ0E5R2Y7QUFBQSxFQThIQSxnQkFBQSxFQUFrQixTQUFDLENBQUQsRUFBSSxRQUFKLEVBQWMsWUFBZCxHQUFBO0FBRWpCLFFBQUEsaUNBQUE7QUFBQSxJQUFBLElBQUEsR0FBTyxJQUFQLENBQUE7QUFBQSxJQUVBLElBQUEsR0FBTyxJQUZQLENBQUE7QUFBQSxJQUlBLEdBQUEsR0FBTSxDQUFDLENBQUMsTUFKUixDQUFBO0FBTUEsSUFBQSxJQUFHLEdBQUEsR0FBTSxDQUFUO0FBRUMsTUFBQSxDQUFDLENBQUMsSUFBRixDQUFPLFFBQVAsQ0FBQSxDQUFBO0FBRUEsYUFBTyxDQUFQLENBSkQ7S0FOQTtBQWFBLFNBQUEsZ0RBQUE7aUJBQUE7QUFFQyxNQUFBLElBQUEsR0FBTyxJQUFQLENBQUE7QUFBQSxNQUVBLElBQUEsR0FBTyxHQUZQLENBQUE7QUFJQSxNQUFBLElBQUcsWUFBQSxDQUFhLElBQWIsRUFBbUIsSUFBbkIsRUFBeUIsUUFBekIsQ0FBSDtBQUVDLGVBQU8sQ0FBQyxDQUFDLE1BQUYsQ0FBUyxDQUFULEVBQVksQ0FBWixFQUFlLFFBQWYsQ0FBUCxDQUZEO09BTkQ7QUFBQSxLQWJBO0FBQUEsSUF1QkEsQ0FBQyxDQUFDLElBQUYsQ0FBTyxRQUFQLENBdkJBLENBQUE7V0F5QkEsRUEzQmlCO0VBQUEsQ0E5SGxCO0FBQUEsRUEySkEsYUFBQSxFQUFlLFNBQUMsQ0FBRCxFQUFJLEtBQUosRUFBVyxRQUFYLEdBQUE7QUFFZCxRQUFBLHdCQUFBO0FBQUEsSUFBQSxHQUFBLEdBQU0sQ0FBQyxDQUFDLE1BQVIsQ0FBQTtBQUFBLElBRUEsQ0FBQSxHQUFJLEtBRkosQ0FBQTtBQUlBLElBQUEsSUFBRyxHQUFBLEdBQU0sQ0FBVDtBQUVDLE1BQUEsQ0FBQyxDQUFDLElBQUYsQ0FBTyxRQUFQLENBQUEsQ0FBQTtBQUVBLGFBQU8sQ0FBUCxDQUpEO0tBSkE7QUFBQSxJQVVBLEtBQUEsR0FBUSxRQVZSLENBQUE7QUFBQSxJQVlBLFNBQUEsR0FBWSxJQVpaLENBQUE7QUFBQSxJQWNBOzs7Ozs7OztHQWRBLENBQUE7V0EwQkEsS0E1QmM7RUFBQSxDQTNKZjtDQUZELENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IGFycmF5ID1cblxuXHQjIyNcblx0VHJpZXMgdG8gdHVybiBhbnl0aGluZyBpbnRvIGFuIGFycmF5LlxuXHQjIyNcblx0ZnJvbTogKHIpIC0+XG5cblx0XHRBcnJheTo6c2xpY2UuY2FsbCByXG5cblx0IyMjXG5cdENsb25lIG9mIGFuIGFycmF5LiBQcm9wZXJ0aWVzIHdpbGwgYmUgc2hhbGxvdyBjb3BpZXMuXG5cdCMjI1xuXHRzaW1wbGVDbG9uZTogKGEpIC0+XG5cblx0XHRhLnNsaWNlIDBcblxuXHRzaGFsbG93RXF1YWw6IChhMSwgYTIpIC0+XG5cblx0XHRyZXR1cm4gbm8gdW5sZXNzIEFycmF5LmlzQXJyYXkoYTEpIGFuZCBBcnJheS5pc0FycmF5KGEyKSBhbmQgYTEubGVuZ3RoIGlzIGEyLmxlbmd0aFxuXG5cdFx0Zm9yIHZhbCwgaSBpbiBhMVxuXG5cdFx0XHRyZXR1cm4gbm8gdW5sZXNzIGEyW2ldIGlzIHZhbFxuXG5cdFx0eWVzXG5cblx0cGx1Y2s6IChhLCBpKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBpbmRleCA+IGlcblxuXHRcdFx0XHRhW2luZGV4IC0gMV0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIDFcblxuXHRcdGFcblxuXHRwbHVja0l0ZW06IChhLCBpdGVtKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblxuXHRcdHJlbW92ZWQgPSAwXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgdmFsdWUgaXMgaXRlbVxuXG5cdFx0XHRcdHJlbW92ZWQrK1xuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGlmIHJlbW92ZWQgaXNudCAwXG5cblx0XHRcdFx0YVtpbmRleCAtIHJlbW92ZWRdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSByZW1vdmVkIGlmIHJlbW92ZWQgPiAwXG5cblx0XHRhXG5cblx0cGx1Y2tPbmVJdGVtOiAoYSwgaXRlbSkgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cdFx0cmVhY2hlZCA9IG5vXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgbm90IHJlYWNoZWRcblxuXHRcdFx0XHRpZiB2YWx1ZSBpcyBpdGVtXG5cblx0XHRcdFx0XHRyZWFjaGVkID0geWVzXG5cblx0XHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRlbHNlXG5cblx0XHRcdFx0YVtpbmRleCAtIDFdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSAxIGlmIHJlYWNoZWRcblxuXHRcdGFcblxuXHRwbHVja0J5Q2FsbGJhY2s6IChhLCBjYikgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cdFx0cmVtb3ZlZCA9IDBcblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBjYiB2YWx1ZSwgaW5kZXhcblxuXHRcdFx0XHRyZW1vdmVkKytcblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRpZiByZW1vdmVkIGlzbnQgMFxuXG5cdFx0XHRcdGFbaW5kZXggLSByZW1vdmVkXSA9IGFbaW5kZXhdXG5cblx0XHRpZiByZW1vdmVkID4gMFxuXG5cdFx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gcmVtb3ZlZFxuXG5cdFx0YVxuXG5cdHBsdWNrTXVsdGlwbGU6IChhcnJheSwgaW5kZXhlc1RvUmVtb3ZlKSAtPlxuXG5cdFx0cmV0dXJuIGFycmF5IGlmIGFycmF5Lmxlbmd0aCA8IDFcblxuXHRcdHJlbW92ZWRTb0ZhciA9IDBcblxuXHRcdGluZGV4ZXNUb1JlbW92ZS5zb3J0KClcblxuXHRcdGZvciBpIGluIGluZGV4ZXNUb1JlbW92ZVxuXG5cdFx0XHRAcGx1Y2sgYXJyYXksIGkgLSByZW1vdmVkU29GYXJcblxuXHRcdFx0cmVtb3ZlZFNvRmFyKytcblxuXHRcdGFycmF5XG5cblx0aW5qZWN0QnlDYWxsYmFjazogKGEsIHRvSW5qZWN0LCBzaG91bGRJbmplY3QpIC0+XG5cblx0XHR2YWxBID0gbnVsbFxuXG5cdFx0dmFsQiA9IG51bGxcblxuXHRcdGxlbiA9IGEubGVuZ3RoXG5cblx0XHRpZiBsZW4gPCAxXG5cblx0XHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0XHRyZXR1cm4gYVxuXG5cblx0XHRmb3IgdmFsLCBpIGluIGFcblxuXHRcdFx0dmFsQSA9IHZhbEJcblxuXHRcdFx0dmFsQiA9IHZhbFxuXG5cdFx0XHRpZiBzaG91bGRJbmplY3QgdmFsQSwgdmFsQiwgdG9JbmplY3RcblxuXHRcdFx0XHRyZXR1cm4gYS5zcGxpY2UgaSwgMCwgdG9JbmplY3RcblxuXHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0YVxuXG5cdGluamVjdEluSW5kZXg6IChhLCBpbmRleCwgdG9JbmplY3QpIC0+XG5cblx0XHRsZW4gPSBhLmxlbmd0aFxuXG5cdFx0aSA9IGluZGV4XG5cblx0XHRpZiBsZW4gPCAxXG5cblx0XHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0XHRyZXR1cm4gYVxuXG5cdFx0dG9QdXQgPSB0b0luamVjdFxuXG5cdFx0dG9QdXROZXh0ID0gbnVsbFxuXG5cdFx0YGZvcig7IGkgPD0gbGVuOyBpKyspe1xuXG5cdFx0XHR0b1B1dE5leHQgPSBhW2ldO1xuXG5cdFx0XHRhW2ldID0gdG9QdXQ7XG5cblx0XHRcdHRvUHV0ID0gdG9QdXROZXh0O1xuXG5cdFx0fWBcblxuXHRcdCMgYVtpXSA9IHRvUHV0XG5cblx0XHRudWxsIl19 \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/lib/classic.js b/node_modules/utila/scripts/js/lib/classic.js
new file mode 100644
index 000000000..3de0c290f
--- /dev/null
+++ b/node_modules/utila/scripts/js/lib/classic.js
@@ -0,0 +1,87 @@
+var classic,
+ __slice = [].slice;
+
+module.exports = classic = {};
+
+classic.implement = function() {
+ var classProto, classReference, desc, member, mixin, mixins, _i, _j, _len;
+ mixins = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), classReference = arguments[_i++];
+ for (_j = 0, _len = mixins.length; _j < _len; _j++) {
+ mixin = mixins[_j];
+ classProto = classReference.prototype;
+ for (member in mixin.prototype) {
+ if (!Object.getOwnPropertyDescriptor(classProto, member)) {
+ desc = Object.getOwnPropertyDescriptor(mixin.prototype, member);
+ Object.defineProperty(classProto, member, desc);
+ }
+ }
+ }
+ return classReference;
+};
+
+classic.mix = function() {
+ var classProto, classReference, desc, member, mixin, mixins, _i, _j, _len;
+ mixins = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), classReference = arguments[_i++];
+ classProto = classReference.prototype;
+ classReference.__mixinCloners = [];
+ classReference.__applyClonersFor = function(instance, args) {
+ var cloner, _j, _len, _ref;
+ if (args == null) {
+ args = null;
+ }
+ _ref = classReference.__mixinCloners;
+ for (_j = 0, _len = _ref.length; _j < _len; _j++) {
+ cloner = _ref[_j];
+ cloner.apply(instance, args);
+ }
+ };
+ classReference.__mixinInitializers = [];
+ classReference.__initMixinsFor = function(instance, args) {
+ var initializer, _j, _len, _ref;
+ if (args == null) {
+ args = null;
+ }
+ _ref = classReference.__mixinInitializers;
+ for (_j = 0, _len = _ref.length; _j < _len; _j++) {
+ initializer = _ref[_j];
+ initializer.apply(instance, args);
+ }
+ };
+ classReference.__mixinQuitters = [];
+ classReference.__applyQuittersFor = function(instance, args) {
+ var quitter, _j, _len, _ref;
+ if (args == null) {
+ args = null;
+ }
+ _ref = classReference.__mixinQuitters;
+ for (_j = 0, _len = _ref.length; _j < _len; _j++) {
+ quitter = _ref[_j];
+ quitter.apply(instance, args);
+ }
+ };
+ for (_j = 0, _len = mixins.length; _j < _len; _j++) {
+ mixin = mixins[_j];
+ if (!(mixin.constructor instanceof Function)) {
+ throw Error("Mixin should be a function");
+ }
+ for (member in mixin.prototype) {
+ if (member.substr(0, 11) === '__initMixin') {
+ classReference.__mixinInitializers.push(mixin.prototype[member]);
+ continue;
+ } else if (member.substr(0, 11) === '__clonerFor') {
+ classReference.__mixinCloners.push(mixin.prototype[member]);
+ continue;
+ } else if (member.substr(0, 12) === '__quitterFor') {
+ classReference.__mixinQuitters.push(mixin.prototype[member]);
+ continue;
+ }
+ if (!Object.getOwnPropertyDescriptor(classProto, member)) {
+ desc = Object.getOwnPropertyDescriptor(mixin.prototype, member);
+ Object.defineProperty(classProto, member, desc);
+ }
+ }
+ }
+ return classReference;
+};
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3NpYy5qcyIsInNvdXJjZVJvb3QiOiIuLlxcLi4iLCJzb3VyY2VzIjpbImNvZmZlZVxcbGliXFxjbGFzc2ljLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFBLE9BQUE7RUFBQSxrQkFBQTs7QUNBQSxNQ0FNLENDQUMsT0NBUCxHQ0FpQixPQ0FBLEdDQVUsRUFBM0IsQ0FBQTs7QUNJQSxPQ0FPLENDQUMsU0NBUixHQ0FvQixTQ0FBLEdDQUE7QUNFbkIsTUNBQSxxRUNBQTtBQ0FBLEVDRm9CLHVHQ0FXLGdDQ0UvQixDQ0FBO0FDQUEsT0NBQSw2Q0NBQTt1QkNBQTtBQ0VDLElDQUEsVUNBQSxHQ0FhLGNDQWMsQ0NBQSxTQ0EzQixDQ0FBO0FDRUEsU0NBQSx5QkNBQSxHQ0FBO0FDRUMsTUNBQSxJQ0FBLENDQU8sTUNBTSxDQ0FDLHdCQ0FQLENDQWdDLFVDQWhDLEVDQTRDLE1DQTVDLENDQVA7QUNFQyxRQ0FBLElDQUEsR0NBTyxNQ0FNLENDQUMsd0JDQVAsQ0NBZ0MsS0NBSyxDQ0FBLFNDQXJDLEVDQXlDLE1DQXpDLENDQVAsQ0NBQTtBQ0FBLFFDRUEsTUNBTSxDQ0FDLGNDQVAsQ0NBc0IsVUNBdEIsRUNBa0MsTUNBbEMsRUNBMEMsSUNBMUMsQ0NGQSxDQ0ZEO09DRkQ7QUNBQSxLQ0pEO0FDQUEsR0NBQTtTQ1lBLGVDZG1CO0FDQUEsQ0FKcEIsQ0FBQTs7QUNvQkEsT0NBTyxDQ0FDLEdDQVIsR0NBYyxTQ0FBLEdDQUE7QUNFYixNQ0FBLHFFQ0FBO0FDQUEsRUNGYyx1R0NBVyxnQ0NFekIsQ0NBQTtBQ0FBLEVDQUEsVUNBQSxHQ0FhLGNDQWMsQ0NBQSxTQ0EzQixDQ0FBO0FDQUEsRUNFQSxjQ0FjLENDQUMsY0NBZixHQ0FnQyxFQ0ZoQyxDQ0FBO0FDQUEsRUNJQSxjQ0FjLENDQUMsaUJDQWYsR0NBbUMsU0NBQyxRQ0FELEVDQVcsSUNBWCxHQ0FBO0FDRWxDLFFDQUEsc0JDQUE7O01DRjZDLE9DQU87S0NFcEQ7QUNBQTtBQ0FBLFNDQUEsMkNDQUE7d0JDQUE7QUNFQyxNQ0FBLE1DQU0sQ0NBQyxLQ0FQLENDQWEsUUNBYixFQ0F1QixJQ0F2QixDQ0FBLENDRkQ7QUNBQSxLQ0ZrQztFQ0FBLENDSm5DLENDQUE7QUNBQSxFQ1lBLGNDQWMsQ0NBQyxtQkNBZixHQ0FxQyxFQ1pyQyxDQ0FBO0FDQUEsRUNjQSxjQ0FjLENDQUMsZUNBZixHQ0FpQyxTQ0FDLFFDQUQsRUNBVyxJQ0FYLEdDQUE7QUNFaEMsUUNBQSwyQkNBQTs7TUNGMkMsT0NBTztLQ0VsRDtBQ0FBO0FDQUEsU0NBQSwyQ0NBQTs2QkNBQTtBQ0VDLE1DQUEsV0NBVyxDQ0FDLEtDQVosQ0NBa0IsUUNBbEIsRUNBNEIsSUNBNUIsQ0NBQSxDQ0ZEO0FDQUEsS0NGZ0M7RUNBQSxDQ2RqQyxDQ0FBO0FDQUEsRUNzQkEsY0NBYyxDQ0FDLGVDQWYsR0NBaUMsRUN0QmpDLENDQUE7QUNBQSxFQ3dCQSxjQ0FjLENDQUMsa0JDQWYsR0NBb0MsU0NBQyxRQ0FELEVDQVcsSUNBWCxHQ0FBO0FDRW5DLFFDQUEsdUJDQUE7O01DRjhDLE9DQU87S0NFckQ7QUNBQTtBQ0FBLFNDQUEsMkNDQUE7eUJDQUE7QUNFQyxNQ0FBLE9DQU8sQ0NBQyxLQ0FSLENDQWMsUUNBZCxFQ0F3QixJQ0F4QixDQ0FBLENDRkQ7QUNBQSxLQ0ZtQztFQ0FBLENDeEJwQyxDQ0FBO0FDZ0NBLE9DQUEsNkNDQUE7dUJDQUE7QUNFQyxJQ0FBLElDQUEsQ0NBQSxDQ0FPLEtDQUssQ0NBQyxXQ0FOLFlDQTZCLFFDQXBDLENDQUE7QUNFQyxZQ0FNLEtDQUEsQ0NBTSw0QkNBTixDQ0FOLENDRkQ7S0NBQTtBQ0lBLFNDQUEseUJDQUEsR0NBQTtBQ0VDLE1DQUEsSUNBRyxNQ0FNLENDQUMsTUNBUCxDQ0FjLENDQWQsRUNBaUIsRUNBakIsQ0NBQSxLQ0F3QixhQ0EzQjtBQ0VDLFFDQUEsY0NBYyxDQ0FDLG1CQ0FtQixDQ0FDLElDQW5DLENDQXdDLEtDQUssQ0NBQSxTQ0FHLENDQUEsTUNBQSxDQ0FoRCxDQ0FBLENDQUE7QUNFQSxpQkNKRDtPQ0FBLE1DTUssSUNBRyxNQ0FNLENDQUMsTUNBUCxDQ0FjLENDQWQsRUNBaUIsRUNBakIsQ0NBQSxLQ0F3QixhQ0EzQjtBQ0VKLFFDQUEsY0NBYyxDQ0FDLGNDQWMsQ0NBQyxJQ0E5QixDQ0FtQyxLQ0FLLENDQUEsU0NBRyxDQ0FBLE1DQUEsQ0NBM0MsQ0NBQSxDQ0FBO0FDRUEsaUJDSkk7T0NBQSxNQ01BLElDQUcsTUNBTSxDQ0FDLE1DQVAsQ0NBYyxDQ0FkLEVDQWlCLEVDQWpCLENDQUEsS0NBd0IsY0NBM0I7QUNFSixRQ0FBLGNDQWMsQ0NBQyxlQ0FlLENDQUMsSUNBL0IsQ0NBb0MsS0NBSyxDQ0FBLFNDQUcsQ0NBQSxNQ0FBLENDQTVDLENDQUEsQ0NBQTtBQ0VBLGlCQ0pJO09DWkw7QUNrQkEsTUNBQSxJQ0FBLENDQU8sTUNBTSxDQ0FDLHdCQ0FQLENDQWdDLFVDQWhDLEVDQTRDLE1DQTVDLENDQVA7QUNFQyxRQ0FBLElDQUEsR0NBTyxNQ0FNLENDQUMsd0JDQVAsQ0NBZ0MsS0NBSyxDQ0FBLFNDQXJDLEVDQXlDLE1DQXpDLENDQVAsQ0NBQTtBQ0FBLFFDRUEsTUNBTSxDQ0FDLGNDQVAsQ0NBc0IsVUNBdEIsRUNBa0MsTUNBbEMsRUNBMEMsSUNBMUMsQ0NGQSxDQ0ZEO09DcEJEO0FDQUEsS0NORDtBQ0FBLEdDaENBO1NDZ0VBLGVDbEVhO0FDQUEsQ0FwQmQsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXJyYXkgPVxuXG5cdCMjI1xuXHRUcmllcyB0byB0dXJuIGFueXRoaW5nIGludG8gYW4gYXJyYXkuXG5cdCMjI1xuXHRmcm9tOiAocikgLT5cblxuXHRcdEFycmF5OjpzbGljZS5jYWxsIHJcblxuXHQjIyNcblx0Q2xvbmUgb2YgYW4gYXJyYXkuIFByb3BlcnRpZXMgd2lsbCBiZSBzaGFsbG93IGNvcGllcy5cblx0IyMjXG5cdHNpbXBsZUNsb25lOiAoYSkgLT5cblxuXHRcdGEuc2xpY2UgMFxuXG5cdHNoYWxsb3dFcXVhbDogKGExLCBhMikgLT5cblxuXHRcdHJldHVybiBubyB1bmxlc3MgQXJyYXkuaXNBcnJheShhMSkgYW5kIEFycmF5LmlzQXJyYXkoYTIpIGFuZCBhMS5sZW5ndGggaXMgYTIubGVuZ3RoXG5cblx0XHRmb3IgdmFsLCBpIGluIGExXG5cblx0XHRcdHJldHVybiBubyB1bmxlc3MgYTJbaV0gaXMgdmFsXG5cblx0XHR5ZXNcblxuXHRwbHVjazogKGEsIGkpIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIGluZGV4ID4gaVxuXG5cdFx0XHRcdGFbaW5kZXggLSAxXSA9IGFbaW5kZXhdXG5cblx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gMVxuXG5cdFx0YVxuXG5cdHBsdWNrSXRlbTogKGEsIGl0ZW0pIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXG5cdFx0cmVtb3ZlZCA9IDBcblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiB2YWx1ZSBpcyBpdGVtXG5cblx0XHRcdFx0cmVtb3ZlZCsrXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0aWYgcmVtb3ZlZCBpc250IDBcblxuXHRcdFx0XHRhW2luZGV4IC0gcmVtb3ZlZF0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIHJlbW92ZWQgaWYgcmVtb3ZlZCA+IDBcblxuXHRcdGFcblxuXHRwbHVja09uZUl0ZW06IChhLCBpdGVtKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblx0XHRyZWFjaGVkID0gbm9cblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBub3QgcmVhY2hlZFxuXG5cdFx0XHRcdGlmIHZhbHVlIGlzIGl0ZW1cblxuXHRcdFx0XHRcdHJlYWNoZWQgPSB5ZXNcblxuXHRcdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2VcblxuXHRcdFx0XHRhW2luZGV4IC0gMV0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIDEgaWYgcmVhY2hlZFxuXG5cdFx0YVxuXG5cdHBsdWNrQnlDYWxsYmFjazogKGEsIGNiKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblx0XHRyZW1vdmVkID0gMFxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIGNiIHZhbHVlLCBpbmRleFxuXG5cdFx0XHRcdHJlbW92ZWQrK1xuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGlmIHJlbW92ZWQgaXNudCAwXG5cblx0XHRcdFx0YVtpbmRleCAtIHJlbW92ZWRdID0gYVtpbmRleF1cblxuXHRcdGlmIHJlbW92ZWQgPiAwXG5cblx0XHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSByZW1vdmVkXG5cblx0XHRhXG5cblx0cGx1Y2tNdWx0aXBsZTogKGFycmF5LCBpbmRleGVzVG9SZW1vdmUpIC0+XG5cblx0XHRyZXR1cm4gYXJyYXkgaWYgYXJyYXkubGVuZ3RoIDwgMVxuXG5cdFx0cmVtb3ZlZFNvRmFyID0gMFxuXG5cdFx0aW5kZXhlc1RvUmVtb3ZlLnNvcnQoKVxuXG5cdFx0Zm9yIGkgaW4gaW5kZXhlc1RvUmVtb3ZlXG5cblx0XHRcdEBwbHVjayBhcnJheSwgaSAtIHJlbW92ZWRTb0ZhclxuXG5cdFx0XHRyZW1vdmVkU29GYXIrK1xuXG5cdFx0YXJyYXlcblxuXHRpbmplY3RCeUNhbGxiYWNrOiAoYSwgdG9JbmplY3QsIHNob3VsZEluamVjdCkgLT5cblxuXHRcdHZhbEEgPSBudWxsXG5cblx0XHR2YWxCID0gbnVsbFxuXG5cdFx0bGVuID0gYS5sZW5ndGhcblxuXHRcdGlmIGxlbiA8IDFcblxuXHRcdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRcdHJldHVybiBhXG5cblxuXHRcdGZvciB2YWwsIGkgaW4gYVxuXG5cdFx0XHR2YWxBID0gdmFsQlxuXG5cdFx0XHR2YWxCID0gdmFsXG5cblx0XHRcdGlmIHNob3VsZEluamVjdCB2YWxBLCB2YWxCLCB0b0luamVjdFxuXG5cdFx0XHRcdHJldHVybiBhLnNwbGljZSBpLCAwLCB0b0luamVjdFxuXG5cdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRhXG5cblx0aW5qZWN0SW5JbmRleDogKGEsIGluZGV4LCB0b0luamVjdCkgLT5cblxuXHRcdGxlbiA9IGEubGVuZ3RoXG5cblx0XHRpID0gaW5kZXhcblxuXHRcdGlmIGxlbiA8IDFcblxuXHRcdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRcdHJldHVybiBhXG5cblx0XHR0b1B1dCA9IHRvSW5qZWN0XG5cblx0XHR0b1B1dE5leHQgPSBudWxsXG5cblx0XHRgZm9yKDsgaSA8PSBsZW47IGkrKyl7XG5cblx0XHRcdHRvUHV0TmV4dCA9IGFbaV07XG5cblx0XHRcdGFbaV0gPSB0b1B1dDtcblxuXHRcdFx0dG9QdXQgPSB0b1B1dE5leHQ7XG5cblx0XHR9YFxuXG5cdFx0IyBhW2ldID0gdG9QdXRcblxuXHRcdG51bGwiLCJtb2R1bGUuZXhwb3J0cyA9IGNsYXNzaWMgPSB7fVxuXG4jIExpdHRsZSBoZWxwZXIgZm9yIG1peGlucyBmcm9tIENvZmZlZVNjcmlwdCBGQVEsXG4jIGNvdXJ0ZXN5IG9mIFNldGhhdXJ1cyAoaHR0cDovL2dpdGh1Yi5jb20vc2V0aGF1cnVzKVxuY2xhc3NpYy5pbXBsZW1lbnQgPSAobWl4aW5zLi4uLCBjbGFzc1JlZmVyZW5jZSkgLT5cblxuXHRmb3IgbWl4aW4gaW4gbWl4aW5zXG5cblx0XHRjbGFzc1Byb3RvID0gY2xhc3NSZWZlcmVuY2U6OlxuXG5cdFx0Zm9yIG1lbWJlciBvZiBtaXhpbjo6XG5cblx0XHRcdHVubGVzcyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIGNsYXNzUHJvdG8sIG1lbWJlclxuXG5cdFx0XHRcdGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIG1peGluOjosIG1lbWJlclxuXG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBjbGFzc1Byb3RvLCBtZW1iZXIsIGRlc2NcblxuXHRjbGFzc1JlZmVyZW5jZVxuXG5jbGFzc2ljLm1peCA9IChtaXhpbnMuLi4sIGNsYXNzUmVmZXJlbmNlKSAtPlxuXG5cdGNsYXNzUHJvdG8gPSBjbGFzc1JlZmVyZW5jZTo6XG5cblx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnMgPSBbXVxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fYXBwbHlDbG9uZXJzRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBjbG9uZXIgaW4gY2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnNcblxuXHRcdFx0Y2xvbmVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRjbGFzc1JlZmVyZW5jZS5fX21peGluSW5pdGlhbGl6ZXJzID0gW11cblxuXHRjbGFzc1JlZmVyZW5jZS5fX2luaXRNaXhpbnNGb3IgPSAoaW5zdGFuY2UsIGFyZ3MgPSBudWxsKSAtPlxuXG5cdFx0Zm9yIGluaXRpYWxpemVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5Jbml0aWFsaXplcnNcblxuXHRcdFx0aW5pdGlhbGl6ZXIuYXBwbHkgaW5zdGFuY2UsIGFyZ3NcblxuXHRcdHJldHVyblxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVycyA9IFtdXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19hcHBseVF1aXR0ZXJzRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBxdWl0dGVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVyc1xuXG5cdFx0XHRxdWl0dGVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRmb3IgbWl4aW4gaW4gbWl4aW5zXG5cblx0XHR1bmxlc3MgbWl4aW4uY29uc3RydWN0b3IgaW5zdGFuY2VvZiBGdW5jdGlvblxuXG5cdFx0XHR0aHJvdyBFcnJvciBcIk1peGluIHNob3VsZCBiZSBhIGZ1bmN0aW9uXCJcblxuXHRcdGZvciBtZW1iZXIgb2YgbWl4aW46OlxuXG5cdFx0XHRpZiBtZW1iZXIuc3Vic3RyKDAsIDExKSBpcyAnX19pbml0TWl4aW4nXG5cblx0XHRcdFx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkluaXRpYWxpemVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2UgaWYgbWVtYmVyLnN1YnN0cigwLCAxMSkgaXMgJ19fY2xvbmVyRm9yJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzLnB1c2ggbWl4aW46OlttZW1iZXJdXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0ZWxzZSBpZiBtZW1iZXIuc3Vic3RyKDAsIDEyKSBpcyAnX19xdWl0dGVyRm9yJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdHVubGVzcyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIGNsYXNzUHJvdG8sIG1lbWJlclxuXG5cdFx0XHRcdGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIG1peGluOjosIG1lbWJlclxuXG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBjbGFzc1Byb3RvLCBtZW1iZXIsIGRlc2NcblxuXHRjbGFzc1JlZmVyZW5jZSJdfQ== \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/lib/object.js b/node_modules/utila/scripts/js/lib/object.js
new file mode 100644
index 000000000..c776361c0
--- /dev/null
+++ b/node_modules/utila/scripts/js/lib/object.js
@@ -0,0 +1,158 @@
+var object, _common,
+ __hasProp = {}.hasOwnProperty;
+
+_common = require('./_common');
+
+module.exports = object = {
+ isBareObject: _common.isBareObject.bind(_common),
+
+ /*
+ if object is an instance of a class
+ */
+ isInstance: function(what) {
+ return !this.isBareObject(what);
+ },
+
+ /*
+ Alias to _common.typeOf
+ */
+ typeOf: _common.typeOf.bind(_common),
+
+ /*
+ Alias to _common.clone
+ */
+ clone: _common.clone.bind(_common),
+
+ /*
+ Empties an object of its properties.
+ */
+ empty: function(o) {
+ var prop;
+ for (prop in o) {
+ if (o.hasOwnProperty(prop)) {
+ delete o[prop];
+ }
+ }
+ return o;
+ },
+
+ /*
+ Empties an object. Doesn't check for hasOwnProperty, so it's a tiny
+ bit faster. Use it for plain objects.
+ */
+ fastEmpty: function(o) {
+ var property;
+ for (property in o) {
+ delete o[property];
+ }
+ return o;
+ },
+
+ /*
+ Overrides values fomr `newValues` on `base`, as long as they
+ already exist in base.
+ */
+ overrideOnto: function(base, newValues) {
+ var key, newVal, oldVal;
+ if (!this.isBareObject(newValues) || !this.isBareObject(base)) {
+ return base;
+ }
+ for (key in base) {
+ oldVal = base[key];
+ newVal = newValues[key];
+ if (newVal === void 0) {
+ continue;
+ }
+ if (typeof newVal !== 'object' || this.isInstance(newVal)) {
+ base[key] = this.clone(newVal);
+ } else {
+ if (typeof oldVal !== 'object' || this.isInstance(oldVal)) {
+ base[key] = this.clone(newVal);
+ } else {
+ this.overrideOnto(oldVal, newVal);
+ }
+ }
+ }
+ return base;
+ },
+
+ /*
+ Takes a clone of 'base' and runs #overrideOnto on it
+ */
+ override: function(base, newValues) {
+ return this.overrideOnto(this.clone(base), newValues);
+ },
+ append: function(base, toAppend) {
+ return this.appendOnto(this.clone(base), toAppend);
+ },
+ appendOnto: function(base, toAppend) {
+ var key, newVal, oldVal;
+ if (!this.isBareObject(toAppend) || !this.isBareObject(base)) {
+ return base;
+ }
+ for (key in toAppend) {
+ if (!__hasProp.call(toAppend, key)) continue;
+ newVal = toAppend[key];
+ if (newVal === void 0) {
+ continue;
+ }
+ if (typeof newVal !== 'object' || this.isInstance(newVal)) {
+ base[key] = newVal;
+ } else {
+ oldVal = base[key];
+ if (typeof oldVal !== 'object' || this.isInstance(oldVal)) {
+ base[key] = this.clone(newVal);
+ } else {
+ this.appendOnto(oldVal, newVal);
+ }
+ }
+ }
+ return base;
+ },
+ groupProps: function(obj, groups) {
+ var def, defs, grouped, key, name, shouldAdd, val, _i, _len;
+ grouped = {};
+ for (name in groups) {
+ defs = groups[name];
+ grouped[name] = {};
+ }
+ grouped['rest'] = {};
+ top: //;
+ for (key in obj) {
+ val = obj[key];
+ shouldAdd = false;
+ for (name in groups) {
+ defs = groups[name];
+ if (!Array.isArray(defs)) {
+ defs = [defs];
+ }
+ for (_i = 0, _len = defs.length; _i < _len; _i++) {
+ def = defs[_i];
+ if (typeof def === 'string') {
+ if (key === def) {
+ shouldAdd = true;
+ }
+ } else if (def instanceof RegExp) {
+ if (def.test(key)) {
+ shouldAdd = true;
+ }
+ } else if (def instanceof Function) {
+ if (def(key)) {
+ shouldAdd = true;
+ }
+ } else {
+ throw Error('Group definitions must either be strings, regexes, or functions.');
+ }
+ if (shouldAdd) {
+ grouped[name][key] = val;
+ continue top;
+ }
+ }
+ }
+ grouped['rest'][key] = val;
+ }
+ return grouped;
+ }
+};
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0LmpzIiwic291cmNlUm9vdCI6Ii4uXFwuLiIsInNvdXJjZXMiOlsiY29mZmVlXFxsaWJcXG9iamVjdC5jb2ZmZWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsSUFBQSxlQUFBO0VBQUEsNkJBQUE7O0FHQUEsT0dBQSxHR0FVLE9HQUEsQ0dBUSxXR0FSLENBQVYsQ0FBQTs7QUdFQSxNR0FNLENHQUMsT0dBUCxHR0FpQixNR0FBLEdHRWhCO0FHQUEsRUdBQSxZR0FBLEVHQWMsT0dBTyxDR0FDLFlHQVksQ0dBQyxJR0FyQixDR0EwQixPR0ExQixDR0FkO0FHRUE7QUdBQTs7S0dGQTtBR0FBLEVHS0EsVUdBQSxFR0FZLFNHQUMsSUdBRCxHR0FBO1dHRVgsQ0dBSSxJR0FDLENHQUEsWUdBRCxDR0FjLElHQWQsRUdGTztFR0FBLENHTFo7QUdTQTtBR0FBOztLR1RBO0FHQUEsRUdZQSxNR0FBLEVHQVEsT0dBTyxDR0FDLE1HQU0sQ0dBQyxJR0FmLENHQW9CLE9HQXBCLENHWlI7QUdjQTtBR0FBOztLR2RBO0FHQUEsRUdpQkEsS0dBQSxFR0FPLE9HQU8sQ0dBQyxLR0FLLENHQUMsSUdBZCxDR0FtQixPR0FuQixDR2pCUDtBR21CQTtBR0FBOztLR25CQTtBR0FBLEVHc0JBLEtHQUEsRUdBTyxTR0FDLENHQUQsR0dBQTtBR0VOLFFHQUEsSUdBQTtBR0FBLFNHQUEsU0dBQSxHR0FBO0FHRUMsTUdBQSxJR0FrQixDR0FDLENHQUMsY0dBRixDR0FpQixJR0FqQixDR0FsQjtBR0FBLFFHQUEsTUdBQSxDR0FPLENHQUUsQ0dBQSxJR0FBLENHQVQsQ0dBQTtPR0ZEO0FHQUEsS0dBQTtXR0lBLEVHTk07RUdBQSxDR3RCUDtBRzhCQTtBR0FBOzs7S0c5QkE7QUdBQSxFR2tDQSxTR0FBLEVHQVcsU0dBQyxDR0FELEdHQUE7QUdFVixRR0FBLFFHQUE7QUdBQSxTR0FBLGFHQUEsR0dBQTtBR0FBLE1HQUEsTUdBQSxDR0FPLENHQUUsQ0dBQSxRR0FBLENHQVQsQ0dBQTtBR0FBLEtHQUE7V0dFQSxFR0pVO0VHQUEsQ0dsQ1g7QUd3Q0E7QUdBQTs7O0tHeENBO0FHQUEsRUc0Q0EsWUdBQSxFR0FjLFNHQUMsSUdBRCxFR0FPLFNHQVAsR0dBQTtBR0ViLFFHQUEsbUJHQUE7QUdBQSxJR0FBLElHQWUsQ0dBSSxJR0FDLENHQUEsWUdBRCxDR0FjLFNHQWQsQ0dBSixJR0FnQyxDR0FJLElHQUMsQ0dBQSxZR0FELENHQWMsSUdBZCxDR0FuRDtBR0FBLGFHQU8sSUdBUCxDR0FBO0tHQUE7QUdFQSxTR0FBLFdHQUE7eUJHQUE7QUdFQyxNR0FBLE1HQUEsR0dBUyxTR0FVLENHQUEsR0dBQSxDR0FuQixDR0FBO0FHRUEsTUdBQSxJR0FZLE1HQUEsS0dBVSxNR0F0QjtBR0FBLGlCR0FBO09HRkE7QUdJQSxNR0FBLElHQUcsTUdBQSxDR0FPLE1HQVAsS0dBbUIsUUdBbkIsSUdBK0IsSUdBQyxDR0FBLFVHQUQsQ0dBWSxNR0FaLENHQWxDO0FHRUMsUUdBQSxJR0FLLENHQUEsR0dBQSxDR0FMLEdHQVksSUdBQyxDR0FBLEtHQUQsQ0dBTyxNR0FQLENHQVosQ0dGRDtPR0FBLE1HQUE7QUdPQyxRR0FBLElHQUcsTUdBQSxDR0FPLE1HQVAsS0dBbUIsUUdBbkIsSUdBK0IsSUdBQyxDR0FBLFVHQUQsQ0dBWSxNR0FaLENHQWxDO0FHRUMsVUdBQSxJR0FLLENHQUEsR0dBQSxDR0FMLEdHQVksSUdBQyxDR0FBLEtHQUQsQ0dBTyxNR0FQLENHQVosQ0dGRDtTR0FBLE1HQUE7QUdNQyxVR0FBLElHQUMsQ0dBQSxZR0FELENHQWMsTUdBZCxFR0FzQixNR0F0QixDR0FBLENHTkQ7U0dQRDtPR05EO0FHQUEsS0dGQTtXR3NCQSxLR3hCYTtFR0FBLENHNUNkO0FHc0VBO0FHQUE7O0tHdEVBO0FHQUEsRUd5RUEsUUdBQSxFR0FVLFNHQUMsSUdBRCxFR0FPLFNHQVAsR0dBQTtXR0VULElHQUMsQ0dBQSxZR0FELENHQWMsSUdBQyxDR0FBLEtHQUQsQ0dBTyxJR0FQLENHQWQsRUdBNEIsU0dBNUIsRUdGUztFR0FBLENHekVWO0FHQUEsRUc2RUEsTUdBQSxFR0FRLFNHQUMsSUdBRCxFR0FPLFFHQVAsR0dBQTtXR0VQLElHQUMsQ0dBQSxVR0FELENHQVksSUdBQyxDR0FBLEtHQUQsQ0dBTyxJR0FQLENHQVosRUdBMEIsUUdBMUIsRUdGTztFR0FBLENHN0VSO0FHQUEsRUdrRkEsVUdBQSxFR0FZLFNHQUMsSUdBRCxFR0FPLFFHQVAsR0dBQTtBR0VYLFFHQUEsbUJHQUE7QUdBQSxJR0FBLElHQWUsQ0dBSSxJR0FDLENHQUEsWUdBRCxDR0FjLFFHQWQsQ0dBSixJR0ErQixDR0FJLElHQUMsQ0dBQSxZR0FELENHQWMsSUdBZCxDR0FsRDtBR0FBLGFHQU8sSUdBUCxDR0FBO0tHQUE7QUdFQSxTR0FBLGVHQUE7OzZCR0FBO0FHRUMsTUdBQSxJR0FnQixNR0FBLEtHQVksTUdBNUI7QUdBQSxpQkdBQTtPR0FBO0FHRUEsTUdBQSxJR0FHLE1HQUEsQ0dBTyxNR0FQLEtHQW1CLFFHQW5CLElHQStCLElHQUMsQ0dBQSxVR0FELENHQVksTUdBWixDR0FsQztBR0VDLFFHQUEsSUdBSyxDR0FBLEdHQUEsQ0dBTCxHR0FZLE1HQVosQ0dGRDtPR0FBLE1HQUE7QUdRQyxRR0FBLE1HQUEsR0dBUyxJR0FLLENHQUEsR0dBQSxDR0FkLENHQUE7QUdFQSxRR0FBLElHQUcsTUdBQSxDR0FPLE1HQVAsS0dBbUIsUUdBbkIsSUdBK0IsSUdBQyxDR0FBLFVHQUQsQ0dBWSxNR0FaLENHQWxDO0FHRUMsVUdBQSxJR0FLLENHQUEsR0dBQSxDR0FMLEdHQVksSUdBQyxDR0FBLEtHQUQsQ0dBTyxNR0FQLENHQVosQ0dGRDtTR0FBLE1HQUE7QUdNQyxVR0FBLElHQUMsQ0dBQSxVR0FELENHQVksTUdBWixFR0FvQixNR0FwQixDR0FBLENHTkQ7U0dWRDtPR0pEO0FHQUEsS0dGQTtXR3dCQSxLRzFCVztFR0FBLENHbEZaO0FHQUEsRUcrR0EsVUdBQSxFR0FZLFNHQUMsR0dBRCxFR0FNLE1HQU4sR0dBQTtBR0VYLFFHQUEsdURHQUE7QUdBQSxJR0FBLE9HQUEsR0dBVSxFR0FWLENHQUE7QUdFQSxTR0FBLGNHQUE7MEJHQUE7QUdFQyxNR0FBLE9HQVEsQ0dBQSxJR0FBLENHQVIsR0dBZ0IsRUdBaEIsQ0dGRDtBR0FBLEtHRkE7QUdBQSxJR01BLE9HQVEsQ0dBQSxNR0FBLENHQVIsR0dBa0IsRUdObEIsQ0dBQTtBR0FBLElHUUEsT0dSQSxDR0FBO0FHU0EsU0dBQSxVR0FBO3FCR0FBO0FHRUMsTUdBQSxTR0FBLEdHQVksS0dBWixDR0FBO0FHRUEsV0dBQSxjR0FBOzRCR0FBO0FHRUMsUUdBQSxJR0FBLENHQU8sS0dBSyxDR0FDLE9HQU4sQ0dBYyxJR0FkLENHQVA7QUdFQyxVR0FBLElHQUEsR0dBTyxDR0FDLElHQUQsQ0dBUCxDR0ZEO1NHQUE7QUdJQSxhR0FBLDJDR0FBO3lCR0FBO0FHRUMsVUdBQSxJR0FHLE1HQUEsQ0dBTyxHR0FQLEtHQWMsUUdBakI7QUdFQyxZR0FBLElHQUcsR0dBQSxLR0FPLEdHQVY7QUdFQyxjR0FBLFNHQUEsR0dBWSxJR0FaLENHRkQ7YUdGRDtXR0FBLE1HTUssSUdBRyxHR0FBLFlHQWUsTUdBbEI7QUdFSixZR0FBLElHQUcsR0dBRyxDR0FDLElHQUosQ0dBUyxHR0FULENHQUg7QUdFQyxjR0FBLFNHQUEsR0dBWSxJR0FaLENHRkQ7YUdGSTtXR0FBLE1HTUEsSUdBRyxHR0FBLFlHQWUsUUdBbEI7QUdFSixZR0FBLElHQUcsR0dBQSxDR0FJLEdHQUosQ0dBSDtBR0VDLGNHQUEsU0dBQSxHR0FZLElHQVosQ0dGRDthR0ZJO1dHQUEsTUdBQTtBR1FKLGtCR0FNLEtHQUEsQ0dBTSxrRUdBTixDR0FOLENHUkk7V0daTDtBR3VCQSxVR0FBLElHQUcsU0dBSDtBR0VDLFlHQUEsT0dBUSxDR0FBLElHQUEsQ0dBTSxDR0FBLEdHQUEsQ0dBZCxHR0FxQixHR0FyQixDR0FBO0FHQUEsWUdFQSxZR0ZBLENHRkQ7V0d6QkQ7QUdBQSxTR05EO0FHQUEsT0dGQTtBR0FBLE1HdUNBLE9HQVEsQ0dBQSxNR0FBLENHQVEsQ0dBQSxHR0FBLENHQWhCLEdHQXVCLEdHdkN2QixDR0ZEO0FHQUEsS0dUQTtXR29EQSxRR3REVztFR0FBLENHL0daO0NBSkQsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXJyYXkgPVxuXG5cdCMjI1xuXHRUcmllcyB0byB0dXJuIGFueXRoaW5nIGludG8gYW4gYXJyYXkuXG5cdCMjI1xuXHRmcm9tOiAocikgLT5cblxuXHRcdEFycmF5OjpzbGljZS5jYWxsIHJcblxuXHQjIyNcblx0Q2xvbmUgb2YgYW4gYXJyYXkuIFByb3BlcnRpZXMgd2lsbCBiZSBzaGFsbG93IGNvcGllcy5cblx0IyMjXG5cdHNpbXBsZUNsb25lOiAoYSkgLT5cblxuXHRcdGEuc2xpY2UgMFxuXG5cdHNoYWxsb3dFcXVhbDogKGExLCBhMikgLT5cblxuXHRcdHJldHVybiBubyB1bmxlc3MgQXJyYXkuaXNBcnJheShhMSkgYW5kIEFycmF5LmlzQXJyYXkoYTIpIGFuZCBhMS5sZW5ndGggaXMgYTIubGVuZ3RoXG5cblx0XHRmb3IgdmFsLCBpIGluIGExXG5cblx0XHRcdHJldHVybiBubyB1bmxlc3MgYTJbaV0gaXMgdmFsXG5cblx0XHR5ZXNcblxuXHRwbHVjazogKGEsIGkpIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIGluZGV4ID4gaVxuXG5cdFx0XHRcdGFbaW5kZXggLSAxXSA9IGFbaW5kZXhdXG5cblx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gMVxuXG5cdFx0YVxuXG5cdHBsdWNrSXRlbTogKGEsIGl0ZW0pIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXG5cdFx0cmVtb3ZlZCA9IDBcblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiB2YWx1ZSBpcyBpdGVtXG5cblx0XHRcdFx0cmVtb3ZlZCsrXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0aWYgcmVtb3ZlZCBpc250IDBcblxuXHRcdFx0XHRhW2luZGV4IC0gcmVtb3ZlZF0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIHJlbW92ZWQgaWYgcmVtb3ZlZCA+IDBcblxuXHRcdGFcblxuXHRwbHVja09uZUl0ZW06IChhLCBpdGVtKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblx0XHRyZWFjaGVkID0gbm9cblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBub3QgcmVhY2hlZFxuXG5cdFx0XHRcdGlmIHZhbHVlIGlzIGl0ZW1cblxuXHRcdFx0XHRcdHJlYWNoZWQgPSB5ZXNcblxuXHRcdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2VcblxuXHRcdFx0XHRhW2luZGV4IC0gMV0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIDEgaWYgcmVhY2hlZFxuXG5cdFx0YVxuXG5cdHBsdWNrQnlDYWxsYmFjazogKGEsIGNiKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblx0XHRyZW1vdmVkID0gMFxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIGNiIHZhbHVlLCBpbmRleFxuXG5cdFx0XHRcdHJlbW92ZWQrK1xuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGlmIHJlbW92ZWQgaXNudCAwXG5cblx0XHRcdFx0YVtpbmRleCAtIHJlbW92ZWRdID0gYVtpbmRleF1cblxuXHRcdGlmIHJlbW92ZWQgPiAwXG5cblx0XHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSByZW1vdmVkXG5cblx0XHRhXG5cblx0cGx1Y2tNdWx0aXBsZTogKGFycmF5LCBpbmRleGVzVG9SZW1vdmUpIC0+XG5cblx0XHRyZXR1cm4gYXJyYXkgaWYgYXJyYXkubGVuZ3RoIDwgMVxuXG5cdFx0cmVtb3ZlZFNvRmFyID0gMFxuXG5cdFx0aW5kZXhlc1RvUmVtb3ZlLnNvcnQoKVxuXG5cdFx0Zm9yIGkgaW4gaW5kZXhlc1RvUmVtb3ZlXG5cblx0XHRcdEBwbHVjayBhcnJheSwgaSAtIHJlbW92ZWRTb0ZhclxuXG5cdFx0XHRyZW1vdmVkU29GYXIrK1xuXG5cdFx0YXJyYXlcblxuXHRpbmplY3RCeUNhbGxiYWNrOiAoYSwgdG9JbmplY3QsIHNob3VsZEluamVjdCkgLT5cblxuXHRcdHZhbEEgPSBudWxsXG5cblx0XHR2YWxCID0gbnVsbFxuXG5cdFx0bGVuID0gYS5sZW5ndGhcblxuXHRcdGlmIGxlbiA8IDFcblxuXHRcdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRcdHJldHVybiBhXG5cblxuXHRcdGZvciB2YWwsIGkgaW4gYVxuXG5cdFx0XHR2YWxBID0gdmFsQlxuXG5cdFx0XHR2YWxCID0gdmFsXG5cblx0XHRcdGlmIHNob3VsZEluamVjdCB2YWxBLCB2YWxCLCB0b0luamVjdFxuXG5cdFx0XHRcdHJldHVybiBhLnNwbGljZSBpLCAwLCB0b0luamVjdFxuXG5cdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRhXG5cblx0aW5qZWN0SW5JbmRleDogKGEsIGluZGV4LCB0b0luamVjdCkgLT5cblxuXHRcdGxlbiA9IGEubGVuZ3RoXG5cblx0XHRpID0gaW5kZXhcblxuXHRcdGlmIGxlbiA8IDFcblxuXHRcdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRcdHJldHVybiBhXG5cblx0XHR0b1B1dCA9IHRvSW5qZWN0XG5cblx0XHR0b1B1dE5leHQgPSBudWxsXG5cblx0XHRgZm9yKDsgaSA8PSBsZW47IGkrKyl7XG5cblx0XHRcdHRvUHV0TmV4dCA9IGFbaV07XG5cblx0XHRcdGFbaV0gPSB0b1B1dDtcblxuXHRcdFx0dG9QdXQgPSB0b1B1dE5leHQ7XG5cblx0XHR9YFxuXG5cdFx0IyBhW2ldID0gdG9QdXRcblxuXHRcdG51bGwiLCJtb2R1bGUuZXhwb3J0cyA9IGNsYXNzaWMgPSB7fVxuXG4jIExpdHRsZSBoZWxwZXIgZm9yIG1peGlucyBmcm9tIENvZmZlZVNjcmlwdCBGQVEsXG4jIGNvdXJ0ZXN5IG9mIFNldGhhdXJ1cyAoaHR0cDovL2dpdGh1Yi5jb20vc2V0aGF1cnVzKVxuY2xhc3NpYy5pbXBsZW1lbnQgPSAobWl4aW5zLi4uLCBjbGFzc1JlZmVyZW5jZSkgLT5cblxuXHRmb3IgbWl4aW4gaW4gbWl4aW5zXG5cblx0XHRjbGFzc1Byb3RvID0gY2xhc3NSZWZlcmVuY2U6OlxuXG5cdFx0Zm9yIG1lbWJlciBvZiBtaXhpbjo6XG5cblx0XHRcdHVubGVzcyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIGNsYXNzUHJvdG8sIG1lbWJlclxuXG5cdFx0XHRcdGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIG1peGluOjosIG1lbWJlclxuXG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBjbGFzc1Byb3RvLCBtZW1iZXIsIGRlc2NcblxuXHRjbGFzc1JlZmVyZW5jZVxuXG5jbGFzc2ljLm1peCA9IChtaXhpbnMuLi4sIGNsYXNzUmVmZXJlbmNlKSAtPlxuXG5cdGNsYXNzUHJvdG8gPSBjbGFzc1JlZmVyZW5jZTo6XG5cblx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnMgPSBbXVxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fYXBwbHlDbG9uZXJzRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBjbG9uZXIgaW4gY2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnNcblxuXHRcdFx0Y2xvbmVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRjbGFzc1JlZmVyZW5jZS5fX21peGluSW5pdGlhbGl6ZXJzID0gW11cblxuXHRjbGFzc1JlZmVyZW5jZS5fX2luaXRNaXhpbnNGb3IgPSAoaW5zdGFuY2UsIGFyZ3MgPSBudWxsKSAtPlxuXG5cdFx0Zm9yIGluaXRpYWxpemVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5Jbml0aWFsaXplcnNcblxuXHRcdFx0aW5pdGlhbGl6ZXIuYXBwbHkgaW5zdGFuY2UsIGFyZ3NcblxuXHRcdHJldHVyblxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVycyA9IFtdXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19hcHBseVF1aXR0ZXJzRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBxdWl0dGVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVyc1xuXG5cdFx0XHRxdWl0dGVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRmb3IgbWl4aW4gaW4gbWl4aW5zXG5cblx0XHR1bmxlc3MgbWl4aW4uY29uc3RydWN0b3IgaW5zdGFuY2VvZiBGdW5jdGlvblxuXG5cdFx0XHR0aHJvdyBFcnJvciBcIk1peGluIHNob3VsZCBiZSBhIGZ1bmN0aW9uXCJcblxuXHRcdGZvciBtZW1iZXIgb2YgbWl4aW46OlxuXG5cdFx0XHRpZiBtZW1iZXIuc3Vic3RyKDAsIDExKSBpcyAnX19pbml0TWl4aW4nXG5cblx0XHRcdFx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkluaXRpYWxpemVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2UgaWYgbWVtYmVyLnN1YnN0cigwLCAxMSkgaXMgJ19fY2xvbmVyRm9yJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzLnB1c2ggbWl4aW46OlttZW1iZXJdXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0ZWxzZSBpZiBtZW1iZXIuc3Vic3RyKDAsIDEyKSBpcyAnX19xdWl0dGVyRm9yJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdHVubGVzcyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIGNsYXNzUHJvdG8sIG1lbWJlclxuXG5cdFx0XHRcdGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIG1peGluOjosIG1lbWJlclxuXG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBjbGFzc1Byb3RvLCBtZW1iZXIsIGRlc2NcblxuXHRjbGFzc1JlZmVyZW5jZSIsImFycmF5ID0gcmVxdWlyZSAnLi9hcnJheSdcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xhc3MgRW1pdHRlclxyXG5cclxuXHRjb25zdHJ1Y3RvcjogLT5cclxuXHJcblx0XHRAX2xpc3RlbmVycyA9IHt9XHJcblxyXG5cdFx0QF9saXN0ZW5lcnNGb3JBbnlFdmVudCA9IFtdXHJcblxyXG5cdFx0QF9kaXNhYmxlZEVtaXR0ZXJzID0ge31cclxuXHJcblx0b246IChldmVudE5hbWUsIGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdFx0QF9saXN0ZW5lcnNbZXZlbnROYW1lXSA9IFtdXHJcblxyXG5cdFx0QF9saXN0ZW5lcnNbZXZlbnROYW1lXS5wdXNoIGxpc3RlbmVyXHJcblxyXG5cdFx0QFxyXG5cclxuXHRvbmNlOiAoZXZlbnROYW1lLCBsaXN0ZW5lcikgLT5cclxuXHJcblx0XHRyYW4gPSBub1xyXG5cclxuXHRcdGNiID0gPT5cclxuXHJcblx0XHRcdHJldHVybiBpZiByYW5cclxuXHJcblx0XHRcdHJhbiA9IHllc1xyXG5cclxuXHRcdFx0ZG8gbGlzdGVuZXJcclxuXHJcblx0XHRcdHNldFRpbWVvdXQgPT5cclxuXHJcblx0XHRcdFx0QHJlbW92ZUV2ZW50IGV2ZW50TmFtZSwgY2JcclxuXHJcblx0XHRcdCwgMFxyXG5cclxuXHRcdEBvbiBldmVudE5hbWUsIGNiXHJcblxyXG5cdFx0QFxyXG5cclxuXHRvbkFueUV2ZW50OiAobGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0QF9saXN0ZW5lcnNGb3JBbnlFdmVudC5wdXNoIGxpc3RlbmVyXHJcblxyXG5cdFx0QFxyXG5cclxuXHRyZW1vdmVFdmVudDogKGV2ZW50TmFtZSwgbGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0cmV0dXJuIEAgdW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0YXJyYXkucGx1Y2tPbmVJdGVtIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0sIGxpc3RlbmVyXHJcblxyXG5cdFx0QFxyXG5cclxuXHRyZW1vdmVMaXN0ZW5lcnM6IChldmVudE5hbWUpIC0+XHJcblxyXG5cdFx0cmV0dXJuIEAgdW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0QF9saXN0ZW5lcnNbZXZlbnROYW1lXS5sZW5ndGggPSAwXHJcblxyXG5cdFx0QFxyXG5cclxuXHRyZW1vdmVBbGxMaXN0ZW5lcnM6IC0+XHJcblxyXG5cdFx0Zm9yIG5hbWUsIGxpc3RlbmVycyBvZiBAX2xpc3RlbmVyc1xyXG5cclxuXHRcdFx0bGlzdGVuZXJzLmxlbmd0aCA9IDBcclxuXHJcblx0XHRAXHJcblxyXG5cdF9lbWl0OiAoZXZlbnROYW1lLCBkYXRhKSAtPlxyXG5cclxuXHRcdGZvciBsaXN0ZW5lciBpbiBAX2xpc3RlbmVyc0ZvckFueUV2ZW50XHJcblxyXG5cdFx0XHRsaXN0ZW5lci5jYWxsIEAsIGRhdGEsIGV2ZW50TmFtZVxyXG5cclxuXHRcdHJldHVybiB1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRmb3IgbGlzdGVuZXIgaW4gQF9saXN0ZW5lcnNbZXZlbnROYW1lXVxyXG5cclxuXHRcdFx0bGlzdGVuZXIuY2FsbCBALCBkYXRhXHJcblxyXG5cdFx0cmV0dXJuXHJcblxyXG5cdCMgdGhpcyBtYWtlcyBzdXJlIHRoYXQgYWxsIHRoZSBjYWxscyB0byB0aGlzIGNsYXNzJ3MgbWV0aG9kICdmbk5hbWUnXHJcblx0IyBhcmUgdGhyb3R0bGVkXHJcblx0X3Rocm90dGxlRW1pdHRlck1ldGhvZDogKGZuTmFtZSwgdGltZSA9IDEwMDApIC0+XHJcblxyXG5cdFx0b3JpZ2luYWxGbiA9IEBbZm5OYW1lXVxyXG5cclxuXHRcdGlmIHR5cGVvZiBvcmlnaW5hbEZuIGlzbnQgJ2Z1bmN0aW9uJ1xyXG5cclxuXHRcdFx0dGhyb3cgRXJyb3IgXCJ0aGlzIGNsYXNzIGRvZXMgbm90IGhhdmUgYSBtZXRob2QgY2FsbGVkICcje2ZuTmFtZX0nXCJcclxuXHJcblx0XHRsYXN0Q2FsbEFyZ3MgPSBudWxsXHJcblx0XHRwZW5kaW5nID0gbm9cclxuXHRcdHRpbWVyID0gbnVsbFxyXG5cclxuXHRcdEBbZm5OYW1lXSA9ID0+XHJcblxyXG5cdFx0XHRsYXN0Q2FsbEFyZ3MgPSBhcmd1bWVudHNcclxuXHJcblx0XHRcdGRvIHBlbmRcclxuXHJcblx0XHRwZW5kID0gPT5cclxuXHJcblx0XHRcdGlmIHBlbmRpbmdcclxuXHJcblx0XHRcdFx0Y2xlYXJUaW1lb3V0IHRpbWVyXHJcblxyXG5cdFx0XHR0aW1lciA9IHNldFRpbWVvdXQgcnVuSXQsIHRpbWVcclxuXHJcblx0XHRcdHBlbmRpbmcgPSB5ZXNcclxuXHJcblx0XHRydW5JdCA9ID0+XHJcblxyXG5cdFx0XHRwZW5kaW5nID0gbm9cclxuXHJcblx0XHRcdG9yaWdpbmFsRm4uYXBwbHkgQCwgbGFzdENhbGxBcmdzXHJcblxyXG5cdF9kaXNhYmxlRW1pdHRlcjogKGZuTmFtZSkgLT5cclxuXHJcblx0XHRpZiBAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXT9cclxuXHJcblx0XHRcdHRocm93IEVycm9yIFwiI3tmbk5hbWV9IGlzIGFscmVhZHkgYSBkaXNhYmxlZCBlbWl0dGVyXCJcclxuXHJcblx0XHRAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXSA9IEBbZm5OYW1lXVxyXG5cclxuXHRcdEBbZm5OYW1lXSA9IC0+XHJcblxyXG5cdF9lbmFibGVFbWl0dGVyOiAoZm5OYW1lKSAtPlxyXG5cclxuXHRcdGZuID0gQF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV1cclxuXHJcblx0XHR1bmxlc3MgZm4/XHJcblxyXG5cdFx0XHR0aHJvdyBFcnJvciBcIiN7Zm5OYW1lfSBpcyBub3QgYSBkaXNhYmxlZCBlbWl0dGVyXCJcclxuXHJcblx0XHRAW2ZuTmFtZV0gPSBmblxyXG5cclxuXHRcdGRlbGV0ZSBAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXSIsIl9jb21tb24gPSByZXF1aXJlICcuL19jb21tb24nXG5cbm1vZHVsZS5leHBvcnRzID0gb2JqZWN0ID1cblxuXHRpc0JhcmVPYmplY3Q6IF9jb21tb24uaXNCYXJlT2JqZWN0LmJpbmQgX2NvbW1vblxuXG5cdCMjI1xuXHRpZiBvYmplY3QgaXMgYW4gaW5zdGFuY2Ugb2YgYSBjbGFzc1xuXHQjIyNcblx0aXNJbnN0YW5jZTogKHdoYXQpIC0+XG5cblx0XHRub3QgQGlzQmFyZU9iamVjdCB3aGF0XG5cblx0IyMjXG5cdEFsaWFzIHRvIF9jb21tb24udHlwZU9mXG5cdCMjI1xuXHR0eXBlT2Y6IF9jb21tb24udHlwZU9mLmJpbmQgX2NvbW1vblxuXG5cdCMjI1xuXHRBbGlhcyB0byBfY29tbW9uLmNsb25lXG5cdCMjI1xuXHRjbG9uZTogX2NvbW1vbi5jbG9uZS5iaW5kIF9jb21tb25cblxuXHQjIyNcblx0RW1wdGllcyBhbiBvYmplY3Qgb2YgaXRzIHByb3BlcnRpZXMuXG5cdCMjI1xuXHRlbXB0eTogKG8pIC0+XG5cblx0XHRmb3IgcHJvcCBvZiBvXG5cblx0XHRcdGRlbGV0ZSBvW3Byb3BdIGlmIG8uaGFzT3duUHJvcGVydHkgcHJvcFxuXG5cdFx0b1xuXG5cdCMjI1xuXHRFbXB0aWVzIGFuIG9iamVjdC4gRG9lc24ndCBjaGVjayBmb3IgaGFzT3duUHJvcGVydHksIHNvIGl0J3MgYSB0aW55XG5cdGJpdCBmYXN0ZXIuIFVzZSBpdCBmb3IgcGxhaW4gb2JqZWN0cy5cblx0IyMjXG5cdGZhc3RFbXB0eTogKG8pIC0+XG5cblx0XHRkZWxldGUgb1twcm9wZXJ0eV0gZm9yIHByb3BlcnR5IG9mIG9cblxuXHRcdG9cblxuXHQjIyNcblx0T3ZlcnJpZGVzIHZhbHVlcyBmb21yIGBuZXdWYWx1ZXNgIG9uIGBiYXNlYCwgYXMgbG9uZyBhcyB0aGV5XG5cdGFscmVhZHkgZXhpc3QgaW4gYmFzZS5cblx0IyMjXG5cdG92ZXJyaWRlT250bzogKGJhc2UsIG5ld1ZhbHVlcykgLT5cblxuXHRcdHJldHVybiBiYXNlIGlmIG5vdCBAaXNCYXJlT2JqZWN0KG5ld1ZhbHVlcykgb3Igbm90IEBpc0JhcmVPYmplY3QoYmFzZSlcblxuXHRcdGZvciBrZXksIG9sZFZhbCBvZiBiYXNlXG5cblx0XHRcdG5ld1ZhbCA9IG5ld1ZhbHVlc1trZXldXG5cblx0XHRcdGNvbnRpbnVlIGlmIG5ld1ZhbCBpcyB1bmRlZmluZWRcblxuXHRcdFx0aWYgdHlwZW9mIG5ld1ZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG5ld1ZhbFxuXG5cdFx0XHRcdGJhc2Vba2V5XSA9IEBjbG9uZSBuZXdWYWxcblxuXHRcdFx0IyBuZXdWYWwgaXMgYSBwbGFpbiBvYmplY3Rcblx0XHRcdGVsc2VcblxuXHRcdFx0XHRpZiB0eXBlb2Ygb2xkVmFsIGlzbnQgJ29iamVjdCcgb3IgQGlzSW5zdGFuY2Ugb2xkVmFsXG5cblx0XHRcdFx0XHRiYXNlW2tleV0gPSBAY2xvbmUgbmV3VmFsXG5cblx0XHRcdFx0ZWxzZVxuXG5cdFx0XHRcdFx0QG92ZXJyaWRlT250byBvbGRWYWwsIG5ld1ZhbFxuXHRcdGJhc2VcblxuXHQjIyNcblx0VGFrZXMgYSBjbG9uZSBvZiAnYmFzZScgYW5kIHJ1bnMgI292ZXJyaWRlT250byBvbiBpdFxuXHQjIyNcblx0b3ZlcnJpZGU6IChiYXNlLCBuZXdWYWx1ZXMpIC0+XG5cblx0XHRAb3ZlcnJpZGVPbnRvIEBjbG9uZShiYXNlKSwgbmV3VmFsdWVzXG5cblx0YXBwZW5kOiAoYmFzZSwgdG9BcHBlbmQpIC0+XG5cblx0XHRAYXBwZW5kT250byBAY2xvbmUoYmFzZSksIHRvQXBwZW5kXG5cblx0IyBEZWVwIGFwcGVuZHMgdmFsdWVzIGZyb20gYHRvQXBwZW5kYCB0byBgYmFzZWBcblx0YXBwZW5kT250bzogKGJhc2UsIHRvQXBwZW5kKSAtPlxuXG5cdFx0cmV0dXJuIGJhc2UgaWYgbm90IEBpc0JhcmVPYmplY3QodG9BcHBlbmQpIG9yIG5vdCBAaXNCYXJlT2JqZWN0KGJhc2UpXG5cblx0XHRmb3Igb3duIGtleSwgbmV3VmFsIG9mIHRvQXBwZW5kXG5cblx0XHRcdGNvbnRpbnVlIHVubGVzcyBuZXdWYWwgaXNudCB1bmRlZmluZWRcblxuXHRcdFx0aWYgdHlwZW9mIG5ld1ZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG5ld1ZhbFxuXG5cdFx0XHRcdGJhc2Vba2V5XSA9IG5ld1ZhbFxuXG5cdFx0XHRlbHNlXG5cblx0XHRcdFx0IyBuZXdWYWwgaXMgYSBiYXJlIG9iamVjdFxuXG5cdFx0XHRcdG9sZFZhbCA9IGJhc2Vba2V5XVxuXG5cdFx0XHRcdGlmIHR5cGVvZiBvbGRWYWwgaXNudCAnb2JqZWN0JyBvciBAaXNJbnN0YW5jZSBvbGRWYWxcblxuXHRcdFx0XHRcdGJhc2Vba2V5XSA9IEBjbG9uZSBuZXdWYWxcblxuXHRcdFx0XHRlbHNlXG5cblx0XHRcdFx0XHRAYXBwZW5kT250byBvbGRWYWwsIG5ld1ZhbFxuXG5cdFx0YmFzZVxuXG5cdCMgR3JvdXBzXG5cdGdyb3VwUHJvcHM6IChvYmosIGdyb3VwcykgLT5cblxuXHRcdGdyb3VwZWQgPSB7fVxuXG5cdFx0Zm9yIG5hbWUsIGRlZnMgb2YgZ3JvdXBzXG5cblx0XHRcdGdyb3VwZWRbbmFtZV0gPSB7fVxuXG5cdFx0Z3JvdXBlZFsncmVzdCddID0ge31cblxuXHRcdGB0b3A6IC8vYFxuXHRcdGZvciBrZXksIHZhbCBvZiBvYmpcblxuXHRcdFx0c2hvdWxkQWRkID0gbm9cblxuXHRcdFx0Zm9yIG5hbWUsIGRlZnMgb2YgZ3JvdXBzXG5cblx0XHRcdFx0dW5sZXNzIEFycmF5LmlzQXJyYXkgZGVmc1xuXG5cdFx0XHRcdFx0ZGVmcyA9IFtkZWZzXVxuXG5cdFx0XHRcdGZvciBkZWYgaW4gZGVmc1xuXG5cdFx0XHRcdFx0aWYgdHlwZW9mIGRlZiBpcyAnc3RyaW5nJ1xuXG5cdFx0XHRcdFx0XHRpZiBrZXkgaXMgZGVmXG5cblx0XHRcdFx0XHRcdFx0c2hvdWxkQWRkID0geWVzXG5cblx0XHRcdFx0XHRlbHNlIGlmIGRlZiBpbnN0YW5jZW9mIFJlZ0V4cFxuXG5cdFx0XHRcdFx0XHRpZiBkZWYudGVzdCBrZXlcblxuXHRcdFx0XHRcdFx0XHRzaG91bGRBZGQgPSB5ZXNcblxuXHRcdFx0XHRcdGVsc2UgaWYgZGVmIGluc3RhbmNlb2YgRnVuY3Rpb25cblxuXHRcdFx0XHRcdFx0aWYgZGVmIGtleVxuXG5cdFx0XHRcdFx0XHRcdHNob3VsZEFkZCA9IHllc1xuXG5cdFx0XHRcdFx0ZWxzZVxuXG5cdFx0XHRcdFx0XHR0aHJvdyBFcnJvciAnR3JvdXAgZGVmaW5pdGlvbnMgbXVzdCBlaXRoZXJcblx0XHRcdFx0XHRcdGJlIHN0cmluZ3MsIHJlZ2V4ZXMsIG9yIGZ1bmN0aW9ucy4nXG5cblx0XHRcdFx0XHRpZiBzaG91bGRBZGRcblxuXHRcdFx0XHRcdFx0Z3JvdXBlZFtuYW1lXVtrZXldID0gdmFsXG5cblx0XHRcdFx0XHRcdGBjb250aW51ZSB0b3BgXG5cblx0XHRcdGdyb3VwZWRbJ3Jlc3QnXVtrZXldID0gdmFsXG5cblx0XHRncm91cGVkIl19 \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/lib/string.js b/node_modules/utila/scripts/js/lib/string.js
new file mode 100644
index 000000000..d49a48ea2
--- /dev/null
+++ b/node_modules/utila/scripts/js/lib/string.js
@@ -0,0 +1,15 @@
+module.exports = {
+ pad: function(n, width, z) {
+ if (z == null) {
+ z = '0';
+ }
+ n = n + '';
+ if (n.length >= width) {
+ return n;
+ } else {
+ return new Array(width - n.length + 1).join(z) + n;
+ }
+ }
+};
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyaW5nLmpzIiwic291cmNlUm9vdCI6Ii4uXFwuLiIsInNvdXJjZXMiOlsiY29mZmVlXFxsaWJcXHN0cmluZy5jb2ZmZWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFJQUEsTUlBTSxDSUFDLE9JQVAsR0lLQztBSUFBLEVJQUEsR0lBQSxFSUFLLFNJQUMsQ0lBRCxFSUFJLEtJQUosRUlBVyxDSUFYLEdJQUE7O01JQVcsSUlBSTtLSUVuQjtBSUFBLElJQUEsQ0lBQSxHSUFJLENJQUEsR0lBSSxFSUFSLENJQUE7QUlFQSxJSUFBLElJQUcsQ0lBQyxDSUFDLE1JQUYsSUlBWSxLSUFmO2FJRUMsRUlGRDtLSUFBLE1JQUE7YUlNSyxJSUFBLEtJQUEsQ0lBTSxLSUFBLEdJQVEsQ0lBQyxDSUFDLE1JQVYsR0lBbUIsQ0lBekIsQ0lBMkIsQ0lBQyxJSUE1QixDSUFpQyxDSUFqQyxDSUFKLEdJQTBDLEVJTjNDO0tJSkk7RUlBQSxDSUFMO0NBTEQsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXJyYXkgPVxuXG5cdCMjI1xuXHRUcmllcyB0byB0dXJuIGFueXRoaW5nIGludG8gYW4gYXJyYXkuXG5cdCMjI1xuXHRmcm9tOiAocikgLT5cblxuXHRcdEFycmF5OjpzbGljZS5jYWxsIHJcblxuXHQjIyNcblx0Q2xvbmUgb2YgYW4gYXJyYXkuIFByb3BlcnRpZXMgd2lsbCBiZSBzaGFsbG93IGNvcGllcy5cblx0IyMjXG5cdHNpbXBsZUNsb25lOiAoYSkgLT5cblxuXHRcdGEuc2xpY2UgMFxuXG5cdHNoYWxsb3dFcXVhbDogKGExLCBhMikgLT5cblxuXHRcdHJldHVybiBubyB1bmxlc3MgQXJyYXkuaXNBcnJheShhMSkgYW5kIEFycmF5LmlzQXJyYXkoYTIpIGFuZCBhMS5sZW5ndGggaXMgYTIubGVuZ3RoXG5cblx0XHRmb3IgdmFsLCBpIGluIGExXG5cblx0XHRcdHJldHVybiBubyB1bmxlc3MgYTJbaV0gaXMgdmFsXG5cblx0XHR5ZXNcblxuXHRwbHVjazogKGEsIGkpIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIGluZGV4ID4gaVxuXG5cdFx0XHRcdGFbaW5kZXggLSAxXSA9IGFbaW5kZXhdXG5cblx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gMVxuXG5cdFx0YVxuXG5cdHBsdWNrSXRlbTogKGEsIGl0ZW0pIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXG5cdFx0cmVtb3ZlZCA9IDBcblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiB2YWx1ZSBpcyBpdGVtXG5cblx0XHRcdFx0cmVtb3ZlZCsrXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0aWYgcmVtb3ZlZCBpc250IDBcblxuXHRcdFx0XHRhW2luZGV4IC0gcmVtb3ZlZF0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIHJlbW92ZWQgaWYgcmVtb3ZlZCA+IDBcblxuXHRcdGFcblxuXHRwbHVja09uZUl0ZW06IChhLCBpdGVtKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblx0XHRyZWFjaGVkID0gbm9cblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBub3QgcmVhY2hlZFxuXG5cdFx0XHRcdGlmIHZhbHVlIGlzIGl0ZW1cblxuXHRcdFx0XHRcdHJlYWNoZWQgPSB5ZXNcblxuXHRcdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2VcblxuXHRcdFx0XHRhW2luZGV4IC0gMV0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIDEgaWYgcmVhY2hlZFxuXG5cdFx0YVxuXG5cdHBsdWNrQnlDYWxsYmFjazogKGEsIGNiKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblx0XHRyZW1vdmVkID0gMFxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIGNiIHZhbHVlLCBpbmRleFxuXG5cdFx0XHRcdHJlbW92ZWQrK1xuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGlmIHJlbW92ZWQgaXNudCAwXG5cblx0XHRcdFx0YVtpbmRleCAtIHJlbW92ZWRdID0gYVtpbmRleF1cblxuXHRcdGlmIHJlbW92ZWQgPiAwXG5cblx0XHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSByZW1vdmVkXG5cblx0XHRhXG5cblx0cGx1Y2tNdWx0aXBsZTogKGFycmF5LCBpbmRleGVzVG9SZW1vdmUpIC0+XG5cblx0XHRyZXR1cm4gYXJyYXkgaWYgYXJyYXkubGVuZ3RoIDwgMVxuXG5cdFx0cmVtb3ZlZFNvRmFyID0gMFxuXG5cdFx0aW5kZXhlc1RvUmVtb3ZlLnNvcnQoKVxuXG5cdFx0Zm9yIGkgaW4gaW5kZXhlc1RvUmVtb3ZlXG5cblx0XHRcdEBwbHVjayBhcnJheSwgaSAtIHJlbW92ZWRTb0ZhclxuXG5cdFx0XHRyZW1vdmVkU29GYXIrK1xuXG5cdFx0YXJyYXlcblxuXHRpbmplY3RCeUNhbGxiYWNrOiAoYSwgdG9JbmplY3QsIHNob3VsZEluamVjdCkgLT5cblxuXHRcdHZhbEEgPSBudWxsXG5cblx0XHR2YWxCID0gbnVsbFxuXG5cdFx0bGVuID0gYS5sZW5ndGhcblxuXHRcdGlmIGxlbiA8IDFcblxuXHRcdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRcdHJldHVybiBhXG5cblxuXHRcdGZvciB2YWwsIGkgaW4gYVxuXG5cdFx0XHR2YWxBID0gdmFsQlxuXG5cdFx0XHR2YWxCID0gdmFsXG5cblx0XHRcdGlmIHNob3VsZEluamVjdCB2YWxBLCB2YWxCLCB0b0luamVjdFxuXG5cdFx0XHRcdHJldHVybiBhLnNwbGljZSBpLCAwLCB0b0luamVjdFxuXG5cdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRhXG5cblx0aW5qZWN0SW5JbmRleDogKGEsIGluZGV4LCB0b0luamVjdCkgLT5cblxuXHRcdGxlbiA9IGEubGVuZ3RoXG5cblx0XHRpID0gaW5kZXhcblxuXHRcdGlmIGxlbiA8IDFcblxuXHRcdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRcdHJldHVybiBhXG5cblx0XHR0b1B1dCA9IHRvSW5qZWN0XG5cblx0XHR0b1B1dE5leHQgPSBudWxsXG5cblx0XHRgZm9yKDsgaSA8PSBsZW47IGkrKyl7XG5cblx0XHRcdHRvUHV0TmV4dCA9IGFbaV07XG5cblx0XHRcdGFbaV0gPSB0b1B1dDtcblxuXHRcdFx0dG9QdXQgPSB0b1B1dE5leHQ7XG5cblx0XHR9YFxuXG5cdFx0IyBhW2ldID0gdG9QdXRcblxuXHRcdG51bGwiLCJtb2R1bGUuZXhwb3J0cyA9IGNsYXNzaWMgPSB7fVxuXG4jIExpdHRsZSBoZWxwZXIgZm9yIG1peGlucyBmcm9tIENvZmZlZVNjcmlwdCBGQVEsXG4jIGNvdXJ0ZXN5IG9mIFNldGhhdXJ1cyAoaHR0cDovL2dpdGh1Yi5jb20vc2V0aGF1cnVzKVxuY2xhc3NpYy5pbXBsZW1lbnQgPSAobWl4aW5zLi4uLCBjbGFzc1JlZmVyZW5jZSkgLT5cblxuXHRmb3IgbWl4aW4gaW4gbWl4aW5zXG5cblx0XHRjbGFzc1Byb3RvID0gY2xhc3NSZWZlcmVuY2U6OlxuXG5cdFx0Zm9yIG1lbWJlciBvZiBtaXhpbjo6XG5cblx0XHRcdHVubGVzcyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIGNsYXNzUHJvdG8sIG1lbWJlclxuXG5cdFx0XHRcdGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIG1peGluOjosIG1lbWJlclxuXG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBjbGFzc1Byb3RvLCBtZW1iZXIsIGRlc2NcblxuXHRjbGFzc1JlZmVyZW5jZVxuXG5jbGFzc2ljLm1peCA9IChtaXhpbnMuLi4sIGNsYXNzUmVmZXJlbmNlKSAtPlxuXG5cdGNsYXNzUHJvdG8gPSBjbGFzc1JlZmVyZW5jZTo6XG5cblx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnMgPSBbXVxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fYXBwbHlDbG9uZXJzRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBjbG9uZXIgaW4gY2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnNcblxuXHRcdFx0Y2xvbmVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRjbGFzc1JlZmVyZW5jZS5fX21peGluSW5pdGlhbGl6ZXJzID0gW11cblxuXHRjbGFzc1JlZmVyZW5jZS5fX2luaXRNaXhpbnNGb3IgPSAoaW5zdGFuY2UsIGFyZ3MgPSBudWxsKSAtPlxuXG5cdFx0Zm9yIGluaXRpYWxpemVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5Jbml0aWFsaXplcnNcblxuXHRcdFx0aW5pdGlhbGl6ZXIuYXBwbHkgaW5zdGFuY2UsIGFyZ3NcblxuXHRcdHJldHVyblxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVycyA9IFtdXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19hcHBseVF1aXR0ZXJzRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBxdWl0dGVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVyc1xuXG5cdFx0XHRxdWl0dGVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRmb3IgbWl4aW4gaW4gbWl4aW5zXG5cblx0XHR1bmxlc3MgbWl4aW4uY29uc3RydWN0b3IgaW5zdGFuY2VvZiBGdW5jdGlvblxuXG5cdFx0XHR0aHJvdyBFcnJvciBcIk1peGluIHNob3VsZCBiZSBhIGZ1bmN0aW9uXCJcblxuXHRcdGZvciBtZW1iZXIgb2YgbWl4aW46OlxuXG5cdFx0XHRpZiBtZW1iZXIuc3Vic3RyKDAsIDExKSBpcyAnX19pbml0TWl4aW4nXG5cblx0XHRcdFx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkluaXRpYWxpemVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2UgaWYgbWVtYmVyLnN1YnN0cigwLCAxMSkgaXMgJ19fY2xvbmVyRm9yJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzLnB1c2ggbWl4aW46OlttZW1iZXJdXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0ZWxzZSBpZiBtZW1iZXIuc3Vic3RyKDAsIDEyKSBpcyAnX19xdWl0dGVyRm9yJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdHVubGVzcyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIGNsYXNzUHJvdG8sIG1lbWJlclxuXG5cdFx0XHRcdGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIG1peGluOjosIG1lbWJlclxuXG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBjbGFzc1Byb3RvLCBtZW1iZXIsIGRlc2NcblxuXHRjbGFzc1JlZmVyZW5jZSIsImFycmF5ID0gcmVxdWlyZSAnLi9hcnJheSdcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xhc3MgRW1pdHRlclxyXG5cclxuXHRjb25zdHJ1Y3RvcjogLT5cclxuXHJcblx0XHRAX2xpc3RlbmVycyA9IHt9XHJcblxyXG5cdFx0QF9saXN0ZW5lcnNGb3JBbnlFdmVudCA9IFtdXHJcblxyXG5cdFx0QF9kaXNhYmxlZEVtaXR0ZXJzID0ge31cclxuXHJcblx0b246IChldmVudE5hbWUsIGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdFx0QF9saXN0ZW5lcnNbZXZlbnROYW1lXSA9IFtdXHJcblxyXG5cdFx0QF9saXN0ZW5lcnNbZXZlbnROYW1lXS5wdXNoIGxpc3RlbmVyXHJcblxyXG5cdFx0QFxyXG5cclxuXHRvbmNlOiAoZXZlbnROYW1lLCBsaXN0ZW5lcikgLT5cclxuXHJcblx0XHRyYW4gPSBub1xyXG5cclxuXHRcdGNiID0gPT5cclxuXHJcblx0XHRcdHJldHVybiBpZiByYW5cclxuXHJcblx0XHRcdHJhbiA9IHllc1xyXG5cclxuXHRcdFx0ZG8gbGlzdGVuZXJcclxuXHJcblx0XHRcdHNldFRpbWVvdXQgPT5cclxuXHJcblx0XHRcdFx0QHJlbW92ZUV2ZW50IGV2ZW50TmFtZSwgY2JcclxuXHJcblx0XHRcdCwgMFxyXG5cclxuXHRcdEBvbiBldmVudE5hbWUsIGNiXHJcblxyXG5cdFx0QFxyXG5cclxuXHRvbkFueUV2ZW50OiAobGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0QF9saXN0ZW5lcnNGb3JBbnlFdmVudC5wdXNoIGxpc3RlbmVyXHJcblxyXG5cdFx0QFxyXG5cclxuXHRyZW1vdmVFdmVudDogKGV2ZW50TmFtZSwgbGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0cmV0dXJuIEAgdW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0YXJyYXkucGx1Y2tPbmVJdGVtIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0sIGxpc3RlbmVyXHJcblxyXG5cdFx0QFxyXG5cclxuXHRyZW1vdmVMaXN0ZW5lcnM6IChldmVudE5hbWUpIC0+XHJcblxyXG5cdFx0cmV0dXJuIEAgdW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0QF9saXN0ZW5lcnNbZXZlbnROYW1lXS5sZW5ndGggPSAwXHJcblxyXG5cdFx0QFxyXG5cclxuXHRyZW1vdmVBbGxMaXN0ZW5lcnM6IC0+XHJcblxyXG5cdFx0Zm9yIG5hbWUsIGxpc3RlbmVycyBvZiBAX2xpc3RlbmVyc1xyXG5cclxuXHRcdFx0bGlzdGVuZXJzLmxlbmd0aCA9IDBcclxuXHJcblx0XHRAXHJcblxyXG5cdF9lbWl0OiAoZXZlbnROYW1lLCBkYXRhKSAtPlxyXG5cclxuXHRcdGZvciBsaXN0ZW5lciBpbiBAX2xpc3RlbmVyc0ZvckFueUV2ZW50XHJcblxyXG5cdFx0XHRsaXN0ZW5lci5jYWxsIEAsIGRhdGEsIGV2ZW50TmFtZVxyXG5cclxuXHRcdHJldHVybiB1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRmb3IgbGlzdGVuZXIgaW4gQF9saXN0ZW5lcnNbZXZlbnROYW1lXVxyXG5cclxuXHRcdFx0bGlzdGVuZXIuY2FsbCBALCBkYXRhXHJcblxyXG5cdFx0cmV0dXJuXHJcblxyXG5cdCMgdGhpcyBtYWtlcyBzdXJlIHRoYXQgYWxsIHRoZSBjYWxscyB0byB0aGlzIGNsYXNzJ3MgbWV0aG9kICdmbk5hbWUnXHJcblx0IyBhcmUgdGhyb3R0bGVkXHJcblx0X3Rocm90dGxlRW1pdHRlck1ldGhvZDogKGZuTmFtZSwgdGltZSA9IDEwMDApIC0+XHJcblxyXG5cdFx0b3JpZ2luYWxGbiA9IEBbZm5OYW1lXVxyXG5cclxuXHRcdGlmIHR5cGVvZiBvcmlnaW5hbEZuIGlzbnQgJ2Z1bmN0aW9uJ1xyXG5cclxuXHRcdFx0dGhyb3cgRXJyb3IgXCJ0aGlzIGNsYXNzIGRvZXMgbm90IGhhdmUgYSBtZXRob2QgY2FsbGVkICcje2ZuTmFtZX0nXCJcclxuXHJcblx0XHRsYXN0Q2FsbEFyZ3MgPSBudWxsXHJcblx0XHRwZW5kaW5nID0gbm9cclxuXHRcdHRpbWVyID0gbnVsbFxyXG5cclxuXHRcdEBbZm5OYW1lXSA9ID0+XHJcblxyXG5cdFx0XHRsYXN0Q2FsbEFyZ3MgPSBhcmd1bWVudHNcclxuXHJcblx0XHRcdGRvIHBlbmRcclxuXHJcblx0XHRwZW5kID0gPT5cclxuXHJcblx0XHRcdGlmIHBlbmRpbmdcclxuXHJcblx0XHRcdFx0Y2xlYXJUaW1lb3V0IHRpbWVyXHJcblxyXG5cdFx0XHR0aW1lciA9IHNldFRpbWVvdXQgcnVuSXQsIHRpbWVcclxuXHJcblx0XHRcdHBlbmRpbmcgPSB5ZXNcclxuXHJcblx0XHRydW5JdCA9ID0+XHJcblxyXG5cdFx0XHRwZW5kaW5nID0gbm9cclxuXHJcblx0XHRcdG9yaWdpbmFsRm4uYXBwbHkgQCwgbGFzdENhbGxBcmdzXHJcblxyXG5cdF9kaXNhYmxlRW1pdHRlcjogKGZuTmFtZSkgLT5cclxuXHJcblx0XHRpZiBAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXT9cclxuXHJcblx0XHRcdHRocm93IEVycm9yIFwiI3tmbk5hbWV9IGlzIGFscmVhZHkgYSBkaXNhYmxlZCBlbWl0dGVyXCJcclxuXHJcblx0XHRAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXSA9IEBbZm5OYW1lXVxyXG5cclxuXHRcdEBbZm5OYW1lXSA9IC0+XHJcblxyXG5cdF9lbmFibGVFbWl0dGVyOiAoZm5OYW1lKSAtPlxyXG5cclxuXHRcdGZuID0gQF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV1cclxuXHJcblx0XHR1bmxlc3MgZm4/XHJcblxyXG5cdFx0XHR0aHJvdyBFcnJvciBcIiN7Zm5OYW1lfSBpcyBub3QgYSBkaXNhYmxlZCBlbWl0dGVyXCJcclxuXHJcblx0XHRAW2ZuTmFtZV0gPSBmblxyXG5cclxuXHRcdGRlbGV0ZSBAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXSIsIl9jb21tb24gPSByZXF1aXJlICcuL19jb21tb24nXG5cbm1vZHVsZS5leHBvcnRzID0gb2JqZWN0ID1cblxuXHRpc0JhcmVPYmplY3Q6IF9jb21tb24uaXNCYXJlT2JqZWN0LmJpbmQgX2NvbW1vblxuXG5cdCMjI1xuXHRpZiBvYmplY3QgaXMgYW4gaW5zdGFuY2Ugb2YgYSBjbGFzc1xuXHQjIyNcblx0aXNJbnN0YW5jZTogKHdoYXQpIC0+XG5cblx0XHRub3QgQGlzQmFyZU9iamVjdCB3aGF0XG5cblx0IyMjXG5cdEFsaWFzIHRvIF9jb21tb24udHlwZU9mXG5cdCMjI1xuXHR0eXBlT2Y6IF9jb21tb24udHlwZU9mLmJpbmQgX2NvbW1vblxuXG5cdCMjI1xuXHRBbGlhcyB0byBfY29tbW9uLmNsb25lXG5cdCMjI1xuXHRjbG9uZTogX2NvbW1vbi5jbG9uZS5iaW5kIF9jb21tb25cblxuXHQjIyNcblx0RW1wdGllcyBhbiBvYmplY3Qgb2YgaXRzIHByb3BlcnRpZXMuXG5cdCMjI1xuXHRlbXB0eTogKG8pIC0+XG5cblx0XHRmb3IgcHJvcCBvZiBvXG5cblx0XHRcdGRlbGV0ZSBvW3Byb3BdIGlmIG8uaGFzT3duUHJvcGVydHkgcHJvcFxuXG5cdFx0b1xuXG5cdCMjI1xuXHRFbXB0aWVzIGFuIG9iamVjdC4gRG9lc24ndCBjaGVjayBmb3IgaGFzT3duUHJvcGVydHksIHNvIGl0J3MgYSB0aW55XG5cdGJpdCBmYXN0ZXIuIFVzZSBpdCBmb3IgcGxhaW4gb2JqZWN0cy5cblx0IyMjXG5cdGZhc3RFbXB0eTogKG8pIC0+XG5cblx0XHRkZWxldGUgb1twcm9wZXJ0eV0gZm9yIHByb3BlcnR5IG9mIG9cblxuXHRcdG9cblxuXHQjIyNcblx0T3ZlcnJpZGVzIHZhbHVlcyBmb21yIGBuZXdWYWx1ZXNgIG9uIGBiYXNlYCwgYXMgbG9uZyBhcyB0aGV5XG5cdGFscmVhZHkgZXhpc3QgaW4gYmFzZS5cblx0IyMjXG5cdG92ZXJyaWRlT250bzogKGJhc2UsIG5ld1ZhbHVlcykgLT5cblxuXHRcdHJldHVybiBiYXNlIGlmIG5vdCBAaXNCYXJlT2JqZWN0KG5ld1ZhbHVlcykgb3Igbm90IEBpc0JhcmVPYmplY3QoYmFzZSlcblxuXHRcdGZvciBrZXksIG9sZFZhbCBvZiBiYXNlXG5cblx0XHRcdG5ld1ZhbCA9IG5ld1ZhbHVlc1trZXldXG5cblx0XHRcdGNvbnRpbnVlIGlmIG5ld1ZhbCBpcyB1bmRlZmluZWRcblxuXHRcdFx0aWYgdHlwZW9mIG5ld1ZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG5ld1ZhbFxuXG5cdFx0XHRcdGJhc2Vba2V5XSA9IEBjbG9uZSBuZXdWYWxcblxuXHRcdFx0IyBuZXdWYWwgaXMgYSBwbGFpbiBvYmplY3Rcblx0XHRcdGVsc2VcblxuXHRcdFx0XHRpZiB0eXBlb2Ygb2xkVmFsIGlzbnQgJ29iamVjdCcgb3IgQGlzSW5zdGFuY2Ugb2xkVmFsXG5cblx0XHRcdFx0XHRiYXNlW2tleV0gPSBAY2xvbmUgbmV3VmFsXG5cblx0XHRcdFx0ZWxzZVxuXG5cdFx0XHRcdFx0QG92ZXJyaWRlT250byBvbGRWYWwsIG5ld1ZhbFxuXHRcdGJhc2VcblxuXHQjIyNcblx0VGFrZXMgYSBjbG9uZSBvZiAnYmFzZScgYW5kIHJ1bnMgI292ZXJyaWRlT250byBvbiBpdFxuXHQjIyNcblx0b3ZlcnJpZGU6IChiYXNlLCBuZXdWYWx1ZXMpIC0+XG5cblx0XHRAb3ZlcnJpZGVPbnRvIEBjbG9uZShiYXNlKSwgbmV3VmFsdWVzXG5cblx0YXBwZW5kOiAoYmFzZSwgdG9BcHBlbmQpIC0+XG5cblx0XHRAYXBwZW5kT250byBAY2xvbmUoYmFzZSksIHRvQXBwZW5kXG5cblx0IyBEZWVwIGFwcGVuZHMgdmFsdWVzIGZyb20gYHRvQXBwZW5kYCB0byBgYmFzZWBcblx0YXBwZW5kT250bzogKGJhc2UsIHRvQXBwZW5kKSAtPlxuXG5cdFx0cmV0dXJuIGJhc2UgaWYgbm90IEBpc0JhcmVPYmplY3QodG9BcHBlbmQpIG9yIG5vdCBAaXNCYXJlT2JqZWN0KGJhc2UpXG5cblx0XHRmb3Igb3duIGtleSwgbmV3VmFsIG9mIHRvQXBwZW5kXG5cblx0XHRcdGNvbnRpbnVlIHVubGVzcyBuZXdWYWwgaXNudCB1bmRlZmluZWRcblxuXHRcdFx0aWYgdHlwZW9mIG5ld1ZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG5ld1ZhbFxuXG5cdFx0XHRcdGJhc2Vba2V5XSA9IG5ld1ZhbFxuXG5cdFx0XHRlbHNlXG5cblx0XHRcdFx0IyBuZXdWYWwgaXMgYSBiYXJlIG9iamVjdFxuXG5cdFx0XHRcdG9sZFZhbCA9IGJhc2Vba2V5XVxuXG5cdFx0XHRcdGlmIHR5cGVvZiBvbGRWYWwgaXNudCAnb2JqZWN0JyBvciBAaXNJbnN0YW5jZSBvbGRWYWxcblxuXHRcdFx0XHRcdGJhc2Vba2V5XSA9IEBjbG9uZSBuZXdWYWxcblxuXHRcdFx0XHRlbHNlXG5cblx0XHRcdFx0XHRAYXBwZW5kT250byBvbGRWYWwsIG5ld1ZhbFxuXG5cdFx0YmFzZVxuXG5cdCMgR3JvdXBzXG5cdGdyb3VwUHJvcHM6IChvYmosIGdyb3VwcykgLT5cblxuXHRcdGdyb3VwZWQgPSB7fVxuXG5cdFx0Zm9yIG5hbWUsIGRlZnMgb2YgZ3JvdXBzXG5cblx0XHRcdGdyb3VwZWRbbmFtZV0gPSB7fVxuXG5cdFx0Z3JvdXBlZFsncmVzdCddID0ge31cblxuXHRcdGB0b3A6IC8vYFxuXHRcdGZvciBrZXksIHZhbCBvZiBvYmpcblxuXHRcdFx0c2hvdWxkQWRkID0gbm9cblxuXHRcdFx0Zm9yIG5hbWUsIGRlZnMgb2YgZ3JvdXBzXG5cblx0XHRcdFx0dW5sZXNzIEFycmF5LmlzQXJyYXkgZGVmc1xuXG5cdFx0XHRcdFx0ZGVmcyA9IFtkZWZzXVxuXG5cdFx0XHRcdGZvciBkZWYgaW4gZGVmc1xuXG5cdFx0XHRcdFx0aWYgdHlwZW9mIGRlZiBpcyAnc3RyaW5nJ1xuXG5cdFx0XHRcdFx0XHRpZiBrZXkgaXMgZGVmXG5cblx0XHRcdFx0XHRcdFx0c2hvdWxkQWRkID0geWVzXG5cblx0XHRcdFx0XHRlbHNlIGlmIGRlZiBpbnN0YW5jZW9mIFJlZ0V4cFxuXG5cdFx0XHRcdFx0XHRpZiBkZWYudGVzdCBrZXlcblxuXHRcdFx0XHRcdFx0XHRzaG91bGRBZGQgPSB5ZXNcblxuXHRcdFx0XHRcdGVsc2UgaWYgZGVmIGluc3RhbmNlb2YgRnVuY3Rpb25cblxuXHRcdFx0XHRcdFx0aWYgZGVmIGtleVxuXG5cdFx0XHRcdFx0XHRcdHNob3VsZEFkZCA9IHllc1xuXG5cdFx0XHRcdFx0ZWxzZVxuXG5cdFx0XHRcdFx0XHR0aHJvdyBFcnJvciAnR3JvdXAgZGVmaW5pdGlvbnMgbXVzdCBlaXRoZXJcblx0XHRcdFx0XHRcdGJlIHN0cmluZ3MsIHJlZ2V4ZXMsIG9yIGZ1bmN0aW9ucy4nXG5cblx0XHRcdFx0XHRpZiBzaG91bGRBZGRcblxuXHRcdFx0XHRcdFx0Z3JvdXBlZFtuYW1lXVtrZXldID0gdmFsXG5cblx0XHRcdFx0XHRcdGBjb250aW51ZSB0b3BgXG5cblx0XHRcdGdyb3VwZWRbJ3Jlc3QnXVtrZXldID0gdmFsXG5cblx0XHRncm91cGVkIiwibW9kdWxlLmV4cG9ydHMgPVxyXG5cclxuXHQjIHBhZHMgYSBudW1iZXIgd2l0aCBsZWFkaW5nIHplcm9lc1xyXG5cdCNcclxuXHQjIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzEwMDczNzg4LzYwNzk5N1xyXG5cdHBhZDogKG4sIHdpZHRoLCB6ID0gJzAnKSAtPlxyXG5cclxuXHRcdG4gPSBuICsgJydcclxuXHJcblx0XHRpZiBuLmxlbmd0aCA+PSB3aWR0aFxyXG5cclxuXHRcdFx0blxyXG5cclxuXHRcdGVsc2VcclxuXHJcblx0XHRcdG5ldyBBcnJheSh3aWR0aCAtIG4ubGVuZ3RoICsgMSkuam9pbih6KSArIG4iXX0= \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/lib/utila.js b/node_modules/utila/scripts/js/lib/utila.js
new file mode 100644
index 000000000..c81012b0a
--- /dev/null
+++ b/node_modules/utila/scripts/js/lib/utila.js
@@ -0,0 +1,11 @@
+var utila;
+
+module.exports = utila = {
+ array: require('./array'),
+ classic: require('./classic'),
+ object: require('./object'),
+ string: require('./string'),
+ Emitter: require('./Emitter')
+};
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbGEuanMiLCJzb3VyY2VSb290IjoiLi5cXC4uIiwic291cmNlcyI6WyJjb2ZmZWVcXGxpYlxcdXRpbGEuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLElBQUEsS0FBQTs7QUtBQSxNS0FNLENLQUMsT0tBUCxHS0FpQixLS0FBLEdLRWhCO0FLQUEsRUtBQSxLS0FBLEVLQU8sT0tBQSxDS0FRLFNLQVIsQ0tBUDtBS0FBLEVLQ0EsT0tBQSxFS0FTLE9LQUEsQ0tBUSxXS0FSLENLRFQ7QUtBQSxFS0VBLE1LQUEsRUtBUSxPS0FBLENLQVEsVUtBUixDS0ZSO0FLQUEsRUtHQSxNS0FBLEVLQVEsT0tBQSxDS0FRLFVLQVIsQ0tIUjtBS0FBLEVLSUEsT0tBQSxFS0FTLE9LQUEsQ0tBUSxXS0FSLENLSlQ7Q0FGRCxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHMgPSBhcnJheSA9XG5cblx0IyMjXG5cdFRyaWVzIHRvIHR1cm4gYW55dGhpbmcgaW50byBhbiBhcnJheS5cblx0IyMjXG5cdGZyb206IChyKSAtPlxuXG5cdFx0QXJyYXk6OnNsaWNlLmNhbGwgclxuXG5cdCMjI1xuXHRDbG9uZSBvZiBhbiBhcnJheS4gUHJvcGVydGllcyB3aWxsIGJlIHNoYWxsb3cgY29waWVzLlxuXHQjIyNcblx0c2ltcGxlQ2xvbmU6IChhKSAtPlxuXG5cdFx0YS5zbGljZSAwXG5cblx0c2hhbGxvd0VxdWFsOiAoYTEsIGEyKSAtPlxuXG5cdFx0cmV0dXJuIG5vIHVubGVzcyBBcnJheS5pc0FycmF5KGExKSBhbmQgQXJyYXkuaXNBcnJheShhMikgYW5kIGExLmxlbmd0aCBpcyBhMi5sZW5ndGhcblxuXHRcdGZvciB2YWwsIGkgaW4gYTFcblxuXHRcdFx0cmV0dXJuIG5vIHVubGVzcyBhMltpXSBpcyB2YWxcblxuXHRcdHllc1xuXG5cdHBsdWNrOiAoYSwgaSkgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgaW5kZXggPiBpXG5cblx0XHRcdFx0YVtpbmRleCAtIDFdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSAxXG5cblx0XHRhXG5cblx0cGx1Y2tJdGVtOiAoYSwgaXRlbSkgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cblx0XHRyZW1vdmVkID0gMFxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIHZhbHVlIGlzIGl0ZW1cblxuXHRcdFx0XHRyZW1vdmVkKytcblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRpZiByZW1vdmVkIGlzbnQgMFxuXG5cdFx0XHRcdGFbaW5kZXggLSByZW1vdmVkXSA9IGFbaW5kZXhdXG5cblx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gcmVtb3ZlZCBpZiByZW1vdmVkID4gMFxuXG5cdFx0YVxuXG5cdHBsdWNrT25lSXRlbTogKGEsIGl0ZW0pIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXHRcdHJlYWNoZWQgPSBub1xuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIG5vdCByZWFjaGVkXG5cblx0XHRcdFx0aWYgdmFsdWUgaXMgaXRlbVxuXG5cdFx0XHRcdFx0cmVhY2hlZCA9IHllc1xuXG5cdFx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0ZWxzZVxuXG5cdFx0XHRcdGFbaW5kZXggLSAxXSA9IGFbaW5kZXhdXG5cblx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gMSBpZiByZWFjaGVkXG5cblx0XHRhXG5cblx0cGx1Y2tCeUNhbGxiYWNrOiAoYSwgY2IpIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXHRcdHJlbW92ZWQgPSAwXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgY2IgdmFsdWUsIGluZGV4XG5cblx0XHRcdFx0cmVtb3ZlZCsrXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0aWYgcmVtb3ZlZCBpc250IDBcblxuXHRcdFx0XHRhW2luZGV4IC0gcmVtb3ZlZF0gPSBhW2luZGV4XVxuXG5cdFx0aWYgcmVtb3ZlZCA+IDBcblxuXHRcdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIHJlbW92ZWRcblxuXHRcdGFcblxuXHRwbHVja011bHRpcGxlOiAoYXJyYXksIGluZGV4ZXNUb1JlbW92ZSkgLT5cblxuXHRcdHJldHVybiBhcnJheSBpZiBhcnJheS5sZW5ndGggPCAxXG5cblx0XHRyZW1vdmVkU29GYXIgPSAwXG5cblx0XHRpbmRleGVzVG9SZW1vdmUuc29ydCgpXG5cblx0XHRmb3IgaSBpbiBpbmRleGVzVG9SZW1vdmVcblxuXHRcdFx0QHBsdWNrIGFycmF5LCBpIC0gcmVtb3ZlZFNvRmFyXG5cblx0XHRcdHJlbW92ZWRTb0ZhcisrXG5cblx0XHRhcnJheVxuXG5cdGluamVjdEJ5Q2FsbGJhY2s6IChhLCB0b0luamVjdCwgc2hvdWxkSW5qZWN0KSAtPlxuXG5cdFx0dmFsQSA9IG51bGxcblxuXHRcdHZhbEIgPSBudWxsXG5cblx0XHRsZW4gPSBhLmxlbmd0aFxuXG5cdFx0aWYgbGVuIDwgMVxuXG5cdFx0XHRhLnB1c2ggdG9JbmplY3RcblxuXHRcdFx0cmV0dXJuIGFcblxuXG5cdFx0Zm9yIHZhbCwgaSBpbiBhXG5cblx0XHRcdHZhbEEgPSB2YWxCXG5cblx0XHRcdHZhbEIgPSB2YWxcblxuXHRcdFx0aWYgc2hvdWxkSW5qZWN0IHZhbEEsIHZhbEIsIHRvSW5qZWN0XG5cblx0XHRcdFx0cmV0dXJuIGEuc3BsaWNlIGksIDAsIHRvSW5qZWN0XG5cblx0XHRhLnB1c2ggdG9JbmplY3RcblxuXHRcdGFcblxuXHRpbmplY3RJbkluZGV4OiAoYSwgaW5kZXgsIHRvSW5qZWN0KSAtPlxuXG5cdFx0bGVuID0gYS5sZW5ndGhcblxuXHRcdGkgPSBpbmRleFxuXG5cdFx0aWYgbGVuIDwgMVxuXG5cdFx0XHRhLnB1c2ggdG9JbmplY3RcblxuXHRcdFx0cmV0dXJuIGFcblxuXHRcdHRvUHV0ID0gdG9JbmplY3RcblxuXHRcdHRvUHV0TmV4dCA9IG51bGxcblxuXHRcdGBmb3IoOyBpIDw9IGxlbjsgaSsrKXtcblxuXHRcdFx0dG9QdXROZXh0ID0gYVtpXTtcblxuXHRcdFx0YVtpXSA9IHRvUHV0O1xuXG5cdFx0XHR0b1B1dCA9IHRvUHV0TmV4dDtcblxuXHRcdH1gXG5cblx0XHQjIGFbaV0gPSB0b1B1dFxuXG5cdFx0bnVsbCIsIm1vZHVsZS5leHBvcnRzID0gY2xhc3NpYyA9IHt9XG5cbiMgTGl0dGxlIGhlbHBlciBmb3IgbWl4aW5zIGZyb20gQ29mZmVlU2NyaXB0IEZBUSxcbiMgY291cnRlc3kgb2YgU2V0aGF1cnVzIChodHRwOi8vZ2l0aHViLmNvbS9zZXRoYXVydXMpXG5jbGFzc2ljLmltcGxlbWVudCA9IChtaXhpbnMuLi4sIGNsYXNzUmVmZXJlbmNlKSAtPlxuXG5cdGZvciBtaXhpbiBpbiBtaXhpbnNcblxuXHRcdGNsYXNzUHJvdG8gPSBjbGFzc1JlZmVyZW5jZTo6XG5cblx0XHRmb3IgbWVtYmVyIG9mIG1peGluOjpcblxuXHRcdFx0dW5sZXNzIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgY2xhc3NQcm90bywgbWVtYmVyXG5cblx0XHRcdFx0ZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgbWl4aW46OiwgbWVtYmVyXG5cblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5IGNsYXNzUHJvdG8sIG1lbWJlciwgZGVzY1xuXG5cdGNsYXNzUmVmZXJlbmNlXG5cbmNsYXNzaWMubWl4ID0gKG1peGlucy4uLiwgY2xhc3NSZWZlcmVuY2UpIC0+XG5cblx0Y2xhc3NQcm90byA9IGNsYXNzUmVmZXJlbmNlOjpcblxuXHRjbGFzc1JlZmVyZW5jZS5fX21peGluQ2xvbmVycyA9IFtdXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19hcHBseUNsb25lcnNGb3IgPSAoaW5zdGFuY2UsIGFyZ3MgPSBudWxsKSAtPlxuXG5cdFx0Zm9yIGNsb25lciBpbiBjbGFzc1JlZmVyZW5jZS5fX21peGluQ2xvbmVyc1xuXG5cdFx0XHRjbG9uZXIuYXBwbHkgaW5zdGFuY2UsIGFyZ3NcblxuXHRcdHJldHVyblxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5Jbml0aWFsaXplcnMgPSBbXVxuXG5cdGNsYXNzUmVmZXJlbmNlLl9faW5pdE1peGluc0ZvciA9IChpbnN0YW5jZSwgYXJncyA9IG51bGwpIC0+XG5cblx0XHRmb3IgaW5pdGlhbGl6ZXIgaW4gY2xhc3NSZWZlcmVuY2UuX19taXhpbkluaXRpYWxpemVyc1xuXG5cdFx0XHRpbml0aWFsaXplci5hcHBseSBpbnN0YW5jZSwgYXJnc1xuXG5cdFx0cmV0dXJuXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19taXhpblF1aXR0ZXJzID0gW11cblxuXHRjbGFzc1JlZmVyZW5jZS5fX2FwcGx5UXVpdHRlcnNGb3IgPSAoaW5zdGFuY2UsIGFyZ3MgPSBudWxsKSAtPlxuXG5cdFx0Zm9yIHF1aXR0ZXIgaW4gY2xhc3NSZWZlcmVuY2UuX19taXhpblF1aXR0ZXJzXG5cblx0XHRcdHF1aXR0ZXIuYXBwbHkgaW5zdGFuY2UsIGFyZ3NcblxuXHRcdHJldHVyblxuXG5cdGZvciBtaXhpbiBpbiBtaXhpbnNcblxuXHRcdHVubGVzcyBtaXhpbi5jb25zdHJ1Y3RvciBpbnN0YW5jZW9mIEZ1bmN0aW9uXG5cblx0XHRcdHRocm93IEVycm9yIFwiTWl4aW4gc2hvdWxkIGJlIGEgZnVuY3Rpb25cIlxuXG5cdFx0Zm9yIG1lbWJlciBvZiBtaXhpbjo6XG5cblx0XHRcdGlmIG1lbWJlci5zdWJzdHIoMCwgMTEpIGlzICdfX2luaXRNaXhpbidcblxuXHRcdFx0XHRjbGFzc1JlZmVyZW5jZS5fX21peGluSW5pdGlhbGl6ZXJzLnB1c2ggbWl4aW46OlttZW1iZXJdXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0ZWxzZSBpZiBtZW1iZXIuc3Vic3RyKDAsIDExKSBpcyAnX19jbG9uZXJGb3InXG5cblx0XHRcdFx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnMucHVzaCBtaXhpbjo6W21lbWJlcl1cblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRlbHNlIGlmIG1lbWJlci5zdWJzdHIoMCwgMTIpIGlzICdfX3F1aXR0ZXJGb3InXG5cblx0XHRcdFx0Y2xhc3NSZWZlcmVuY2UuX19taXhpblF1aXR0ZXJzLnB1c2ggbWl4aW46OlttZW1iZXJdXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0dW5sZXNzIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgY2xhc3NQcm90bywgbWVtYmVyXG5cblx0XHRcdFx0ZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgbWl4aW46OiwgbWVtYmVyXG5cblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5IGNsYXNzUHJvdG8sIG1lbWJlciwgZGVzY1xuXG5cdGNsYXNzUmVmZXJlbmNlIiwiYXJyYXkgPSByZXF1aXJlICcuL2FycmF5J1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjbGFzcyBFbWl0dGVyXHJcblxyXG5cdGNvbnN0cnVjdG9yOiAtPlxyXG5cclxuXHRcdEBfbGlzdGVuZXJzID0ge31cclxuXHJcblx0XHRAX2xpc3RlbmVyc0ZvckFueUV2ZW50ID0gW11cclxuXHJcblx0XHRAX2Rpc2FibGVkRW1pdHRlcnMgPSB7fVxyXG5cclxuXHRvbjogKGV2ZW50TmFtZSwgbGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0dW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0XHRAX2xpc3RlbmVyc1tldmVudE5hbWVdID0gW11cclxuXHJcblx0XHRAX2xpc3RlbmVyc1tldmVudE5hbWVdLnB1c2ggbGlzdGVuZXJcclxuXHJcblx0XHRAXHJcblxyXG5cdG9uY2U6IChldmVudE5hbWUsIGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdHJhbiA9IG5vXHJcblxyXG5cdFx0Y2IgPSA9PlxyXG5cclxuXHRcdFx0cmV0dXJuIGlmIHJhblxyXG5cclxuXHRcdFx0cmFuID0geWVzXHJcblxyXG5cdFx0XHRkbyBsaXN0ZW5lclxyXG5cclxuXHRcdFx0c2V0VGltZW91dCA9PlxyXG5cclxuXHRcdFx0XHRAcmVtb3ZlRXZlbnQgZXZlbnROYW1lLCBjYlxyXG5cclxuXHRcdFx0LCAwXHJcblxyXG5cdFx0QG9uIGV2ZW50TmFtZSwgY2JcclxuXHJcblx0XHRAXHJcblxyXG5cdG9uQW55RXZlbnQ6IChsaXN0ZW5lcikgLT5cclxuXHJcblx0XHRAX2xpc3RlbmVyc0ZvckFueUV2ZW50LnB1c2ggbGlzdGVuZXJcclxuXHJcblx0XHRAXHJcblxyXG5cdHJlbW92ZUV2ZW50OiAoZXZlbnROYW1lLCBsaXN0ZW5lcikgLT5cclxuXHJcblx0XHRyZXR1cm4gQCB1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRhcnJheS5wbHVja09uZUl0ZW0gQF9saXN0ZW5lcnNbZXZlbnROYW1lXSwgbGlzdGVuZXJcclxuXHJcblx0XHRAXHJcblxyXG5cdHJlbW92ZUxpc3RlbmVyczogKGV2ZW50TmFtZSkgLT5cclxuXHJcblx0XHRyZXR1cm4gQCB1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRAX2xpc3RlbmVyc1tldmVudE5hbWVdLmxlbmd0aCA9IDBcclxuXHJcblx0XHRAXHJcblxyXG5cdHJlbW92ZUFsbExpc3RlbmVyczogLT5cclxuXHJcblx0XHRmb3IgbmFtZSwgbGlzdGVuZXJzIG9mIEBfbGlzdGVuZXJzXHJcblxyXG5cdFx0XHRsaXN0ZW5lcnMubGVuZ3RoID0gMFxyXG5cclxuXHRcdEBcclxuXHJcblx0X2VtaXQ6IChldmVudE5hbWUsIGRhdGEpIC0+XHJcblxyXG5cdFx0Zm9yIGxpc3RlbmVyIGluIEBfbGlzdGVuZXJzRm9yQW55RXZlbnRcclxuXHJcblx0XHRcdGxpc3RlbmVyLmNhbGwgQCwgZGF0YSwgZXZlbnROYW1lXHJcblxyXG5cdFx0cmV0dXJuIHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdGZvciBsaXN0ZW5lciBpbiBAX2xpc3RlbmVyc1tldmVudE5hbWVdXHJcblxyXG5cdFx0XHRsaXN0ZW5lci5jYWxsIEAsIGRhdGFcclxuXHJcblx0XHRyZXR1cm5cclxuXHJcblx0IyB0aGlzIG1ha2VzIHN1cmUgdGhhdCBhbGwgdGhlIGNhbGxzIHRvIHRoaXMgY2xhc3MncyBtZXRob2QgJ2ZuTmFtZSdcclxuXHQjIGFyZSB0aHJvdHRsZWRcclxuXHRfdGhyb3R0bGVFbWl0dGVyTWV0aG9kOiAoZm5OYW1lLCB0aW1lID0gMTAwMCkgLT5cclxuXHJcblx0XHRvcmlnaW5hbEZuID0gQFtmbk5hbWVdXHJcblxyXG5cdFx0aWYgdHlwZW9mIG9yaWdpbmFsRm4gaXNudCAnZnVuY3Rpb24nXHJcblxyXG5cdFx0XHR0aHJvdyBFcnJvciBcInRoaXMgY2xhc3MgZG9lcyBub3QgaGF2ZSBhIG1ldGhvZCBjYWxsZWQgJyN7Zm5OYW1lfSdcIlxyXG5cclxuXHRcdGxhc3RDYWxsQXJncyA9IG51bGxcclxuXHRcdHBlbmRpbmcgPSBub1xyXG5cdFx0dGltZXIgPSBudWxsXHJcblxyXG5cdFx0QFtmbk5hbWVdID0gPT5cclxuXHJcblx0XHRcdGxhc3RDYWxsQXJncyA9IGFyZ3VtZW50c1xyXG5cclxuXHRcdFx0ZG8gcGVuZFxyXG5cclxuXHRcdHBlbmQgPSA9PlxyXG5cclxuXHRcdFx0aWYgcGVuZGluZ1xyXG5cclxuXHRcdFx0XHRjbGVhclRpbWVvdXQgdGltZXJcclxuXHJcblx0XHRcdHRpbWVyID0gc2V0VGltZW91dCBydW5JdCwgdGltZVxyXG5cclxuXHRcdFx0cGVuZGluZyA9IHllc1xyXG5cclxuXHRcdHJ1bkl0ID0gPT5cclxuXHJcblx0XHRcdHBlbmRpbmcgPSBub1xyXG5cclxuXHRcdFx0b3JpZ2luYWxGbi5hcHBseSBALCBsYXN0Q2FsbEFyZ3NcclxuXHJcblx0X2Rpc2FibGVFbWl0dGVyOiAoZm5OYW1lKSAtPlxyXG5cclxuXHRcdGlmIEBfZGlzYWJsZWRFbWl0dGVyc1tmbk5hbWVdP1xyXG5cclxuXHRcdFx0dGhyb3cgRXJyb3IgXCIje2ZuTmFtZX0gaXMgYWxyZWFkeSBhIGRpc2FibGVkIGVtaXR0ZXJcIlxyXG5cclxuXHRcdEBfZGlzYWJsZWRFbWl0dGVyc1tmbk5hbWVdID0gQFtmbk5hbWVdXHJcblxyXG5cdFx0QFtmbk5hbWVdID0gLT5cclxuXHJcblx0X2VuYWJsZUVtaXR0ZXI6IChmbk5hbWUpIC0+XHJcblxyXG5cdFx0Zm4gPSBAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXVxyXG5cclxuXHRcdHVubGVzcyBmbj9cclxuXHJcblx0XHRcdHRocm93IEVycm9yIFwiI3tmbk5hbWV9IGlzIG5vdCBhIGRpc2FibGVkIGVtaXR0ZXJcIlxyXG5cclxuXHRcdEBbZm5OYW1lXSA9IGZuXHJcblxyXG5cdFx0ZGVsZXRlIEBfZGlzYWJsZWRFbWl0dGVyc1tmbk5hbWVdIiwiX2NvbW1vbiA9IHJlcXVpcmUgJy4vX2NvbW1vbidcblxubW9kdWxlLmV4cG9ydHMgPSBvYmplY3QgPVxuXG5cdGlzQmFyZU9iamVjdDogX2NvbW1vbi5pc0JhcmVPYmplY3QuYmluZCBfY29tbW9uXG5cblx0IyMjXG5cdGlmIG9iamVjdCBpcyBhbiBpbnN0YW5jZSBvZiBhIGNsYXNzXG5cdCMjI1xuXHRpc0luc3RhbmNlOiAod2hhdCkgLT5cblxuXHRcdG5vdCBAaXNCYXJlT2JqZWN0IHdoYXRcblxuXHQjIyNcblx0QWxpYXMgdG8gX2NvbW1vbi50eXBlT2Zcblx0IyMjXG5cdHR5cGVPZjogX2NvbW1vbi50eXBlT2YuYmluZCBfY29tbW9uXG5cblx0IyMjXG5cdEFsaWFzIHRvIF9jb21tb24uY2xvbmVcblx0IyMjXG5cdGNsb25lOiBfY29tbW9uLmNsb25lLmJpbmQgX2NvbW1vblxuXG5cdCMjI1xuXHRFbXB0aWVzIGFuIG9iamVjdCBvZiBpdHMgcHJvcGVydGllcy5cblx0IyMjXG5cdGVtcHR5OiAobykgLT5cblxuXHRcdGZvciBwcm9wIG9mIG9cblxuXHRcdFx0ZGVsZXRlIG9bcHJvcF0gaWYgby5oYXNPd25Qcm9wZXJ0eSBwcm9wXG5cblx0XHRvXG5cblx0IyMjXG5cdEVtcHRpZXMgYW4gb2JqZWN0LiBEb2Vzbid0IGNoZWNrIGZvciBoYXNPd25Qcm9wZXJ0eSwgc28gaXQncyBhIHRpbnlcblx0Yml0IGZhc3Rlci4gVXNlIGl0IGZvciBwbGFpbiBvYmplY3RzLlxuXHQjIyNcblx0ZmFzdEVtcHR5OiAobykgLT5cblxuXHRcdGRlbGV0ZSBvW3Byb3BlcnR5XSBmb3IgcHJvcGVydHkgb2Ygb1xuXG5cdFx0b1xuXG5cdCMjI1xuXHRPdmVycmlkZXMgdmFsdWVzIGZvbXIgYG5ld1ZhbHVlc2Agb24gYGJhc2VgLCBhcyBsb25nIGFzIHRoZXlcblx0YWxyZWFkeSBleGlzdCBpbiBiYXNlLlxuXHQjIyNcblx0b3ZlcnJpZGVPbnRvOiAoYmFzZSwgbmV3VmFsdWVzKSAtPlxuXG5cdFx0cmV0dXJuIGJhc2UgaWYgbm90IEBpc0JhcmVPYmplY3QobmV3VmFsdWVzKSBvciBub3QgQGlzQmFyZU9iamVjdChiYXNlKVxuXG5cdFx0Zm9yIGtleSwgb2xkVmFsIG9mIGJhc2VcblxuXHRcdFx0bmV3VmFsID0gbmV3VmFsdWVzW2tleV1cblxuXHRcdFx0Y29udGludWUgaWYgbmV3VmFsIGlzIHVuZGVmaW5lZFxuXG5cdFx0XHRpZiB0eXBlb2YgbmV3VmFsIGlzbnQgJ29iamVjdCcgb3IgQGlzSW5zdGFuY2UgbmV3VmFsXG5cblx0XHRcdFx0YmFzZVtrZXldID0gQGNsb25lIG5ld1ZhbFxuXG5cdFx0XHQjIG5ld1ZhbCBpcyBhIHBsYWluIG9iamVjdFxuXHRcdFx0ZWxzZVxuXG5cdFx0XHRcdGlmIHR5cGVvZiBvbGRWYWwgaXNudCAnb2JqZWN0JyBvciBAaXNJbnN0YW5jZSBvbGRWYWxcblxuXHRcdFx0XHRcdGJhc2Vba2V5XSA9IEBjbG9uZSBuZXdWYWxcblxuXHRcdFx0XHRlbHNlXG5cblx0XHRcdFx0XHRAb3ZlcnJpZGVPbnRvIG9sZFZhbCwgbmV3VmFsXG5cdFx0YmFzZVxuXG5cdCMjI1xuXHRUYWtlcyBhIGNsb25lIG9mICdiYXNlJyBhbmQgcnVucyAjb3ZlcnJpZGVPbnRvIG9uIGl0XG5cdCMjI1xuXHRvdmVycmlkZTogKGJhc2UsIG5ld1ZhbHVlcykgLT5cblxuXHRcdEBvdmVycmlkZU9udG8gQGNsb25lKGJhc2UpLCBuZXdWYWx1ZXNcblxuXHRhcHBlbmQ6IChiYXNlLCB0b0FwcGVuZCkgLT5cblxuXHRcdEBhcHBlbmRPbnRvIEBjbG9uZShiYXNlKSwgdG9BcHBlbmRcblxuXHQjIERlZXAgYXBwZW5kcyB2YWx1ZXMgZnJvbSBgdG9BcHBlbmRgIHRvIGBiYXNlYFxuXHRhcHBlbmRPbnRvOiAoYmFzZSwgdG9BcHBlbmQpIC0+XG5cblx0XHRyZXR1cm4gYmFzZSBpZiBub3QgQGlzQmFyZU9iamVjdCh0b0FwcGVuZCkgb3Igbm90IEBpc0JhcmVPYmplY3QoYmFzZSlcblxuXHRcdGZvciBvd24ga2V5LCBuZXdWYWwgb2YgdG9BcHBlbmRcblxuXHRcdFx0Y29udGludWUgdW5sZXNzIG5ld1ZhbCBpc250IHVuZGVmaW5lZFxuXG5cdFx0XHRpZiB0eXBlb2YgbmV3VmFsIGlzbnQgJ29iamVjdCcgb3IgQGlzSW5zdGFuY2UgbmV3VmFsXG5cblx0XHRcdFx0YmFzZVtrZXldID0gbmV3VmFsXG5cblx0XHRcdGVsc2VcblxuXHRcdFx0XHQjIG5ld1ZhbCBpcyBhIGJhcmUgb2JqZWN0XG5cblx0XHRcdFx0b2xkVmFsID0gYmFzZVtrZXldXG5cblx0XHRcdFx0aWYgdHlwZW9mIG9sZFZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG9sZFZhbFxuXG5cdFx0XHRcdFx0YmFzZVtrZXldID0gQGNsb25lIG5ld1ZhbFxuXG5cdFx0XHRcdGVsc2VcblxuXHRcdFx0XHRcdEBhcHBlbmRPbnRvIG9sZFZhbCwgbmV3VmFsXG5cblx0XHRiYXNlXG5cblx0IyBHcm91cHNcblx0Z3JvdXBQcm9wczogKG9iaiwgZ3JvdXBzKSAtPlxuXG5cdFx0Z3JvdXBlZCA9IHt9XG5cblx0XHRmb3IgbmFtZSwgZGVmcyBvZiBncm91cHNcblxuXHRcdFx0Z3JvdXBlZFtuYW1lXSA9IHt9XG5cblx0XHRncm91cGVkWydyZXN0J10gPSB7fVxuXG5cdFx0YHRvcDogLy9gXG5cdFx0Zm9yIGtleSwgdmFsIG9mIG9ialxuXG5cdFx0XHRzaG91bGRBZGQgPSBub1xuXG5cdFx0XHRmb3IgbmFtZSwgZGVmcyBvZiBncm91cHNcblxuXHRcdFx0XHR1bmxlc3MgQXJyYXkuaXNBcnJheSBkZWZzXG5cblx0XHRcdFx0XHRkZWZzID0gW2RlZnNdXG5cblx0XHRcdFx0Zm9yIGRlZiBpbiBkZWZzXG5cblx0XHRcdFx0XHRpZiB0eXBlb2YgZGVmIGlzICdzdHJpbmcnXG5cblx0XHRcdFx0XHRcdGlmIGtleSBpcyBkZWZcblxuXHRcdFx0XHRcdFx0XHRzaG91bGRBZGQgPSB5ZXNcblxuXHRcdFx0XHRcdGVsc2UgaWYgZGVmIGluc3RhbmNlb2YgUmVnRXhwXG5cblx0XHRcdFx0XHRcdGlmIGRlZi50ZXN0IGtleVxuXG5cdFx0XHRcdFx0XHRcdHNob3VsZEFkZCA9IHllc1xuXG5cdFx0XHRcdFx0ZWxzZSBpZiBkZWYgaW5zdGFuY2VvZiBGdW5jdGlvblxuXG5cdFx0XHRcdFx0XHRpZiBkZWYga2V5XG5cblx0XHRcdFx0XHRcdFx0c2hvdWxkQWRkID0geWVzXG5cblx0XHRcdFx0XHRlbHNlXG5cblx0XHRcdFx0XHRcdHRocm93IEVycm9yICdHcm91cCBkZWZpbml0aW9ucyBtdXN0IGVpdGhlclxuXHRcdFx0XHRcdFx0YmUgc3RyaW5ncywgcmVnZXhlcywgb3IgZnVuY3Rpb25zLidcblxuXHRcdFx0XHRcdGlmIHNob3VsZEFkZFxuXG5cdFx0XHRcdFx0XHRncm91cGVkW25hbWVdW2tleV0gPSB2YWxcblxuXHRcdFx0XHRcdFx0YGNvbnRpbnVlIHRvcGBcblxuXHRcdFx0Z3JvdXBlZFsncmVzdCddW2tleV0gPSB2YWxcblxuXHRcdGdyb3VwZWQiLCJtb2R1bGUuZXhwb3J0cyA9XHJcblxyXG5cdCMgcGFkcyBhIG51bWJlciB3aXRoIGxlYWRpbmcgemVyb2VzXHJcblx0I1xyXG5cdCMgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTAwNzM3ODgvNjA3OTk3XHJcblx0cGFkOiAobiwgd2lkdGgsIHogPSAnMCcpIC0+XHJcblxyXG5cdFx0biA9IG4gKyAnJ1xyXG5cclxuXHRcdGlmIG4ubGVuZ3RoID49IHdpZHRoXHJcblxyXG5cdFx0XHRuXHJcblxyXG5cdFx0ZWxzZVxyXG5cclxuXHRcdFx0bmV3IEFycmF5KHdpZHRoIC0gbi5sZW5ndGggKyAxKS5qb2luKHopICsgbiIsIm1vZHVsZS5leHBvcnRzID0gdXRpbGEgPVxuXG5cdGFycmF5OiByZXF1aXJlICcuL2FycmF5J1xuXHRjbGFzc2ljOiByZXF1aXJlICcuL2NsYXNzaWMnXG5cdG9iamVjdDogcmVxdWlyZSAnLi9vYmplY3QnXG5cdHN0cmluZzogcmVxdWlyZSAnLi9zdHJpbmcnXG5cdEVtaXR0ZXI6IHJlcXVpcmUgJy4vRW1pdHRlciciXX0= \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/test/_prepare.js b/node_modules/utila/scripts/js/test/_prepare.js
new file mode 100644
index 000000000..0489e2e58
--- /dev/null
+++ b/node_modules/utila/scripts/js/test/_prepare.js
@@ -0,0 +1,9 @@
+var path, pathToLib;
+
+path = require('path');
+
+pathToLib = path.resolve(__dirname, '../lib');
+
+require('little-popo')(pathToLib);
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX3ByZXBhcmUuanMiLCJzb3VyY2VSb290IjoiLi5cXC4uIiwic291cmNlcyI6WyJjb2ZmZWVcXHRlc3RcXF9wcmVwYXJlLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFBLGVBQUE7O0FTQUEsSVNBQSxHU0FPLE9TQUEsQ1NBUSxNU0FSLENBQVAsQ0FBQTs7QVNFQSxTU0FBLEdTQVksSVNBSSxDU0FDLE9TQUwsQ1NBYSxTU0FiLEVTQXdCLFFTQXhCLENBRlosQ0FBQTs7QVNJQSxPU0FBLENTQVEsYVNBUixDU0FBLENTQXVCLFNTQXZCLENBSkEsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gYXJyYXkgPVxuXG5cdCMjI1xuXHRUcmllcyB0byB0dXJuIGFueXRoaW5nIGludG8gYW4gYXJyYXkuXG5cdCMjI1xuXHRmcm9tOiAocikgLT5cblxuXHRcdEFycmF5OjpzbGljZS5jYWxsIHJcblxuXHQjIyNcblx0Q2xvbmUgb2YgYW4gYXJyYXkuIFByb3BlcnRpZXMgd2lsbCBiZSBzaGFsbG93IGNvcGllcy5cblx0IyMjXG5cdHNpbXBsZUNsb25lOiAoYSkgLT5cblxuXHRcdGEuc2xpY2UgMFxuXG5cdHNoYWxsb3dFcXVhbDogKGExLCBhMikgLT5cblxuXHRcdHJldHVybiBubyB1bmxlc3MgQXJyYXkuaXNBcnJheShhMSkgYW5kIEFycmF5LmlzQXJyYXkoYTIpIGFuZCBhMS5sZW5ndGggaXMgYTIubGVuZ3RoXG5cblx0XHRmb3IgdmFsLCBpIGluIGExXG5cblx0XHRcdHJldHVybiBubyB1bmxlc3MgYTJbaV0gaXMgdmFsXG5cblx0XHR5ZXNcblxuXHRwbHVjazogKGEsIGkpIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIGluZGV4ID4gaVxuXG5cdFx0XHRcdGFbaW5kZXggLSAxXSA9IGFbaW5kZXhdXG5cblx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gMVxuXG5cdFx0YVxuXG5cdHBsdWNrSXRlbTogKGEsIGl0ZW0pIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXG5cdFx0cmVtb3ZlZCA9IDBcblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiB2YWx1ZSBpcyBpdGVtXG5cblx0XHRcdFx0cmVtb3ZlZCsrXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0aWYgcmVtb3ZlZCBpc250IDBcblxuXHRcdFx0XHRhW2luZGV4IC0gcmVtb3ZlZF0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIHJlbW92ZWQgaWYgcmVtb3ZlZCA+IDBcblxuXHRcdGFcblxuXHRwbHVja09uZUl0ZW06IChhLCBpdGVtKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblx0XHRyZWFjaGVkID0gbm9cblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBub3QgcmVhY2hlZFxuXG5cdFx0XHRcdGlmIHZhbHVlIGlzIGl0ZW1cblxuXHRcdFx0XHRcdHJlYWNoZWQgPSB5ZXNcblxuXHRcdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2VcblxuXHRcdFx0XHRhW2luZGV4IC0gMV0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIDEgaWYgcmVhY2hlZFxuXG5cdFx0YVxuXG5cdHBsdWNrQnlDYWxsYmFjazogKGEsIGNiKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblx0XHRyZW1vdmVkID0gMFxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIGNiIHZhbHVlLCBpbmRleFxuXG5cdFx0XHRcdHJlbW92ZWQrK1xuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGlmIHJlbW92ZWQgaXNudCAwXG5cblx0XHRcdFx0YVtpbmRleCAtIHJlbW92ZWRdID0gYVtpbmRleF1cblxuXHRcdGlmIHJlbW92ZWQgPiAwXG5cblx0XHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSByZW1vdmVkXG5cblx0XHRhXG5cblx0cGx1Y2tNdWx0aXBsZTogKGFycmF5LCBpbmRleGVzVG9SZW1vdmUpIC0+XG5cblx0XHRyZXR1cm4gYXJyYXkgaWYgYXJyYXkubGVuZ3RoIDwgMVxuXG5cdFx0cmVtb3ZlZFNvRmFyID0gMFxuXG5cdFx0aW5kZXhlc1RvUmVtb3ZlLnNvcnQoKVxuXG5cdFx0Zm9yIGkgaW4gaW5kZXhlc1RvUmVtb3ZlXG5cblx0XHRcdEBwbHVjayBhcnJheSwgaSAtIHJlbW92ZWRTb0ZhclxuXG5cdFx0XHRyZW1vdmVkU29GYXIrK1xuXG5cdFx0YXJyYXlcblxuXHRpbmplY3RCeUNhbGxiYWNrOiAoYSwgdG9JbmplY3QsIHNob3VsZEluamVjdCkgLT5cblxuXHRcdHZhbEEgPSBudWxsXG5cblx0XHR2YWxCID0gbnVsbFxuXG5cdFx0bGVuID0gYS5sZW5ndGhcblxuXHRcdGlmIGxlbiA8IDFcblxuXHRcdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRcdHJldHVybiBhXG5cblxuXHRcdGZvciB2YWwsIGkgaW4gYVxuXG5cdFx0XHR2YWxBID0gdmFsQlxuXG5cdFx0XHR2YWxCID0gdmFsXG5cblx0XHRcdGlmIHNob3VsZEluamVjdCB2YWxBLCB2YWxCLCB0b0luamVjdFxuXG5cdFx0XHRcdHJldHVybiBhLnNwbGljZSBpLCAwLCB0b0luamVjdFxuXG5cdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRhXG5cblx0aW5qZWN0SW5JbmRleDogKGEsIGluZGV4LCB0b0luamVjdCkgLT5cblxuXHRcdGxlbiA9IGEubGVuZ3RoXG5cblx0XHRpID0gaW5kZXhcblxuXHRcdGlmIGxlbiA8IDFcblxuXHRcdFx0YS5wdXNoIHRvSW5qZWN0XG5cblx0XHRcdHJldHVybiBhXG5cblx0XHR0b1B1dCA9IHRvSW5qZWN0XG5cblx0XHR0b1B1dE5leHQgPSBudWxsXG5cblx0XHRgZm9yKDsgaSA8PSBsZW47IGkrKyl7XG5cblx0XHRcdHRvUHV0TmV4dCA9IGFbaV07XG5cblx0XHRcdGFbaV0gPSB0b1B1dDtcblxuXHRcdFx0dG9QdXQgPSB0b1B1dE5leHQ7XG5cblx0XHR9YFxuXG5cdFx0IyBhW2ldID0gdG9QdXRcblxuXHRcdG51bGwiLCJtb2R1bGUuZXhwb3J0cyA9IGNsYXNzaWMgPSB7fVxuXG4jIExpdHRsZSBoZWxwZXIgZm9yIG1peGlucyBmcm9tIENvZmZlZVNjcmlwdCBGQVEsXG4jIGNvdXJ0ZXN5IG9mIFNldGhhdXJ1cyAoaHR0cDovL2dpdGh1Yi5jb20vc2V0aGF1cnVzKVxuY2xhc3NpYy5pbXBsZW1lbnQgPSAobWl4aW5zLi4uLCBjbGFzc1JlZmVyZW5jZSkgLT5cblxuXHRmb3IgbWl4aW4gaW4gbWl4aW5zXG5cblx0XHRjbGFzc1Byb3RvID0gY2xhc3NSZWZlcmVuY2U6OlxuXG5cdFx0Zm9yIG1lbWJlciBvZiBtaXhpbjo6XG5cblx0XHRcdHVubGVzcyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIGNsYXNzUHJvdG8sIG1lbWJlclxuXG5cdFx0XHRcdGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIG1peGluOjosIG1lbWJlclxuXG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBjbGFzc1Byb3RvLCBtZW1iZXIsIGRlc2NcblxuXHRjbGFzc1JlZmVyZW5jZVxuXG5jbGFzc2ljLm1peCA9IChtaXhpbnMuLi4sIGNsYXNzUmVmZXJlbmNlKSAtPlxuXG5cdGNsYXNzUHJvdG8gPSBjbGFzc1JlZmVyZW5jZTo6XG5cblx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnMgPSBbXVxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fYXBwbHlDbG9uZXJzRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBjbG9uZXIgaW4gY2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnNcblxuXHRcdFx0Y2xvbmVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRjbGFzc1JlZmVyZW5jZS5fX21peGluSW5pdGlhbGl6ZXJzID0gW11cblxuXHRjbGFzc1JlZmVyZW5jZS5fX2luaXRNaXhpbnNGb3IgPSAoaW5zdGFuY2UsIGFyZ3MgPSBudWxsKSAtPlxuXG5cdFx0Zm9yIGluaXRpYWxpemVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5Jbml0aWFsaXplcnNcblxuXHRcdFx0aW5pdGlhbGl6ZXIuYXBwbHkgaW5zdGFuY2UsIGFyZ3NcblxuXHRcdHJldHVyblxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVycyA9IFtdXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19hcHBseVF1aXR0ZXJzRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBxdWl0dGVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVyc1xuXG5cdFx0XHRxdWl0dGVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRmb3IgbWl4aW4gaW4gbWl4aW5zXG5cblx0XHR1bmxlc3MgbWl4aW4uY29uc3RydWN0b3IgaW5zdGFuY2VvZiBGdW5jdGlvblxuXG5cdFx0XHR0aHJvdyBFcnJvciBcIk1peGluIHNob3VsZCBiZSBhIGZ1bmN0aW9uXCJcblxuXHRcdGZvciBtZW1iZXIgb2YgbWl4aW46OlxuXG5cdFx0XHRpZiBtZW1iZXIuc3Vic3RyKDAsIDExKSBpcyAnX19pbml0TWl4aW4nXG5cblx0XHRcdFx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkluaXRpYWxpemVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2UgaWYgbWVtYmVyLnN1YnN0cigwLCAxMSkgaXMgJ19fY2xvbmVyRm9yJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzLnB1c2ggbWl4aW46OlttZW1iZXJdXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0ZWxzZSBpZiBtZW1iZXIuc3Vic3RyKDAsIDEyKSBpcyAnX19xdWl0dGVyRm9yJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5RdWl0dGVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdHVubGVzcyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIGNsYXNzUHJvdG8sIG1lbWJlclxuXG5cdFx0XHRcdGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIG1peGluOjosIG1lbWJlclxuXG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBjbGFzc1Byb3RvLCBtZW1iZXIsIGRlc2NcblxuXHRjbGFzc1JlZmVyZW5jZSIsImFycmF5ID0gcmVxdWlyZSAnLi9hcnJheSdcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xhc3MgRW1pdHRlclxyXG5cclxuXHRjb25zdHJ1Y3RvcjogLT5cclxuXHJcblx0XHRAX2xpc3RlbmVycyA9IHt9XHJcblxyXG5cdFx0QF9saXN0ZW5lcnNGb3JBbnlFdmVudCA9IFtdXHJcblxyXG5cdFx0QF9kaXNhYmxlZEVtaXR0ZXJzID0ge31cclxuXHJcblx0b246IChldmVudE5hbWUsIGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdFx0QF9saXN0ZW5lcnNbZXZlbnROYW1lXSA9IFtdXHJcblxyXG5cdFx0QF9saXN0ZW5lcnNbZXZlbnROYW1lXS5wdXNoIGxpc3RlbmVyXHJcblxyXG5cdFx0QFxyXG5cclxuXHRvbmNlOiAoZXZlbnROYW1lLCBsaXN0ZW5lcikgLT5cclxuXHJcblx0XHRyYW4gPSBub1xyXG5cclxuXHRcdGNiID0gPT5cclxuXHJcblx0XHRcdHJldHVybiBpZiByYW5cclxuXHJcblx0XHRcdHJhbiA9IHllc1xyXG5cclxuXHRcdFx0ZG8gbGlzdGVuZXJcclxuXHJcblx0XHRcdHNldFRpbWVvdXQgPT5cclxuXHJcblx0XHRcdFx0QHJlbW92ZUV2ZW50IGV2ZW50TmFtZSwgY2JcclxuXHJcblx0XHRcdCwgMFxyXG5cclxuXHRcdEBvbiBldmVudE5hbWUsIGNiXHJcblxyXG5cdFx0QFxyXG5cclxuXHRvbkFueUV2ZW50OiAobGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0QF9saXN0ZW5lcnNGb3JBbnlFdmVudC5wdXNoIGxpc3RlbmVyXHJcblxyXG5cdFx0QFxyXG5cclxuXHRyZW1vdmVFdmVudDogKGV2ZW50TmFtZSwgbGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0cmV0dXJuIEAgdW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0YXJyYXkucGx1Y2tPbmVJdGVtIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0sIGxpc3RlbmVyXHJcblxyXG5cdFx0QFxyXG5cclxuXHRyZW1vdmVMaXN0ZW5lcnM6IChldmVudE5hbWUpIC0+XHJcblxyXG5cdFx0cmV0dXJuIEAgdW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0QF9saXN0ZW5lcnNbZXZlbnROYW1lXS5sZW5ndGggPSAwXHJcblxyXG5cdFx0QFxyXG5cclxuXHRyZW1vdmVBbGxMaXN0ZW5lcnM6IC0+XHJcblxyXG5cdFx0Zm9yIG5hbWUsIGxpc3RlbmVycyBvZiBAX2xpc3RlbmVyc1xyXG5cclxuXHRcdFx0bGlzdGVuZXJzLmxlbmd0aCA9IDBcclxuXHJcblx0XHRAXHJcblxyXG5cdF9lbWl0OiAoZXZlbnROYW1lLCBkYXRhKSAtPlxyXG5cclxuXHRcdGZvciBsaXN0ZW5lciBpbiBAX2xpc3RlbmVyc0ZvckFueUV2ZW50XHJcblxyXG5cdFx0XHRsaXN0ZW5lci5jYWxsIEAsIGRhdGEsIGV2ZW50TmFtZVxyXG5cclxuXHRcdHJldHVybiB1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRmb3IgbGlzdGVuZXIgaW4gQF9saXN0ZW5lcnNbZXZlbnROYW1lXVxyXG5cclxuXHRcdFx0bGlzdGVuZXIuY2FsbCBALCBkYXRhXHJcblxyXG5cdFx0cmV0dXJuXHJcblxyXG5cdCMgdGhpcyBtYWtlcyBzdXJlIHRoYXQgYWxsIHRoZSBjYWxscyB0byB0aGlzIGNsYXNzJ3MgbWV0aG9kICdmbk5hbWUnXHJcblx0IyBhcmUgdGhyb3R0bGVkXHJcblx0X3Rocm90dGxlRW1pdHRlck1ldGhvZDogKGZuTmFtZSwgdGltZSA9IDEwMDApIC0+XHJcblxyXG5cdFx0b3JpZ2luYWxGbiA9IEBbZm5OYW1lXVxyXG5cclxuXHRcdGlmIHR5cGVvZiBvcmlnaW5hbEZuIGlzbnQgJ2Z1bmN0aW9uJ1xyXG5cclxuXHRcdFx0dGhyb3cgRXJyb3IgXCJ0aGlzIGNsYXNzIGRvZXMgbm90IGhhdmUgYSBtZXRob2QgY2FsbGVkICcje2ZuTmFtZX0nXCJcclxuXHJcblx0XHRsYXN0Q2FsbEFyZ3MgPSBudWxsXHJcblx0XHRwZW5kaW5nID0gbm9cclxuXHRcdHRpbWVyID0gbnVsbFxyXG5cclxuXHRcdEBbZm5OYW1lXSA9ID0+XHJcblxyXG5cdFx0XHRsYXN0Q2FsbEFyZ3MgPSBhcmd1bWVudHNcclxuXHJcblx0XHRcdGRvIHBlbmRcclxuXHJcblx0XHRwZW5kID0gPT5cclxuXHJcblx0XHRcdGlmIHBlbmRpbmdcclxuXHJcblx0XHRcdFx0Y2xlYXJUaW1lb3V0IHRpbWVyXHJcblxyXG5cdFx0XHR0aW1lciA9IHNldFRpbWVvdXQgcnVuSXQsIHRpbWVcclxuXHJcblx0XHRcdHBlbmRpbmcgPSB5ZXNcclxuXHJcblx0XHRydW5JdCA9ID0+XHJcblxyXG5cdFx0XHRwZW5kaW5nID0gbm9cclxuXHJcblx0XHRcdG9yaWdpbmFsRm4uYXBwbHkgQCwgbGFzdENhbGxBcmdzXHJcblxyXG5cdF9kaXNhYmxlRW1pdHRlcjogKGZuTmFtZSkgLT5cclxuXHJcblx0XHRpZiBAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXT9cclxuXHJcblx0XHRcdHRocm93IEVycm9yIFwiI3tmbk5hbWV9IGlzIGFscmVhZHkgYSBkaXNhYmxlZCBlbWl0dGVyXCJcclxuXHJcblx0XHRAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXSA9IEBbZm5OYW1lXVxyXG5cclxuXHRcdEBbZm5OYW1lXSA9IC0+XHJcblxyXG5cdF9lbmFibGVFbWl0dGVyOiAoZm5OYW1lKSAtPlxyXG5cclxuXHRcdGZuID0gQF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV1cclxuXHJcblx0XHR1bmxlc3MgZm4/XHJcblxyXG5cdFx0XHR0aHJvdyBFcnJvciBcIiN7Zm5OYW1lfSBpcyBub3QgYSBkaXNhYmxlZCBlbWl0dGVyXCJcclxuXHJcblx0XHRAW2ZuTmFtZV0gPSBmblxyXG5cclxuXHRcdGRlbGV0ZSBAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXSIsIl9jb21tb24gPSByZXF1aXJlICcuL19jb21tb24nXG5cbm1vZHVsZS5leHBvcnRzID0gb2JqZWN0ID1cblxuXHRpc0JhcmVPYmplY3Q6IF9jb21tb24uaXNCYXJlT2JqZWN0LmJpbmQgX2NvbW1vblxuXG5cdCMjI1xuXHRpZiBvYmplY3QgaXMgYW4gaW5zdGFuY2Ugb2YgYSBjbGFzc1xuXHQjIyNcblx0aXNJbnN0YW5jZTogKHdoYXQpIC0+XG5cblx0XHRub3QgQGlzQmFyZU9iamVjdCB3aGF0XG5cblx0IyMjXG5cdEFsaWFzIHRvIF9jb21tb24udHlwZU9mXG5cdCMjI1xuXHR0eXBlT2Y6IF9jb21tb24udHlwZU9mLmJpbmQgX2NvbW1vblxuXG5cdCMjI1xuXHRBbGlhcyB0byBfY29tbW9uLmNsb25lXG5cdCMjI1xuXHRjbG9uZTogX2NvbW1vbi5jbG9uZS5iaW5kIF9jb21tb25cblxuXHQjIyNcblx0RW1wdGllcyBhbiBvYmplY3Qgb2YgaXRzIHByb3BlcnRpZXMuXG5cdCMjI1xuXHRlbXB0eTogKG8pIC0+XG5cblx0XHRmb3IgcHJvcCBvZiBvXG5cblx0XHRcdGRlbGV0ZSBvW3Byb3BdIGlmIG8uaGFzT3duUHJvcGVydHkgcHJvcFxuXG5cdFx0b1xuXG5cdCMjI1xuXHRFbXB0aWVzIGFuIG9iamVjdC4gRG9lc24ndCBjaGVjayBmb3IgaGFzT3duUHJvcGVydHksIHNvIGl0J3MgYSB0aW55XG5cdGJpdCBmYXN0ZXIuIFVzZSBpdCBmb3IgcGxhaW4gb2JqZWN0cy5cblx0IyMjXG5cdGZhc3RFbXB0eTogKG8pIC0+XG5cblx0XHRkZWxldGUgb1twcm9wZXJ0eV0gZm9yIHByb3BlcnR5IG9mIG9cblxuXHRcdG9cblxuXHQjIyNcblx0T3ZlcnJpZGVzIHZhbHVlcyBmb21yIGBuZXdWYWx1ZXNgIG9uIGBiYXNlYCwgYXMgbG9uZyBhcyB0aGV5XG5cdGFscmVhZHkgZXhpc3QgaW4gYmFzZS5cblx0IyMjXG5cdG92ZXJyaWRlT250bzogKGJhc2UsIG5ld1ZhbHVlcykgLT5cblxuXHRcdHJldHVybiBiYXNlIGlmIG5vdCBAaXNCYXJlT2JqZWN0KG5ld1ZhbHVlcykgb3Igbm90IEBpc0JhcmVPYmplY3QoYmFzZSlcblxuXHRcdGZvciBrZXksIG9sZFZhbCBvZiBiYXNlXG5cblx0XHRcdG5ld1ZhbCA9IG5ld1ZhbHVlc1trZXldXG5cblx0XHRcdGNvbnRpbnVlIGlmIG5ld1ZhbCBpcyB1bmRlZmluZWRcblxuXHRcdFx0aWYgdHlwZW9mIG5ld1ZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG5ld1ZhbFxuXG5cdFx0XHRcdGJhc2Vba2V5XSA9IEBjbG9uZSBuZXdWYWxcblxuXHRcdFx0IyBuZXdWYWwgaXMgYSBwbGFpbiBvYmplY3Rcblx0XHRcdGVsc2VcblxuXHRcdFx0XHRpZiB0eXBlb2Ygb2xkVmFsIGlzbnQgJ29iamVjdCcgb3IgQGlzSW5zdGFuY2Ugb2xkVmFsXG5cblx0XHRcdFx0XHRiYXNlW2tleV0gPSBAY2xvbmUgbmV3VmFsXG5cblx0XHRcdFx0ZWxzZVxuXG5cdFx0XHRcdFx0QG92ZXJyaWRlT250byBvbGRWYWwsIG5ld1ZhbFxuXHRcdGJhc2VcblxuXHQjIyNcblx0VGFrZXMgYSBjbG9uZSBvZiAnYmFzZScgYW5kIHJ1bnMgI292ZXJyaWRlT250byBvbiBpdFxuXHQjIyNcblx0b3ZlcnJpZGU6IChiYXNlLCBuZXdWYWx1ZXMpIC0+XG5cblx0XHRAb3ZlcnJpZGVPbnRvIEBjbG9uZShiYXNlKSwgbmV3VmFsdWVzXG5cblx0YXBwZW5kOiAoYmFzZSwgdG9BcHBlbmQpIC0+XG5cblx0XHRAYXBwZW5kT250byBAY2xvbmUoYmFzZSksIHRvQXBwZW5kXG5cblx0IyBEZWVwIGFwcGVuZHMgdmFsdWVzIGZyb20gYHRvQXBwZW5kYCB0byBgYmFzZWBcblx0YXBwZW5kT250bzogKGJhc2UsIHRvQXBwZW5kKSAtPlxuXG5cdFx0cmV0dXJuIGJhc2UgaWYgbm90IEBpc0JhcmVPYmplY3QodG9BcHBlbmQpIG9yIG5vdCBAaXNCYXJlT2JqZWN0KGJhc2UpXG5cblx0XHRmb3Igb3duIGtleSwgbmV3VmFsIG9mIHRvQXBwZW5kXG5cblx0XHRcdGNvbnRpbnVlIHVubGVzcyBuZXdWYWwgaXNudCB1bmRlZmluZWRcblxuXHRcdFx0aWYgdHlwZW9mIG5ld1ZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG5ld1ZhbFxuXG5cdFx0XHRcdGJhc2Vba2V5XSA9IG5ld1ZhbFxuXG5cdFx0XHRlbHNlXG5cblx0XHRcdFx0IyBuZXdWYWwgaXMgYSBiYXJlIG9iamVjdFxuXG5cdFx0XHRcdG9sZFZhbCA9IGJhc2Vba2V5XVxuXG5cdFx0XHRcdGlmIHR5cGVvZiBvbGRWYWwgaXNudCAnb2JqZWN0JyBvciBAaXNJbnN0YW5jZSBvbGRWYWxcblxuXHRcdFx0XHRcdGJhc2Vba2V5XSA9IEBjbG9uZSBuZXdWYWxcblxuXHRcdFx0XHRlbHNlXG5cblx0XHRcdFx0XHRAYXBwZW5kT250byBvbGRWYWwsIG5ld1ZhbFxuXG5cdFx0YmFzZVxuXG5cdCMgR3JvdXBzXG5cdGdyb3VwUHJvcHM6IChvYmosIGdyb3VwcykgLT5cblxuXHRcdGdyb3VwZWQgPSB7fVxuXG5cdFx0Zm9yIG5hbWUsIGRlZnMgb2YgZ3JvdXBzXG5cblx0XHRcdGdyb3VwZWRbbmFtZV0gPSB7fVxuXG5cdFx0Z3JvdXBlZFsncmVzdCddID0ge31cblxuXHRcdGB0b3A6IC8vYFxuXHRcdGZvciBrZXksIHZhbCBvZiBvYmpcblxuXHRcdFx0c2hvdWxkQWRkID0gbm9cblxuXHRcdFx0Zm9yIG5hbWUsIGRlZnMgb2YgZ3JvdXBzXG5cblx0XHRcdFx0dW5sZXNzIEFycmF5LmlzQXJyYXkgZGVmc1xuXG5cdFx0XHRcdFx0ZGVmcyA9IFtkZWZzXVxuXG5cdFx0XHRcdGZvciBkZWYgaW4gZGVmc1xuXG5cdFx0XHRcdFx0aWYgdHlwZW9mIGRlZiBpcyAnc3RyaW5nJ1xuXG5cdFx0XHRcdFx0XHRpZiBrZXkgaXMgZGVmXG5cblx0XHRcdFx0XHRcdFx0c2hvdWxkQWRkID0geWVzXG5cblx0XHRcdFx0XHRlbHNlIGlmIGRlZiBpbnN0YW5jZW9mIFJlZ0V4cFxuXG5cdFx0XHRcdFx0XHRpZiBkZWYudGVzdCBrZXlcblxuXHRcdFx0XHRcdFx0XHRzaG91bGRBZGQgPSB5ZXNcblxuXHRcdFx0XHRcdGVsc2UgaWYgZGVmIGluc3RhbmNlb2YgRnVuY3Rpb25cblxuXHRcdFx0XHRcdFx0aWYgZGVmIGtleVxuXG5cdFx0XHRcdFx0XHRcdHNob3VsZEFkZCA9IHllc1xuXG5cdFx0XHRcdFx0ZWxzZVxuXG5cdFx0XHRcdFx0XHR0aHJvdyBFcnJvciAnR3JvdXAgZGVmaW5pdGlvbnMgbXVzdCBlaXRoZXJcblx0XHRcdFx0XHRcdGJlIHN0cmluZ3MsIHJlZ2V4ZXMsIG9yIGZ1bmN0aW9ucy4nXG5cblx0XHRcdFx0XHRpZiBzaG91bGRBZGRcblxuXHRcdFx0XHRcdFx0Z3JvdXBlZFtuYW1lXVtrZXldID0gdmFsXG5cblx0XHRcdFx0XHRcdGBjb250aW51ZSB0b3BgXG5cblx0XHRcdGdyb3VwZWRbJ3Jlc3QnXVtrZXldID0gdmFsXG5cblx0XHRncm91cGVkIiwibW9kdWxlLmV4cG9ydHMgPVxyXG5cclxuXHQjIHBhZHMgYSBudW1iZXIgd2l0aCBsZWFkaW5nIHplcm9lc1xyXG5cdCNcclxuXHQjIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzEwMDczNzg4LzYwNzk5N1xyXG5cdHBhZDogKG4sIHdpZHRoLCB6ID0gJzAnKSAtPlxyXG5cclxuXHRcdG4gPSBuICsgJydcclxuXHJcblx0XHRpZiBuLmxlbmd0aCA+PSB3aWR0aFxyXG5cclxuXHRcdFx0blxyXG5cclxuXHRcdGVsc2VcclxuXHJcblx0XHRcdG5ldyBBcnJheSh3aWR0aCAtIG4ubGVuZ3RoICsgMSkuam9pbih6KSArIG4iLCJtb2R1bGUuZXhwb3J0cyA9IHV0aWxhID1cblxuXHRhcnJheTogcmVxdWlyZSAnLi9hcnJheSdcblx0Y2xhc3NpYzogcmVxdWlyZSAnLi9jbGFzc2ljJ1xuXHRvYmplY3Q6IHJlcXVpcmUgJy4vb2JqZWN0J1xuXHRzdHJpbmc6IHJlcXVpcmUgJy4vc3RyaW5nJ1xuXHRFbWl0dGVyOiByZXF1aXJlICcuL0VtaXR0ZXInIiwibW9kdWxlLmV4cG9ydHMgPSBjb21tb24gPVxuXG5cdCMjI1xuXHRDaGVja3MgdG8gc2VlIGlmIG8gaXMgYW4gb2JqZWN0LCBhbmQgaXQgaXNuJ3QgYW4gaW5zdGFuY2Vcblx0b2Ygc29tZSBjbGFzcy5cblx0IyMjXG5cdGlzQmFyZU9iamVjdDogKG8pIC0+XG5cblx0XHRpZiBvPyBhbmQgby5jb25zdHJ1Y3RvciBpcyBPYmplY3RcblxuXHRcdFx0cmV0dXJuIHRydWVcblxuXHRcdGZhbHNlXG5cblx0IyMjXG5cdFJldHVybnMgdHlwZSBvZiBhbiBvYmplY3QsIGluY2x1ZGluZzpcblx0dW5kZWZpbmVkLCBudWxsLCBzdHJpbmcsIG51bWJlciwgYXJyYXksXG5cdGFyZ3VtZW50cywgZWxlbWVudCwgdGV4dG5vZGUsIHdoaXRlc3BhY2UsIGFuZCBvYmplY3Rcblx0IyMjXG5cdHR5cGVPZjogKGl0ZW0pIC0+XG5cblx0XHRyZXR1cm4gJ251bGwnIGlmIGl0ZW0gaXMgbnVsbFxuXG5cdFx0cmV0dXJuIHR5cGVvZiBpdGVtIGlmIHR5cGVvZiBpdGVtIGlzbnQgJ29iamVjdCdcblxuXHRcdHJldHVybiAnYXJyYXknIGlmIEFycmF5LmlzQXJyYXkgaXRlbVxuXG5cdFx0IyBGcm9tIE1vb1Rvb2xzXG5cdFx0IyAtIGRvIHdlIGV2ZW4gbmVlZCB0aGlzP1xuXHRcdGlmIGl0ZW0ubm9kZU5hbWVcblxuXHRcdFx0aWYgaXRlbS5ub2RlVHlwZSBpcyAxIHRoZW4gcmV0dXJuICdlbGVtZW50J1xuXHRcdFx0aWYgaXRlbS5ub2RlVHlwZSBpcyAzIHRoZW4gcmV0dXJuICgvXFxTLykudGVzdChpdGVtLm5vZGVWYWx1ZSkgPyAndGV4dG5vZGUnIDogJ3doaXRlc3BhY2UnXG5cblx0XHRlbHNlIGlmIHR5cGVvZiBpdGVtLmxlbmd0aCBpcyAnbnVtYmVyJ1xuXG5cdFx0XHRpZiBpdGVtLmNhbGxlZSB0aGVuIHJldHVybiAnYXJndW1lbnRzJ1xuXG5cdFx0cmV0dXJuIHR5cGVvZiBpdGVtXG5cblx0IyBEZWVwIGNsb25lIG9mIGFueSB2YXJpYWJsZS5cblx0IyBGcm9tIE1vb1Rvb2xzXG5cdGNsb25lOiAoaXRlbSwgaW5jbHVkZVByb3RvdHlwZSA9IGZhbHNlKSAtPlxuXG5cdFx0c3dpdGNoIGNvbW1vbi50eXBlT2YgaXRlbVxuXG5cdFx0XHR3aGVuICdhcnJheScgdGhlbiByZXR1cm4gY29tbW9uLl9jbG9uZUFycmF5IGl0ZW0sIGluY2x1ZGVQcm90b3R5cGVcblxuXHRcdFx0d2hlbiAnb2JqZWN0JyB0aGVuIHJldHVybiBjb21tb24uX2Nsb25lT2JqZWN0IGl0ZW0sIGluY2x1ZGVQcm90b3R5cGVcblxuXHRcdFx0ZWxzZSByZXR1cm4gaXRlbVxuXG5cdCMjI1xuXHREZWVwIGNsb25lIG9mIGFuIG9iamVjdC5cblx0RnJvbSBNb29Ub29sc1xuXHQjIyNcblx0X2Nsb25lT2JqZWN0OiAobywgaW5jbHVkZVByb3RvdHlwZSA9IGZhbHNlKSAtPlxuXG5cdFx0aWYgY29tbW9uLmlzQmFyZU9iamVjdCBvXG5cblx0XHRcdGNsb25lID0ge31cblxuXHRcdFx0Zm9yIGtleSBvZiBvXG5cblx0XHRcdFx0Y2xvbmVba2V5XSA9IGNvbW1vbi5jbG9uZSBvW2tleV0sIGluY2x1ZGVQcm90b3R5cGVcblxuXHRcdFx0cmV0dXJuIGNsb25lXG5cblx0XHRlbHNlXG5cblx0XHRcdHJldHVybiBvIHVubGVzcyBpbmNsdWRlUHJvdG90eXBlXG5cblx0XHRcdHJldHVybiBvIGlmIG8gaW5zdGFuY2VvZiBGdW5jdGlvblxuXG5cdFx0XHRjbG9uZSA9IE9iamVjdC5jcmVhdGUgby5jb25zdHJ1Y3Rvci5wcm90b3R5cGVcblxuXHRcdFx0Zm9yIGtleSBvZiBvXG5cblx0XHRcdFx0aWYgby5oYXNPd25Qcm9wZXJ0eSBrZXlcblxuXHRcdFx0XHRcdGNsb25lW2tleV0gPSBjb21tb24uY2xvbmUgb1trZXldLCBpbmNsdWRlUHJvdG90eXBlXG5cblx0XHRcdGNsb25lXG5cblx0IyMjXG5cdERlZXAgY2xvbmUgb2YgYW4gYXJyYXkuXG5cdEZyb20gTW9vVG9vbHNcblx0IyMjXG5cdF9jbG9uZUFycmF5OiAoYSwgaW5jbHVkZVByb3RvdHlwZSA9IGZhbHNlKSAtPlxuXG5cdFx0aSA9IGEubGVuZ3RoXG5cblx0XHRjbG9uZSA9IG5ldyBBcnJheSBpXG5cblx0XHR3aGlsZSBpLS1cblxuXHRcdFx0Y2xvbmVbaV0gPSBjb21tb24uY2xvbmUgYVtpXSwgaW5jbHVkZVByb3RvdHlwZVxuXG5cdFx0Y2xvbmUiLCJyZXF1aXJlICcuL19wcmVwYXJlJ1xuXG5hcnJheSA9IG1vZCAnYXJyYXknXG5cbnRlc3QgJ2Zyb20nLCAtPlxuXG5cdGFycmF5LmZyb20oWzFdKS5zaG91bGQuYmUuYW4uaW5zdGFuY2VPZiBBcnJheVxuXHRhcnJheS5mcm9tKFsxXSlbMF0uc2hvdWxkLmVxdWFsIDFcblxuIyB0ZXN0ICdjbG9uZScsIC0+XG5cbiMgXHRhID0gWzAsIDEsIDJdXG5cbiMgXHRiID0gYXJyYXkuY2xvbmUgYVxuXG4jIFx0YlswXS5zaG91bGQuZXF1YWwgMFxuIyBcdGJbMV0uc2hvdWxkLmVxdWFsIDFcblxuIyBcdGJbMF0gPSAzXG5cbiMgXHRhWzBdLnNob3VsZC5lcXVhbCAwXG5cbnRlc3QgJ3BsdWNrJywgLT5cblxuXHRhID0gWzAsIDEsIDIsIDNdXG5cblx0YWZ0ZXIgPSBhcnJheS5wbHVjayBhLCAxXG5cblx0YWZ0ZXIubGVuZ3RoLnNob3VsZC5lcXVhbCAzXG5cblx0YWZ0ZXJbMF0uc2hvdWxkLmVxdWFsIDBcblx0YWZ0ZXJbMV0uc2hvdWxkLmVxdWFsIDJcblx0YWZ0ZXJbMl0uc2hvdWxkLmVxdWFsIDNcblx0YWZ0ZXIuc2hvdWxkLmVxdWFsIGFcblxudGVzdCAncGx1Y2tNdWx0aXBsZScsIC0+XG5cblx0YSA9IFswLCAxLCAyLCAzLCA0LCA1LCA2XVxuXG5cdGFycmF5LnBsdWNrTXVsdGlwbGUgYSwgWzAsIDQsIDIsIDZdXG5cblx0YS5sZW5ndGguc2hvdWxkLmVxdWFsIDNcblx0YVswXS5zaG91bGQuZXF1YWwgMVxuXHRhWzFdLnNob3VsZC5lcXVhbCAzXG5cdGFbMl0uc2hvdWxkLmVxdWFsIDVcblxudGVzdCAncGx1Y2tJdGVtJywgLT5cblxuXHRhID0gWzAsIDEsIDIsIDMsIDIsIDQsIDJdXG5cblx0YXJyYXkucGx1Y2tJdGVtIGEsIDJcblxuXHRhWzBdLnNob3VsZC5lcXVhbCAwXG5cdGFbMV0uc2hvdWxkLmVxdWFsIDFcblx0YVsyXS5zaG91bGQuZXF1YWwgM1xuXHRhWzNdLnNob3VsZC5lcXVhbCA0XG5cblx0YXJyYXkucGx1Y2tJdGVtKFsxXSwgMikubGVuZ3RoLnNob3VsZC5lcXVhbCAxXG5cblxudGVzdCAncGx1Y2tPbmVJdGVtJywgLT5cblxuXHRhID0gWzAsIDEsIDIsIDMsIDIsIDQsIDJdXG5cblx0YXJyYXkucGx1Y2tPbmVJdGVtIGEsIDJcblxuXHRhWzBdLnNob3VsZC5lcXVhbCAwXG5cdGFbMV0uc2hvdWxkLmVxdWFsIDFcblx0YVsyXS5zaG91bGQuZXF1YWwgM1xuXHRhWzNdLnNob3VsZC5lcXVhbCAyXG5cdGFbNF0uc2hvdWxkLmVxdWFsIDRcblx0YVs1XS5zaG91bGQuZXF1YWwgMlxuXG5cdGEgPSBbMSwgMl1cblxuXHRhcnJheS5wbHVja09uZUl0ZW0gYSwgMVxuXG5cdGEubGVuZ3RoLnNob3VsZC5lcXVhbCAxXG5cdGFbMF0uc2hvdWxkLmVxdWFsIDJcblxuXHRhcnJheS5wbHVja09uZUl0ZW0oW10sIDEpLmxlbmd0aC5zaG91bGQuZXF1YWwgMFxuXG5cdGFycmF5LnBsdWNrT25lSXRlbShbMV0sIDIpLmxlbmd0aC5zaG91bGQuZXF1YWwgMVxuXG50ZXN0ICdwbGN1a0J5Q2FsbGJhY2snLCAtPlxuXG5cdGEgPSBbMCwgMSwgMiwgM11cblxuXHRhcnJheS5wbHVja0J5Q2FsbGJhY2sgYSwgKHZhbCwgaSkgLT5cblxuXHRcdHJldHVybiB5ZXMgaWYgdmFsIGlzIDJcblxuXHRcdHJldHVybiBub1xuXG5cdGFbMF0uc2hvdWxkLmVxdWFsIDBcblx0YVsxXS5zaG91bGQuZXF1YWwgMVxuXHRhWzJdLnNob3VsZC5lcXVhbCAzXG5cbnRlc3QgJ2luamVjdEJ5Q2FsbGJhY2snLCAtPlxuXG5cdHNob3VsZEluamVjdCA9ICh2YWxBLCB2YWxCLCB0b0luamVjdCkgLT5cblxuXHRcdHVubGVzcyB2YWxBP1xuXG5cdFx0XHRyZXR1cm4geWVzIGlmIHRvSW5qZWN0IDw9IHZhbEJcblxuXHRcdFx0cmV0dXJuIG5vXG5cblx0XHR1bmxlc3MgdmFsQj9cblxuXHRcdFx0cmV0dXJuIHllcyBpZiB2YWxBIDw9IHRvSW5qZWN0XG5cblx0XHRcdHJldHVybiBub1xuXG5cdFx0cmV0dXJuIHllcyBpZiB2YWxBIDw9IHRvSW5qZWN0IDw9IHZhbEJcblxuXHRcdHJldHVybiBub1xuXG5cdGEgPSBbMC41LCAxLCAyLjUsIDIuNSwgMi43NSwgMi43NSwgM11cblxuXHRhcnJheS5pbmplY3RCeUNhbGxiYWNrIGEsIDAsIHNob3VsZEluamVjdFxuXG5cdGFbMF0uc2hvdWxkLmVxdWFsIDBcblx0YVsxXS5zaG91bGQuZXF1YWwgMC41XG5cdGFbN10uc2hvdWxkLmVxdWFsIDNcblxuXHRhID0gWzAuNSwgMSwgMi41LCAyLjUsIDIuNzUsIDIuNzUsIDNdXG5cblx0YXJyYXkuaW5qZWN0QnlDYWxsYmFjayBhLCAyLjcsIHNob3VsZEluamVjdFxuXG5cdGFbMF0uc2hvdWxkLmVxdWFsIDAuNVxuXHRhWzRdLnNob3VsZC5lcXVhbCAyLjdcblx0YVs1XS5zaG91bGQuZXF1YWwgMi43NVxuXHRhWzddLnNob3VsZC5lcXVhbCAzXG5cblx0YSA9IFswLjUsIDEsIDIuNSwgMi41LCAyLjc1LCAyLjc1LCAzXVxuXG5cdGFycmF5LmluamVjdEJ5Q2FsbGJhY2sgYSwgMy4yLCBzaG91bGRJbmplY3RcblxuXHRhWzBdLnNob3VsZC5lcXVhbCAwLjVcblx0YVs0XS5zaG91bGQuZXF1YWwgMi43NVxuXHRhWzZdLnNob3VsZC5lcXVhbCAzXG5cdGFbN10uc2hvdWxkLmVxdWFsIDMuMiIsInJlcXVpcmUgJy4vX3ByZXBhcmUnXG5cbm9iamVjdCA9IG1vZCAnb2JqZWN0J1xuXG50ZXN0ICdpc0JhcmVPYmplY3QnLCAtPlxuXG5cdG9iamVjdC5pc0JhcmVPYmplY3QoJ2EnKS5zaG91bGQuZXF1YWwgZmFsc2VcblxuXHRvYmplY3QuaXNCYXJlT2JqZWN0KHsnYSc6ICdhJ30pLnNob3VsZC5lcXVhbCB0cnVlXG5cbnRlc3QgJ3R5cGVPZicsIC0+XG5cblx0b2JqZWN0LnR5cGVPZigncycpLnNob3VsZC5lcXVhbCAnc3RyaW5nJ1xuXHRvYmplY3QudHlwZU9mKDApLnNob3VsZC5lcXVhbCAnbnVtYmVyJ1xuXHRvYmplY3QudHlwZU9mKGZhbHNlKS5zaG91bGQuZXF1YWwgJ2Jvb2xlYW4nXG5cdG9iamVjdC50eXBlT2Yoe30pLnNob3VsZC5lcXVhbCAnb2JqZWN0J1xuXHRvYmplY3QudHlwZU9mKGFyZ3VtZW50cykuc2hvdWxkLmVxdWFsICdhcmd1bWVudHMnXG5cdG9iamVjdC50eXBlT2YoW10pLnNob3VsZC5lcXVhbCAnYXJyYXknXG5cbnRlc3QgJ2VtcHR5JywgLT5cblxuXHRvID1cblxuXHRcdGE6IDFcblx0XHRiOiAyXG5cblxuXHRvYmplY3QuZW1wdHkgb1xuXG5cdG8uc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5ICdhJ1xuXHRvLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSAnYidcblxudGVzdCAnZmFzdEVtcHR5JywgLT5cblxuXHRvID1cblx0XHRhOiAxXG5cdFx0YjogMlxuXG5cblx0b2JqZWN0LmZhc3RFbXB0eSBvXG5cblx0by5zaG91bGQubm90LmhhdmUucHJvcGVydHkgJ2EnXG5cdG8uc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5ICdiJ1xuXG50ZXN0ICdjbG9uZScsIC0+XG5cblx0b2JqZWN0LmNsb25lKFsxXSlbMF0uc2hvdWxkLmVxdWFsIDFcblx0b2JqZWN0LmNsb25lKHthOjF9KS5hLnNob3VsZC5lcXVhbCAxXG5cblx0byA9IHthOiAxfVxuXG5cdG9iamVjdC5jbG9uZShvKS5zaG91bGQubm90LmVxdWFsIG9cblxudGVzdCAnY2xvbmUgW2luY2x1ZGUgcHJvdG90eXBlXScsIC0+XG5cblx0Y2xhc3MgQ1xuXG5cdFx0Y29uc3RydWN0b3I6IChAYSkgLT5cblxuXHRcdHNheUE6IC0+IEBhICsgJ2EnXG5cblx0YSA9IG5ldyBDICdhJ1xuXG5cdGEuc2F5QSgpLnNob3VsZC5lcXVhbCAnYWEnXG5cblx0YiA9IG9iamVjdC5jbG9uZSBhLCB5ZXNcblxuXHRiLnNob3VsZC5ub3QuZXF1YWwgYVxuXG5cdGIuY29uc3RydWN0b3Iuc2hvdWxkLmVxdWFsIENcblxuXHRiLmEuc2hvdWxkLmVxdWFsICdhJ1xuXG5cdGIuYSA9ICdhMidcblxuXHRiLnNheUEoKS5zaG91bGQuZXF1YWwgJ2EyYSdcblxudGVzdCAnY2xvbmUgW3dpdGhvdXQgcHJvdG90eXBlXScsIC0+XG5cblx0Y2xhc3MgQ1xuXG5cdFx0Y29uc3RydWN0b3I6IChAYSkgLT5cblxuXHRcdHNheUE6IC0+IEBhICsgJ2EnXG5cblx0YSA9IG5ldyBDICdhJ1xuXG5cdGEuc2F5QSgpLnNob3VsZC5lcXVhbCAnYWEnXG5cblx0YiA9IG9iamVjdC5jbG9uZSBhLCBub1xuXG5cdGIuc2hvdWxkLmVxdWFsIGFcblxudGVzdCAnb3ZlcnJpZGVPbnRvIFtiYXNpY10nLCAtPlxuXG5cdG9udG8gPVxuXHRcdGE6ICdhJ1xuXHRcdGI6XG5cdFx0XHRjOiAnYydcblx0XHRcdGQ6XG5cdFx0XHRcdGU6ICdlJ1xuXG5cdHdoYXQgPVxuXHRcdGE6ICdhMidcblx0XHRiOlxuXHRcdFx0YzogJ2MyJ1xuXHRcdFx0ZDpcblx0XHRcdFx0ZjogJ2YyJ1xuXG5cdG9iamVjdC5vdmVycmlkZU9udG8gb250bywgd2hhdFxuXG5cdG9udG8uYS5zaG91bGQuZXF1YWwgJ2EyJ1xuXHRvbnRvLmIuc2hvdWxkLmhhdmUucHJvcGVydHkgJ2MnXG5cdG9udG8uYi5jLnNob3VsZC5lcXVhbCAnYzInXG5cdG9udG8uYi5kLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSAnZidcblx0b250by5iLmQuZS5zaG91bGQuZXF1YWwgJ2UnXG5cbnRlc3QgJ292ZXJyaWRlJywgLT5cblxuXHRvbnRvID1cblxuXHRcdGE6ICdhJ1xuXG5cdFx0YjpcblxuXHRcdFx0YzogJ2MnXG5cblx0XHRcdGQ6XG5cblx0XHRcdFx0ZTogJ2UnXG5cblx0d2hhdCA9XG5cblx0XHRhOiAnYTInXG5cblx0XHRiOlxuXG5cdFx0XHRjOiAnYzInXG5cblx0XHRcdGQ6XG5cblx0XHRcdFx0ZjogJ2YyJ1xuXG5cblx0b250bzIgPSBvYmplY3Qub3ZlcnJpZGUgb250bywgd2hhdFxuXG5cdG9udG8yLmEuc2hvdWxkLmVxdWFsICdhMidcblx0b250bzIuYi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSAnYydcblx0b250bzIuYi5jLnNob3VsZC5lcXVhbCAnYzInXG5cdG9udG8yLmIuZC5zaG91bGQubm90LmhhdmUucHJvcGVydHkgJ2YnXG5cdG9udG8yLmIuZC5lLnNob3VsZC5lcXVhbCAnZSdcblxuXHRvbnRvLnNob3VsZC5ub3QuZXF1YWwgb250bzJcblxuZG8gLT5cblxuXHR3aGF0ID1cblxuXHRcdGE6ICdhMidcblxuXHRcdGM6IC0+XG5cblx0XHR6OiAneidcblxuXHRcdHk6XG5cblx0XHRcdGE6ICdhJ1xuXG5cdG9udG8gPVxuXG5cdFx0YTogJ2EnXG5cblx0XHRiOiAnYidcblxuXHR0ZXN0ICdhcHBlbmRPbnRvIFtiYXNpY10nLCAtPlxuXG5cdFx0b2JqZWN0LmFwcGVuZE9udG8gb250bywgd2hhdFxuXG5cdFx0b250by5hLnNob3VsZC5lcXVhbCAnYTInXG5cdFx0b250by5iLnNob3VsZC5lcXVhbCAnYidcblx0XHRvbnRvLnouc2hvdWxkLmVxdWFsICd6J1xuXG5cdHRlc3QgXCJhcHBlbmRPbnRvIFtzaGFsbG93IGNvcGllcyBpbnN0YW5jZXNdXCIsIC0+XG5cblx0XHRvbnRvLmMuc2hvdWxkLmJlLmluc3RhbmNlb2YgRnVuY3Rpb25cblx0XHRvbnRvLmMuc2hvdWxkLmVxdWFsIHdoYXQuY1xuXG5cblx0dGVzdCBcImFwcGVuZE9udG8gW2Nsb25lcyBvYmplY3RzXVwiLCAtPlxuXG5cdFx0b250by5zaG91bGQuaGF2ZS5wcm9wZXJ0eSAneSdcblx0XHRvbnRvLnkuYS5zaG91bGQuZXF1YWwgJ2EnXG5cdFx0b250by55LnNob3VsZC5ub3QuZXF1YWwgd2hhdC55XG5cbnRlc3QgJ2dyb3VwUHJvcHMnLCAtPlxuXG5cdG9iaiA9XG5cblx0XHRhMTogJzEnXG5cdFx0YTI6ICcyJ1xuXG5cdFx0YjE6ICcxJ1xuXHRcdGIyOiAnMidcblxuXHRcdGMxOiAnMSdcblx0XHRjMjogJzInXG5cblx0XHRyZXN0MTogJzEnXG5cdFx0cmVzdDI6ICcyJ1xuXG5cdGdyb3VwcyA9IG9iamVjdC5ncm91cFByb3BzIG9iaixcblxuXHRcdGE6IFsnYTEnLCAnYTInXVxuXG5cdFx0YjogWy9eYlswLTldKyQvXVxuXG5cdFx0YzogKGtleSkgLT4ga2V5WzBdIGlzICdjJ1xuXG5cdGdyb3Vwcy5hLnNob3VsZC5oYXZlLnByb3BlcnR5ICdhMSdcblx0Z3JvdXBzLmEuYTEuc2hvdWxkLmVxdWFsICcxJ1xuXG5cdGdyb3Vwcy5hLnNob3VsZC5oYXZlLnByb3BlcnR5ICdhMidcblxuXHRncm91cHMuYi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSAnYjEnXG5cdGdyb3Vwcy5iLnNob3VsZC5oYXZlLnByb3BlcnR5ICdiMidcblxuXHRncm91cHMuYy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSAnYzEnXG5cdGdyb3Vwcy5jLnNob3VsZC5oYXZlLnByb3BlcnR5ICdjMidcblxuXHRncm91cHMucmVzdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSAncmVzdDEnXG5cdGdyb3Vwcy5yZXN0LnNob3VsZC5oYXZlLnByb3BlcnR5ICdyZXN0MSdcblxuXHRncm91cHMucmVzdC5zaG91bGQubm90LmhhdmUucHJvcGVydHkgJ2MxJyIsInBhdGggPSByZXF1aXJlICdwYXRoJ1xuXG5wYXRoVG9MaWIgPSBwYXRoLnJlc29sdmUgX19kaXJuYW1lLCAnLi4vbGliJ1xuXG5yZXF1aXJlKCdsaXR0bGUtcG9wbycpKHBhdGhUb0xpYikiXX0= \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/test/array.js b/node_modules/utila/scripts/js/test/array.js
new file mode 100644
index 000000000..febdfaa57
--- /dev/null
+++ b/node_modules/utila/scripts/js/test/array.js
@@ -0,0 +1,115 @@
+var array;
+
+require('./_prepare');
+
+array = mod('array');
+
+test('from', function() {
+ array.from([1]).should.be.an.instanceOf(Array);
+ return array.from([1])[0].should.equal(1);
+});
+
+test('pluck', function() {
+ var a, after;
+ a = [0, 1, 2, 3];
+ after = array.pluck(a, 1);
+ after.length.should.equal(3);
+ after[0].should.equal(0);
+ after[1].should.equal(2);
+ after[2].should.equal(3);
+ return after.should.equal(a);
+});
+
+test('pluckMultiple', function() {
+ var a;
+ a = [0, 1, 2, 3, 4, 5, 6];
+ array.pluckMultiple(a, [0, 4, 2, 6]);
+ a.length.should.equal(3);
+ a[0].should.equal(1);
+ a[1].should.equal(3);
+ return a[2].should.equal(5);
+});
+
+test('pluckItem', function() {
+ var a;
+ a = [0, 1, 2, 3, 2, 4, 2];
+ array.pluckItem(a, 2);
+ a[0].should.equal(0);
+ a[1].should.equal(1);
+ a[2].should.equal(3);
+ a[3].should.equal(4);
+ return array.pluckItem([1], 2).length.should.equal(1);
+});
+
+test('pluckOneItem', function() {
+ var a;
+ a = [0, 1, 2, 3, 2, 4, 2];
+ array.pluckOneItem(a, 2);
+ a[0].should.equal(0);
+ a[1].should.equal(1);
+ a[2].should.equal(3);
+ a[3].should.equal(2);
+ a[4].should.equal(4);
+ a[5].should.equal(2);
+ a = [1, 2];
+ array.pluckOneItem(a, 1);
+ a.length.should.equal(1);
+ a[0].should.equal(2);
+ array.pluckOneItem([], 1).length.should.equal(0);
+ return array.pluckOneItem([1], 2).length.should.equal(1);
+});
+
+test('plcukByCallback', function() {
+ var a;
+ a = [0, 1, 2, 3];
+ array.pluckByCallback(a, function(val, i) {
+ if (val === 2) {
+ return true;
+ }
+ return false;
+ });
+ a[0].should.equal(0);
+ a[1].should.equal(1);
+ return a[2].should.equal(3);
+});
+
+test('injectByCallback', function() {
+ var a, shouldInject;
+ shouldInject = function(valA, valB, toInject) {
+ if (valA == null) {
+ if (toInject <= valB) {
+ return true;
+ }
+ return false;
+ }
+ if (valB == null) {
+ if (valA <= toInject) {
+ return true;
+ }
+ return false;
+ }
+ if ((valA <= toInject && toInject <= valB)) {
+ return true;
+ }
+ return false;
+ };
+ a = [0.5, 1, 2.5, 2.5, 2.75, 2.75, 3];
+ array.injectByCallback(a, 0, shouldInject);
+ a[0].should.equal(0);
+ a[1].should.equal(0.5);
+ a[7].should.equal(3);
+ a = [0.5, 1, 2.5, 2.5, 2.75, 2.75, 3];
+ array.injectByCallback(a, 2.7, shouldInject);
+ a[0].should.equal(0.5);
+ a[4].should.equal(2.7);
+ a[5].should.equal(2.75);
+ a[7].should.equal(3);
+ a = [0.5, 1, 2.5, 2.5, 2.75, 2.75, 3];
+ array.injectByCallback(a, 3.2, shouldInject);
+ a[0].should.equal(0.5);
+ a[4].should.equal(2.75);
+ a[6].should.equal(3);
+ return a[7].should.equal(3.2);
+});
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXkuanMiLCJzb3VyY2VSb290IjoiLi5cXC4uIiwic291cmNlcyI6WyJjb2ZmZWVcXHRlc3RcXGFycmF5LmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFBLEtBQUE7O0FPQUEsT09BQSxDT0FRLFlPQVIsQ0FBQSxDQUFBOztBT0VBLEtPQUEsR09BUSxHT0FBLENPQUksT09BSixDQUZSLENBQUE7O0FPSUEsSU9BQSxDT0FLLE1PQUwsRU9BYSxTT0FBLEdPQUE7QU9FWixFT0FBLEtPQUssQ09BQyxJT0FOLENPQVcsQ09BQyxDT0FELENPQVgsQ09BZSxDT0FDLE1PQU0sQ09BQyxFT0FFLENPQUMsRU9BRSxDT0FDLFVPQTdCLENPQXdDLEtPQXhDLENPQUEsQ09BQTtTT0NBLEtPQUssQ09BQyxJT0FOLENPQVcsQ09BQyxDT0FELENPQVgsQ09BZ0IsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BMUIsQ09BZ0MsQ09BaEMsRU9IWTtBT0FBLENPQWIsQ0FKQSxDQUFBOztBT3NCQSxJT0FBLENPQUssT09BTCxFT0FjLFNPQUEsR09BQTtBT0ViLE1PQUEsUU9BQTtBT0FBLEVPQUEsQ09BQSxHT0FJLENPQUMsQ09BRCxFT0FJLENPQUosRU9BTyxDT0FQLEVPQVUsQ09BVixDT0FKLENPQUE7QU9BQSxFT0VBLEtPQUEsR09BUSxLT0FLLENPQUMsS09BTixDT0FZLENPQVosRU9BZSxDT0FmLENPRlIsQ09BQTtBT0FBLEVPSUEsS09BSyxDT0FDLE1PQU0sQ09BQyxNT0FNLENPQUMsS09BcEIsQ09BMEIsQ09BMUIsQ09KQSxDT0FBO0FPQUEsRU9NQSxLT0FNLENPQUEsQ09BQSxDT0FFLENPQUMsTU9BTSxDT0FDLEtPQWhCLENPQXNCLENPQXRCLENPTkEsQ09BQTtBT0FBLEVPT0EsS09BTSxDT0FBLENPQUEsQ09BRSxDT0FDLE1PQU0sQ09BQyxLT0FoQixDT0FzQixDT0F0QixDT1BBLENPQUE7QU9BQSxFT1FBLEtPQU0sQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BaEIsQ09Bc0IsQ09BdEIsQ09SQSxDT0FBO1NPU0EsS09BSyxDT0FDLE1PQU0sQ09BQyxLT0FiLENPQW1CLENPQW5CLEVPWGE7QU9BQSxDT0FkLENBdEJBLENBQUE7O0FPbUNBLElPQUEsQ09BSyxlT0FMLEVPQXNCLFNPQUEsR09BQTtBT0VyQixNT0FBLENPQUE7QU9BQSxFT0FBLENPQUEsR09BSSxDT0FDLENPQUQsRU9BSSxDT0FKLEVPQU8sQ09BUCxFT0FVLENPQVYsRU9BYSxDT0FiLEVPQWdCLENPQWhCLEVPQW1CLENPQW5CLENPQUosQ09BQTtBT0FBLEVPRUEsS09BSyxDT0FDLGFPQU4sQ09Bb0IsQ09BcEIsRU9BdUIsQ09BQyxDT0FELEVPQUksQ09BSixFT0FPLENPQVAsRU9BVSxDT0FWLENPQXZCLENPRkEsQ09BQTtBT0FBLEVPSUEsQ09BQyxDT0FDLE1PQU0sQ09BQyxNT0FNLENPQUMsS09BaEIsQ09Bc0IsQ09BdEIsQ09KQSxDT0FBO0FPQUEsRU9LQSxDT0FFLENPQUEsQ09BQSxDT0FFLENPQUMsTU9BTSxDT0FDLEtPQVosQ09Ba0IsQ09BbEIsQ09MQSxDT0FBO0FPQUEsRU9NQSxDT0FFLENPQUEsQ09BQSxDT0FFLENPQUMsTU9BTSxDT0FDLEtPQVosQ09Ba0IsQ09BbEIsQ09OQSxDT0FBO1NPT0EsQ09BRSxDT0FBLENPQUEsQ09BRSxDT0FDLE1PQU0sQ09BQyxLT0FaLENPQWtCLENPQWxCLEVPVHFCO0FPQUEsQ09BdEIsQ0FuQ0EsQ0FBQTs7QU84Q0EsSU9BQSxDT0FLLFdPQUwsRU9Ba0IsU09BQSxHT0FBO0FPRWpCLE1PQUEsQ09BQTtBT0FBLEVPQUEsQ09BQSxHT0FJLENPQUMsQ09BRCxFT0FJLENPQUosRU9BTyxDT0FQLEVPQVUsQ09BVixFT0FhLENPQWIsRU9BZ0IsQ09BaEIsRU9BbUIsQ09BbkIsQ09BSixDT0FBO0FPQUEsRU9FQSxLT0FLLENPQUMsU09BTixDT0FnQixDT0FoQixFT0FtQixDT0FuQixDT0ZBLENPQUE7QU9BQSxFT0lBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT0pBLENPQUE7QU9BQSxFT0tBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT0xBLENPQUE7QU9BQSxFT01BLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT05BLENPQUE7QU9BQSxFT09BLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT1BBLENPQUE7U09TQSxLT0FLLENPQUMsU09BTixDT0FnQixDT0FDLENPQUQsQ09BaEIsRU9BcUIsQ09BckIsQ09BdUIsQ09BQyxNT0FNLENPQUMsTU9BTSxDT0FDLEtPQXRDLENPQTRDLENPQTVDLEVPWGlCO0FPQUEsQ09BbEIsQ0E5Q0EsQ0FBQTs7QU80REEsSU9BQSxDT0FLLGNPQUwsRU9BcUIsU09BQSxHT0FBO0FPRXBCLE1PQUEsQ09BQTtBT0FBLEVPQUEsQ09BQSxHT0FJLENPQUMsQ09BRCxFT0FJLENPQUosRU9BTyxDT0FQLEVPQVUsQ09BVixFT0FhLENPQWIsRU9BZ0IsQ09BaEIsRU9BbUIsQ09BbkIsQ09BSixDT0FBO0FPQUEsRU9FQSxLT0FLLENPQUMsWU9BTixDT0FtQixDT0FuQixFT0FzQixDT0F0QixDT0ZBLENPQUE7QU9BQSxFT0lBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT0pBLENPQUE7QU9BQSxFT0tBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT0xBLENPQUE7QU9BQSxFT01BLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT05BLENPQUE7QU9BQSxFT09BLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT1BBLENPQUE7QU9BQSxFT1FBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT1JBLENPQUE7QU9BQSxFT1NBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT1RBLENPQUE7QU9BQSxFT1dBLENPQUEsR09BSSxDT0FDLENPQUQsRU9BSSxDT0FKLENPWEosQ09BQTtBT0FBLEVPYUEsS09BSyxDT0FDLFlPQU4sQ09BbUIsQ09BbkIsRU9Bc0IsQ09BdEIsQ09iQSxDT0FBO0FPQUEsRU9lQSxDT0FDLENPQUMsTU9BTSxDT0FDLE1PQU0sQ09BQyxLT0FoQixDT0FzQixDT0F0QixDT2ZBLENPQUE7QU9BQSxFT2dCQSxDT0FFLENPQUEsQ09BQSxDT0FFLENPQUMsTU9BTSxDT0FDLEtPQVosQ09Ba0IsQ09BbEIsQ09oQkEsQ09BQTtBT0FBLEVPa0JBLEtPQUssQ09BQyxZT0FOLENPQW1CLEVPQW5CLEVPQXVCLENPQXZCLENPQXlCLENPQUMsTU9BTSxDT0FDLE1PQU0sQ09BQyxLT0F4QyxDT0E4QyxDT0E5QyxDT2xCQSxDT0FBO1NPb0JBLEtPQUssQ09BQyxZT0FOLENPQW1CLENPQUMsQ09BRCxDT0FuQixFT0F3QixDT0F4QixDT0EwQixDT0FDLE1PQU0sQ09BQyxNT0FNLENPQUMsS09BekMsQ09BK0MsQ09BL0MsRU90Qm9CO0FPQUEsQ09BckIsQ0E1REEsQ0FBQTs7QU9vRkEsSU9BQSxDT0FLLGlCT0FMLEVPQXdCLFNPQUEsR09BQTtBT0V2QixNT0FBLENPQUE7QU9BQSxFT0FBLENPQUEsR09BSSxDT0FDLENPQUQsRU9BSSxDT0FKLEVPQU8sQ09BUCxFT0FVLENPQVYsQ09BSixDT0FBO0FPQUEsRU9FQSxLT0FLLENPQUMsZU9BTixDT0FzQixDT0F0QixFT0F5QixTT0FDLEdPQUQsRU9BTSxDT0FOLEdPQUE7QU9FeEIsSU9BQSxJT0FjLEdPQUEsS09BTyxDT0FyQjtBT0FBLGFPQU8sSU9BUCxDT0FBO0tPQUE7QU9FQSxXT0FPLEtPQVAsQ09Kd0I7RU9BQSxDT0F6QixDT0ZBLENPQUE7QU9BQSxFT1FBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT1JBLENPQUE7QU9BQSxFT1NBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT1RBLENPQUE7U09VQSxDT0FFLENPQUEsQ09BQSxDT0FFLENPQUMsTU9BTSxDT0FDLEtPQVosQ09Ba0IsQ09BbEIsRU9adUI7QU9BQSxDT0F4QixDQXBGQSxDQUFBOztBT2tHQSxJT0FBLENPQUssa0JPQUwsRU9BeUIsU09BQSxHT0FBO0FPRXhCLE1PQUEsZU9BQTtBT0FBLEVPQUEsWU9BQSxHT0FlLFNPQUMsSU9BRCxFT0FPLElPQVAsRU9BYSxRT0FiLEdPQUE7QU9FZCxJT0FBLElPQU8sWU9BUDtBT0VDLE1PQUEsSU9BYyxRT0FBLElPQVksSU9BMUI7QU9BQSxlT0FPLElPQVAsQ09BQTtPT0FBO0FPRUEsYU9BTyxLT0FQLENPSkQ7S09BQTtBT01BLElPQUEsSU9BTyxZT0FQO0FPRUMsTU9BQSxJT0FjLElPQUEsSU9BUSxRT0F0QjtBT0FBLGVPQU8sSU9BUCxDT0FBO09PQUE7QU9FQSxhT0FPLEtPQVAsQ09KRDtLT05BO0FPWUEsSU9BQSxJT0FjLENPQUEsSU9BQSxJT0FRLFFPQVIsSU9BUSxRT0FSLElPQW9CLElPQXBCLENPQWQ7QU9BQSxhT0FPLElPQVAsQ09BQTtLT1pBO0FPY0EsV09BTyxLT0FQLENPaEJjO0VPQUEsQ09BZixDT0FBO0FPQUEsRU9rQkEsQ09BQSxHT0FJLENPQUMsR09BRCxFT0FNLENPQU4sRU9BUyxHT0FULEVPQWMsR09BZCxFT0FtQixJT0FuQixFT0F5QixJT0F6QixFT0ErQixDT0EvQixDT2xCSixDT0FBO0FPQUEsRU9vQkEsS09BSyxDT0FDLGdCT0FOLENPQXVCLENPQXZCLEVPQTBCLENPQTFCLEVPQTZCLFlPQTdCLENPcEJBLENPQUE7QU9BQSxFT3NCQSxDT0FFLENPQUEsQ09BQSxDT0FFLENPQUMsTU9BTSxDT0FDLEtPQVosQ09Ba0IsQ09BbEIsQ090QkEsQ09BQTtBT0FBLEVPdUJBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixHT0FsQixDT3ZCQSxDT0FBO0FPQUEsRU93QkEsQ09BRSxDT0FBLENPQUEsQ09BRSxDT0FDLE1PQU0sQ09BQyxLT0FaLENPQWtCLENPQWxCLENPeEJBLENPQUE7QU9BQSxFTzBCQSxDT0FBLEdPQUksQ09BQyxHT0FELEVPQU0sQ09BTixFT0FTLEdPQVQsRU9BYyxHT0FkLEVPQW1CLElPQW5CLEVPQXlCLElPQXpCLEVPQStCLENPQS9CLENPMUJKLENPQUE7QU9BQSxFTzRCQSxLT0FLLENPQUMsZ0JPQU4sQ09BdUIsQ09BdkIsRU9BMEIsR09BMUIsRU9BK0IsWU9BL0IsQ081QkEsQ09BQTtBT0FBLEVPOEJBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixHT0FsQixDTzlCQSxDT0FBO0FPQUEsRU8rQkEsQ09BRSxDT0FBLENPQUEsQ09BRSxDT0FDLE1PQU0sQ09BQyxLT0FaLENPQWtCLEdPQWxCLENPL0JBLENPQUE7QU9BQSxFT2dDQSxDT0FFLENPQUEsQ09BQSxDT0FFLENPQUMsTU9BTSxDT0FDLEtPQVosQ09Ba0IsSU9BbEIsQ09oQ0EsQ09BQTtBT0FBLEVPaUNBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixDT0FsQixDT2pDQSxDT0FBO0FPQUEsRU9tQ0EsQ09BQSxHT0FJLENPQUMsR09BRCxFT0FNLENPQU4sRU9BUyxHT0FULEVPQWMsR09BZCxFT0FtQixJT0FuQixFT0F5QixJT0F6QixFT0ErQixDT0EvQixDT25DSixDT0FBO0FPQUEsRU9xQ0EsS09BSyxDT0FDLGdCT0FOLENPQXVCLENPQXZCLEVPQTBCLEdPQTFCLEVPQStCLFlPQS9CLENPckNBLENPQUE7QU9BQSxFT3VDQSxDT0FFLENPQUEsQ09BQSxDT0FFLENPQUMsTU9BTSxDT0FDLEtPQVosQ09Ba0IsR09BbEIsQ092Q0EsQ09BQTtBT0FBLEVPd0NBLENPQUUsQ09BQSxDT0FBLENPQUUsQ09BQyxNT0FNLENPQUMsS09BWixDT0FrQixJT0FsQixDT3hDQSxDT0FBO0FPQUEsRU95Q0EsQ09BRSxDT0FBLENPQUEsQ09BRSxDT0FDLE1PQU0sQ09BQyxLT0FaLENPQWtCLENPQWxCLENPekNBLENPQUE7U08wQ0EsQ09BRSxDT0FBLENPQUEsQ09BRSxDT0FDLE1PQU0sQ09BQyxLT0FaLENPQWtCLEdPQWxCLEVPNUN3QjtBT0FBLENPQXpCLENBbEdBLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IGFycmF5ID1cblxuXHQjIyNcblx0VHJpZXMgdG8gdHVybiBhbnl0aGluZyBpbnRvIGFuIGFycmF5LlxuXHQjIyNcblx0ZnJvbTogKHIpIC0+XG5cblx0XHRBcnJheTo6c2xpY2UuY2FsbCByXG5cblx0IyMjXG5cdENsb25lIG9mIGFuIGFycmF5LiBQcm9wZXJ0aWVzIHdpbGwgYmUgc2hhbGxvdyBjb3BpZXMuXG5cdCMjI1xuXHRzaW1wbGVDbG9uZTogKGEpIC0+XG5cblx0XHRhLnNsaWNlIDBcblxuXHRzaGFsbG93RXF1YWw6IChhMSwgYTIpIC0+XG5cblx0XHRyZXR1cm4gbm8gdW5sZXNzIEFycmF5LmlzQXJyYXkoYTEpIGFuZCBBcnJheS5pc0FycmF5KGEyKSBhbmQgYTEubGVuZ3RoIGlzIGEyLmxlbmd0aFxuXG5cdFx0Zm9yIHZhbCwgaSBpbiBhMVxuXG5cdFx0XHRyZXR1cm4gbm8gdW5sZXNzIGEyW2ldIGlzIHZhbFxuXG5cdFx0eWVzXG5cblx0cGx1Y2s6IChhLCBpKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBpbmRleCA+IGlcblxuXHRcdFx0XHRhW2luZGV4IC0gMV0gPSBhW2luZGV4XVxuXG5cdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIDFcblxuXHRcdGFcblxuXHRwbHVja0l0ZW06IChhLCBpdGVtKSAtPlxuXG5cdFx0cmV0dXJuIGEgaWYgYS5sZW5ndGggPCAxXG5cblxuXHRcdHJlbW92ZWQgPSAwXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgdmFsdWUgaXMgaXRlbVxuXG5cdFx0XHRcdHJlbW92ZWQrK1xuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGlmIHJlbW92ZWQgaXNudCAwXG5cblx0XHRcdFx0YVtpbmRleCAtIHJlbW92ZWRdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSByZW1vdmVkIGlmIHJlbW92ZWQgPiAwXG5cblx0XHRhXG5cblx0cGx1Y2tPbmVJdGVtOiAoYSwgaXRlbSkgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cdFx0cmVhY2hlZCA9IG5vXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgbm90IHJlYWNoZWRcblxuXHRcdFx0XHRpZiB2YWx1ZSBpcyBpdGVtXG5cblx0XHRcdFx0XHRyZWFjaGVkID0geWVzXG5cblx0XHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRlbHNlXG5cblx0XHRcdFx0YVtpbmRleCAtIDFdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSAxIGlmIHJlYWNoZWRcblxuXHRcdGFcblxuXHRwbHVja0J5Q2FsbGJhY2s6IChhLCBjYikgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cdFx0cmVtb3ZlZCA9IDBcblxuXHRcdGZvciB2YWx1ZSwgaW5kZXggaW4gYVxuXG5cdFx0XHRpZiBjYiB2YWx1ZSwgaW5kZXhcblxuXHRcdFx0XHRyZW1vdmVkKytcblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRpZiByZW1vdmVkIGlzbnQgMFxuXG5cdFx0XHRcdGFbaW5kZXggLSByZW1vdmVkXSA9IGFbaW5kZXhdXG5cblx0XHRpZiByZW1vdmVkID4gMFxuXG5cdFx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gcmVtb3ZlZFxuXG5cdFx0YVxuXG5cdHBsdWNrTXVsdGlwbGU6IChhcnJheSwgaW5kZXhlc1RvUmVtb3ZlKSAtPlxuXG5cdFx0cmV0dXJuIGFycmF5IGlmIGFycmF5Lmxlbmd0aCA8IDFcblxuXHRcdHJlbW92ZWRTb0ZhciA9IDBcblxuXHRcdGluZGV4ZXNUb1JlbW92ZS5zb3J0KClcblxuXHRcdGZvciBpIGluIGluZGV4ZXNUb1JlbW92ZVxuXG5cdFx0XHRAcGx1Y2sgYXJyYXksIGkgLSByZW1vdmVkU29GYXJcblxuXHRcdFx0cmVtb3ZlZFNvRmFyKytcblxuXHRcdGFycmF5XG5cblx0aW5qZWN0QnlDYWxsYmFjazogKGEsIHRvSW5qZWN0LCBzaG91bGRJbmplY3QpIC0+XG5cblx0XHR2YWxBID0gbnVsbFxuXG5cdFx0dmFsQiA9IG51bGxcblxuXHRcdGxlbiA9IGEubGVuZ3RoXG5cblx0XHRpZiBsZW4gPCAxXG5cblx0XHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0XHRyZXR1cm4gYVxuXG5cblx0XHRmb3IgdmFsLCBpIGluIGFcblxuXHRcdFx0dmFsQSA9IHZhbEJcblxuXHRcdFx0dmFsQiA9IHZhbFxuXG5cdFx0XHRpZiBzaG91bGRJbmplY3QgdmFsQSwgdmFsQiwgdG9JbmplY3RcblxuXHRcdFx0XHRyZXR1cm4gYS5zcGxpY2UgaSwgMCwgdG9JbmplY3RcblxuXHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0YVxuXG5cdGluamVjdEluSW5kZXg6IChhLCBpbmRleCwgdG9JbmplY3QpIC0+XG5cblx0XHRsZW4gPSBhLmxlbmd0aFxuXG5cdFx0aSA9IGluZGV4XG5cblx0XHRpZiBsZW4gPCAxXG5cblx0XHRcdGEucHVzaCB0b0luamVjdFxuXG5cdFx0XHRyZXR1cm4gYVxuXG5cdFx0dG9QdXQgPSB0b0luamVjdFxuXG5cdFx0dG9QdXROZXh0ID0gbnVsbFxuXG5cdFx0YGZvcig7IGkgPD0gbGVuOyBpKyspe1xuXG5cdFx0XHR0b1B1dE5leHQgPSBhW2ldO1xuXG5cdFx0XHRhW2ldID0gdG9QdXQ7XG5cblx0XHRcdHRvUHV0ID0gdG9QdXROZXh0O1xuXG5cdFx0fWBcblxuXHRcdCMgYVtpXSA9IHRvUHV0XG5cblx0XHRudWxsIiwibW9kdWxlLmV4cG9ydHMgPSBjbGFzc2ljID0ge31cblxuIyBMaXR0bGUgaGVscGVyIGZvciBtaXhpbnMgZnJvbSBDb2ZmZWVTY3JpcHQgRkFRLFxuIyBjb3VydGVzeSBvZiBTZXRoYXVydXMgKGh0dHA6Ly9naXRodWIuY29tL3NldGhhdXJ1cylcbmNsYXNzaWMuaW1wbGVtZW50ID0gKG1peGlucy4uLiwgY2xhc3NSZWZlcmVuY2UpIC0+XG5cblx0Zm9yIG1peGluIGluIG1peGluc1xuXG5cdFx0Y2xhc3NQcm90byA9IGNsYXNzUmVmZXJlbmNlOjpcblxuXHRcdGZvciBtZW1iZXIgb2YgbWl4aW46OlxuXG5cdFx0XHR1bmxlc3MgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBjbGFzc1Byb3RvLCBtZW1iZXJcblxuXHRcdFx0XHRkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBtaXhpbjo6LCBtZW1iZXJcblxuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkgY2xhc3NQcm90bywgbWVtYmVyLCBkZXNjXG5cblx0Y2xhc3NSZWZlcmVuY2VcblxuY2xhc3NpYy5taXggPSAobWl4aW5zLi4uLCBjbGFzc1JlZmVyZW5jZSkgLT5cblxuXHRjbGFzc1Byb3RvID0gY2xhc3NSZWZlcmVuY2U6OlxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzID0gW11cblxuXHRjbGFzc1JlZmVyZW5jZS5fX2FwcGx5Q2xvbmVyc0ZvciA9IChpbnN0YW5jZSwgYXJncyA9IG51bGwpIC0+XG5cblx0XHRmb3IgY2xvbmVyIGluIGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5DbG9uZXJzXG5cblx0XHRcdGNsb25lci5hcHBseSBpbnN0YW5jZSwgYXJnc1xuXG5cdFx0cmV0dXJuXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkluaXRpYWxpemVycyA9IFtdXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19pbml0TWl4aW5zRm9yID0gKGluc3RhbmNlLCBhcmdzID0gbnVsbCkgLT5cblxuXHRcdGZvciBpbml0aWFsaXplciBpbiBjbGFzc1JlZmVyZW5jZS5fX21peGluSW5pdGlhbGl6ZXJzXG5cblx0XHRcdGluaXRpYWxpemVyLmFwcGx5IGluc3RhbmNlLCBhcmdzXG5cblx0XHRyZXR1cm5cblxuXHRjbGFzc1JlZmVyZW5jZS5fX21peGluUXVpdHRlcnMgPSBbXVxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fYXBwbHlRdWl0dGVyc0ZvciA9IChpbnN0YW5jZSwgYXJncyA9IG51bGwpIC0+XG5cblx0XHRmb3IgcXVpdHRlciBpbiBjbGFzc1JlZmVyZW5jZS5fX21peGluUXVpdHRlcnNcblxuXHRcdFx0cXVpdHRlci5hcHBseSBpbnN0YW5jZSwgYXJnc1xuXG5cdFx0cmV0dXJuXG5cblx0Zm9yIG1peGluIGluIG1peGluc1xuXG5cdFx0dW5sZXNzIG1peGluLmNvbnN0cnVjdG9yIGluc3RhbmNlb2YgRnVuY3Rpb25cblxuXHRcdFx0dGhyb3cgRXJyb3IgXCJNaXhpbiBzaG91bGQgYmUgYSBmdW5jdGlvblwiXG5cblx0XHRmb3IgbWVtYmVyIG9mIG1peGluOjpcblxuXHRcdFx0aWYgbWVtYmVyLnN1YnN0cigwLCAxMSkgaXMgJ19faW5pdE1peGluJ1xuXG5cdFx0XHRcdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5Jbml0aWFsaXplcnMucHVzaCBtaXhpbjo6W21lbWJlcl1cblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRlbHNlIGlmIG1lbWJlci5zdWJzdHIoMCwgMTEpIGlzICdfX2Nsb25lckZvcidcblxuXHRcdFx0XHRjbGFzc1JlZmVyZW5jZS5fX21peGluQ2xvbmVycy5wdXNoIG1peGluOjpbbWVtYmVyXVxuXG5cdFx0XHRcdGNvbnRpbnVlXG5cblx0XHRcdGVsc2UgaWYgbWVtYmVyLnN1YnN0cigwLCAxMikgaXMgJ19fcXVpdHRlckZvcidcblxuXHRcdFx0XHRjbGFzc1JlZmVyZW5jZS5fX21peGluUXVpdHRlcnMucHVzaCBtaXhpbjo6W21lbWJlcl1cblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHR1bmxlc3MgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBjbGFzc1Byb3RvLCBtZW1iZXJcblxuXHRcdFx0XHRkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciBtaXhpbjo6LCBtZW1iZXJcblxuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkgY2xhc3NQcm90bywgbWVtYmVyLCBkZXNjXG5cblx0Y2xhc3NSZWZlcmVuY2UiLCJhcnJheSA9IHJlcXVpcmUgJy4vYXJyYXknXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYXNzIEVtaXR0ZXJcclxuXHJcblx0Y29uc3RydWN0b3I6IC0+XHJcblxyXG5cdFx0QF9saXN0ZW5lcnMgPSB7fVxyXG5cclxuXHRcdEBfbGlzdGVuZXJzRm9yQW55RXZlbnQgPSBbXVxyXG5cclxuXHRcdEBfZGlzYWJsZWRFbWl0dGVycyA9IHt9XHJcblxyXG5cdG9uOiAoZXZlbnROYW1lLCBsaXN0ZW5lcikgLT5cclxuXHJcblx0XHR1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRcdEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0gPSBbXVxyXG5cclxuXHRcdEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0ucHVzaCBsaXN0ZW5lclxyXG5cclxuXHRcdEBcclxuXHJcblx0b25jZTogKGV2ZW50TmFtZSwgbGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0cmFuID0gbm9cclxuXHJcblx0XHRjYiA9ID0+XHJcblxyXG5cdFx0XHRyZXR1cm4gaWYgcmFuXHJcblxyXG5cdFx0XHRyYW4gPSB5ZXNcclxuXHJcblx0XHRcdGRvIGxpc3RlbmVyXHJcblxyXG5cdFx0XHRzZXRUaW1lb3V0ID0+XHJcblxyXG5cdFx0XHRcdEByZW1vdmVFdmVudCBldmVudE5hbWUsIGNiXHJcblxyXG5cdFx0XHQsIDBcclxuXHJcblx0XHRAb24gZXZlbnROYW1lLCBjYlxyXG5cclxuXHRcdEBcclxuXHJcblx0b25BbnlFdmVudDogKGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdEBfbGlzdGVuZXJzRm9yQW55RXZlbnQucHVzaCBsaXN0ZW5lclxyXG5cclxuXHRcdEBcclxuXHJcblx0cmVtb3ZlRXZlbnQ6IChldmVudE5hbWUsIGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdHJldHVybiBAIHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdGFycmF5LnBsdWNrT25lSXRlbSBAX2xpc3RlbmVyc1tldmVudE5hbWVdLCBsaXN0ZW5lclxyXG5cclxuXHRcdEBcclxuXHJcblx0cmVtb3ZlTGlzdGVuZXJzOiAoZXZlbnROYW1lKSAtPlxyXG5cclxuXHRcdHJldHVybiBAIHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0ubGVuZ3RoID0gMFxyXG5cclxuXHRcdEBcclxuXHJcblx0cmVtb3ZlQWxsTGlzdGVuZXJzOiAtPlxyXG5cclxuXHRcdGZvciBuYW1lLCBsaXN0ZW5lcnMgb2YgQF9saXN0ZW5lcnNcclxuXHJcblx0XHRcdGxpc3RlbmVycy5sZW5ndGggPSAwXHJcblxyXG5cdFx0QFxyXG5cclxuXHRfZW1pdDogKGV2ZW50TmFtZSwgZGF0YSkgLT5cclxuXHJcblx0XHRmb3IgbGlzdGVuZXIgaW4gQF9saXN0ZW5lcnNGb3JBbnlFdmVudFxyXG5cclxuXHRcdFx0bGlzdGVuZXIuY2FsbCBALCBkYXRhLCBldmVudE5hbWVcclxuXHJcblx0XHRyZXR1cm4gdW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0Zm9yIGxpc3RlbmVyIGluIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV1cclxuXHJcblx0XHRcdGxpc3RlbmVyLmNhbGwgQCwgZGF0YVxyXG5cclxuXHRcdHJldHVyblxyXG5cclxuXHQjIHRoaXMgbWFrZXMgc3VyZSB0aGF0IGFsbCB0aGUgY2FsbHMgdG8gdGhpcyBjbGFzcydzIG1ldGhvZCAnZm5OYW1lJ1xyXG5cdCMgYXJlIHRocm90dGxlZFxyXG5cdF90aHJvdHRsZUVtaXR0ZXJNZXRob2Q6IChmbk5hbWUsIHRpbWUgPSAxMDAwKSAtPlxyXG5cclxuXHRcdG9yaWdpbmFsRm4gPSBAW2ZuTmFtZV1cclxuXHJcblx0XHRpZiB0eXBlb2Ygb3JpZ2luYWxGbiBpc250ICdmdW5jdGlvbidcclxuXHJcblx0XHRcdHRocm93IEVycm9yIFwidGhpcyBjbGFzcyBkb2VzIG5vdCBoYXZlIGEgbWV0aG9kIGNhbGxlZCAnI3tmbk5hbWV9J1wiXHJcblxyXG5cdFx0bGFzdENhbGxBcmdzID0gbnVsbFxyXG5cdFx0cGVuZGluZyA9IG5vXHJcblx0XHR0aW1lciA9IG51bGxcclxuXHJcblx0XHRAW2ZuTmFtZV0gPSA9PlxyXG5cclxuXHRcdFx0bGFzdENhbGxBcmdzID0gYXJndW1lbnRzXHJcblxyXG5cdFx0XHRkbyBwZW5kXHJcblxyXG5cdFx0cGVuZCA9ID0+XHJcblxyXG5cdFx0XHRpZiBwZW5kaW5nXHJcblxyXG5cdFx0XHRcdGNsZWFyVGltZW91dCB0aW1lclxyXG5cclxuXHRcdFx0dGltZXIgPSBzZXRUaW1lb3V0IHJ1bkl0LCB0aW1lXHJcblxyXG5cdFx0XHRwZW5kaW5nID0geWVzXHJcblxyXG5cdFx0cnVuSXQgPSA9PlxyXG5cclxuXHRcdFx0cGVuZGluZyA9IG5vXHJcblxyXG5cdFx0XHRvcmlnaW5hbEZuLmFwcGx5IEAsIGxhc3RDYWxsQXJnc1xyXG5cclxuXHRfZGlzYWJsZUVtaXR0ZXI6IChmbk5hbWUpIC0+XHJcblxyXG5cdFx0aWYgQF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV0/XHJcblxyXG5cdFx0XHR0aHJvdyBFcnJvciBcIiN7Zm5OYW1lfSBpcyBhbHJlYWR5IGEgZGlzYWJsZWQgZW1pdHRlclwiXHJcblxyXG5cdFx0QF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV0gPSBAW2ZuTmFtZV1cclxuXHJcblx0XHRAW2ZuTmFtZV0gPSAtPlxyXG5cclxuXHRfZW5hYmxlRW1pdHRlcjogKGZuTmFtZSkgLT5cclxuXHJcblx0XHRmbiA9IEBfZGlzYWJsZWRFbWl0dGVyc1tmbk5hbWVdXHJcblxyXG5cdFx0dW5sZXNzIGZuP1xyXG5cclxuXHRcdFx0dGhyb3cgRXJyb3IgXCIje2ZuTmFtZX0gaXMgbm90IGEgZGlzYWJsZWQgZW1pdHRlclwiXHJcblxyXG5cdFx0QFtmbk5hbWVdID0gZm5cclxuXHJcblx0XHRkZWxldGUgQF9kaXNhYmxlZEVtaXR0ZXJzW2ZuTmFtZV0iLCJfY29tbW9uID0gcmVxdWlyZSAnLi9fY29tbW9uJ1xuXG5tb2R1bGUuZXhwb3J0cyA9IG9iamVjdCA9XG5cblx0aXNCYXJlT2JqZWN0OiBfY29tbW9uLmlzQmFyZU9iamVjdC5iaW5kIF9jb21tb25cblxuXHQjIyNcblx0aWYgb2JqZWN0IGlzIGFuIGluc3RhbmNlIG9mIGEgY2xhc3Ncblx0IyMjXG5cdGlzSW5zdGFuY2U6ICh3aGF0KSAtPlxuXG5cdFx0bm90IEBpc0JhcmVPYmplY3Qgd2hhdFxuXG5cdCMjI1xuXHRBbGlhcyB0byBfY29tbW9uLnR5cGVPZlxuXHQjIyNcblx0dHlwZU9mOiBfY29tbW9uLnR5cGVPZi5iaW5kIF9jb21tb25cblxuXHQjIyNcblx0QWxpYXMgdG8gX2NvbW1vbi5jbG9uZVxuXHQjIyNcblx0Y2xvbmU6IF9jb21tb24uY2xvbmUuYmluZCBfY29tbW9uXG5cblx0IyMjXG5cdEVtcHRpZXMgYW4gb2JqZWN0IG9mIGl0cyBwcm9wZXJ0aWVzLlxuXHQjIyNcblx0ZW1wdHk6IChvKSAtPlxuXG5cdFx0Zm9yIHByb3Agb2Ygb1xuXG5cdFx0XHRkZWxldGUgb1twcm9wXSBpZiBvLmhhc093blByb3BlcnR5IHByb3BcblxuXHRcdG9cblxuXHQjIyNcblx0RW1wdGllcyBhbiBvYmplY3QuIERvZXNuJ3QgY2hlY2sgZm9yIGhhc093blByb3BlcnR5LCBzbyBpdCdzIGEgdGlueVxuXHRiaXQgZmFzdGVyLiBVc2UgaXQgZm9yIHBsYWluIG9iamVjdHMuXG5cdCMjI1xuXHRmYXN0RW1wdHk6IChvKSAtPlxuXG5cdFx0ZGVsZXRlIG9bcHJvcGVydHldIGZvciBwcm9wZXJ0eSBvZiBvXG5cblx0XHRvXG5cblx0IyMjXG5cdE92ZXJyaWRlcyB2YWx1ZXMgZm9tciBgbmV3VmFsdWVzYCBvbiBgYmFzZWAsIGFzIGxvbmcgYXMgdGhleVxuXHRhbHJlYWR5IGV4aXN0IGluIGJhc2UuXG5cdCMjI1xuXHRvdmVycmlkZU9udG86IChiYXNlLCBuZXdWYWx1ZXMpIC0+XG5cblx0XHRyZXR1cm4gYmFzZSBpZiBub3QgQGlzQmFyZU9iamVjdChuZXdWYWx1ZXMpIG9yIG5vdCBAaXNCYXJlT2JqZWN0KGJhc2UpXG5cblx0XHRmb3Iga2V5LCBvbGRWYWwgb2YgYmFzZVxuXG5cdFx0XHRuZXdWYWwgPSBuZXdWYWx1ZXNba2V5XVxuXG5cdFx0XHRjb250aW51ZSBpZiBuZXdWYWwgaXMgdW5kZWZpbmVkXG5cblx0XHRcdGlmIHR5cGVvZiBuZXdWYWwgaXNudCAnb2JqZWN0JyBvciBAaXNJbnN0YW5jZSBuZXdWYWxcblxuXHRcdFx0XHRiYXNlW2tleV0gPSBAY2xvbmUgbmV3VmFsXG5cblx0XHRcdCMgbmV3VmFsIGlzIGEgcGxhaW4gb2JqZWN0XG5cdFx0XHRlbHNlXG5cblx0XHRcdFx0aWYgdHlwZW9mIG9sZFZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG9sZFZhbFxuXG5cdFx0XHRcdFx0YmFzZVtrZXldID0gQGNsb25lIG5ld1ZhbFxuXG5cdFx0XHRcdGVsc2VcblxuXHRcdFx0XHRcdEBvdmVycmlkZU9udG8gb2xkVmFsLCBuZXdWYWxcblx0XHRiYXNlXG5cblx0IyMjXG5cdFRha2VzIGEgY2xvbmUgb2YgJ2Jhc2UnIGFuZCBydW5zICNvdmVycmlkZU9udG8gb24gaXRcblx0IyMjXG5cdG92ZXJyaWRlOiAoYmFzZSwgbmV3VmFsdWVzKSAtPlxuXG5cdFx0QG92ZXJyaWRlT250byBAY2xvbmUoYmFzZSksIG5ld1ZhbHVlc1xuXG5cdGFwcGVuZDogKGJhc2UsIHRvQXBwZW5kKSAtPlxuXG5cdFx0QGFwcGVuZE9udG8gQGNsb25lKGJhc2UpLCB0b0FwcGVuZFxuXG5cdCMgRGVlcCBhcHBlbmRzIHZhbHVlcyBmcm9tIGB0b0FwcGVuZGAgdG8gYGJhc2VgXG5cdGFwcGVuZE9udG86IChiYXNlLCB0b0FwcGVuZCkgLT5cblxuXHRcdHJldHVybiBiYXNlIGlmIG5vdCBAaXNCYXJlT2JqZWN0KHRvQXBwZW5kKSBvciBub3QgQGlzQmFyZU9iamVjdChiYXNlKVxuXG5cdFx0Zm9yIG93biBrZXksIG5ld1ZhbCBvZiB0b0FwcGVuZFxuXG5cdFx0XHRjb250aW51ZSB1bmxlc3MgbmV3VmFsIGlzbnQgdW5kZWZpbmVkXG5cblx0XHRcdGlmIHR5cGVvZiBuZXdWYWwgaXNudCAnb2JqZWN0JyBvciBAaXNJbnN0YW5jZSBuZXdWYWxcblxuXHRcdFx0XHRiYXNlW2tleV0gPSBuZXdWYWxcblxuXHRcdFx0ZWxzZVxuXG5cdFx0XHRcdCMgbmV3VmFsIGlzIGEgYmFyZSBvYmplY3RcblxuXHRcdFx0XHRvbGRWYWwgPSBiYXNlW2tleV1cblxuXHRcdFx0XHRpZiB0eXBlb2Ygb2xkVmFsIGlzbnQgJ29iamVjdCcgb3IgQGlzSW5zdGFuY2Ugb2xkVmFsXG5cblx0XHRcdFx0XHRiYXNlW2tleV0gPSBAY2xvbmUgbmV3VmFsXG5cblx0XHRcdFx0ZWxzZVxuXG5cdFx0XHRcdFx0QGFwcGVuZE9udG8gb2xkVmFsLCBuZXdWYWxcblxuXHRcdGJhc2VcblxuXHQjIEdyb3Vwc1xuXHRncm91cFByb3BzOiAob2JqLCBncm91cHMpIC0+XG5cblx0XHRncm91cGVkID0ge31cblxuXHRcdGZvciBuYW1lLCBkZWZzIG9mIGdyb3Vwc1xuXG5cdFx0XHRncm91cGVkW25hbWVdID0ge31cblxuXHRcdGdyb3VwZWRbJ3Jlc3QnXSA9IHt9XG5cblx0XHRgdG9wOiAvL2Bcblx0XHRmb3Iga2V5LCB2YWwgb2Ygb2JqXG5cblx0XHRcdHNob3VsZEFkZCA9IG5vXG5cblx0XHRcdGZvciBuYW1lLCBkZWZzIG9mIGdyb3Vwc1xuXG5cdFx0XHRcdHVubGVzcyBBcnJheS5pc0FycmF5IGRlZnNcblxuXHRcdFx0XHRcdGRlZnMgPSBbZGVmc11cblxuXHRcdFx0XHRmb3IgZGVmIGluIGRlZnNcblxuXHRcdFx0XHRcdGlmIHR5cGVvZiBkZWYgaXMgJ3N0cmluZydcblxuXHRcdFx0XHRcdFx0aWYga2V5IGlzIGRlZlxuXG5cdFx0XHRcdFx0XHRcdHNob3VsZEFkZCA9IHllc1xuXG5cdFx0XHRcdFx0ZWxzZSBpZiBkZWYgaW5zdGFuY2VvZiBSZWdFeHBcblxuXHRcdFx0XHRcdFx0aWYgZGVmLnRlc3Qga2V5XG5cblx0XHRcdFx0XHRcdFx0c2hvdWxkQWRkID0geWVzXG5cblx0XHRcdFx0XHRlbHNlIGlmIGRlZiBpbnN0YW5jZW9mIEZ1bmN0aW9uXG5cblx0XHRcdFx0XHRcdGlmIGRlZiBrZXlcblxuXHRcdFx0XHRcdFx0XHRzaG91bGRBZGQgPSB5ZXNcblxuXHRcdFx0XHRcdGVsc2VcblxuXHRcdFx0XHRcdFx0dGhyb3cgRXJyb3IgJ0dyb3VwIGRlZmluaXRpb25zIG11c3QgZWl0aGVyXG5cdFx0XHRcdFx0XHRiZSBzdHJpbmdzLCByZWdleGVzLCBvciBmdW5jdGlvbnMuJ1xuXG5cdFx0XHRcdFx0aWYgc2hvdWxkQWRkXG5cblx0XHRcdFx0XHRcdGdyb3VwZWRbbmFtZV1ba2V5XSA9IHZhbFxuXG5cdFx0XHRcdFx0XHRgY29udGludWUgdG9wYFxuXG5cdFx0XHRncm91cGVkWydyZXN0J11ba2V5XSA9IHZhbFxuXG5cdFx0Z3JvdXBlZCIsIm1vZHVsZS5leHBvcnRzID1cclxuXHJcblx0IyBwYWRzIGEgbnVtYmVyIHdpdGggbGVhZGluZyB6ZXJvZXNcclxuXHQjXHJcblx0IyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xMDA3Mzc4OC82MDc5OTdcclxuXHRwYWQ6IChuLCB3aWR0aCwgeiA9ICcwJykgLT5cclxuXHJcblx0XHRuID0gbiArICcnXHJcblxyXG5cdFx0aWYgbi5sZW5ndGggPj0gd2lkdGhcclxuXHJcblx0XHRcdG5cclxuXHJcblx0XHRlbHNlXHJcblxyXG5cdFx0XHRuZXcgQXJyYXkod2lkdGggLSBuLmxlbmd0aCArIDEpLmpvaW4oeikgKyBuIiwibW9kdWxlLmV4cG9ydHMgPSB1dGlsYSA9XG5cblx0YXJyYXk6IHJlcXVpcmUgJy4vYXJyYXknXG5cdGNsYXNzaWM6IHJlcXVpcmUgJy4vY2xhc3NpYydcblx0b2JqZWN0OiByZXF1aXJlICcuL29iamVjdCdcblx0c3RyaW5nOiByZXF1aXJlICcuL3N0cmluZydcblx0RW1pdHRlcjogcmVxdWlyZSAnLi9FbWl0dGVyJyIsIm1vZHVsZS5leHBvcnRzID0gY29tbW9uID1cblxuXHQjIyNcblx0Q2hlY2tzIHRvIHNlZSBpZiBvIGlzIGFuIG9iamVjdCwgYW5kIGl0IGlzbid0IGFuIGluc3RhbmNlXG5cdG9mIHNvbWUgY2xhc3MuXG5cdCMjI1xuXHRpc0JhcmVPYmplY3Q6IChvKSAtPlxuXG5cdFx0aWYgbz8gYW5kIG8uY29uc3RydWN0b3IgaXMgT2JqZWN0XG5cblx0XHRcdHJldHVybiB0cnVlXG5cblx0XHRmYWxzZVxuXG5cdCMjI1xuXHRSZXR1cm5zIHR5cGUgb2YgYW4gb2JqZWN0LCBpbmNsdWRpbmc6XG5cdHVuZGVmaW5lZCwgbnVsbCwgc3RyaW5nLCBudW1iZXIsIGFycmF5LFxuXHRhcmd1bWVudHMsIGVsZW1lbnQsIHRleHRub2RlLCB3aGl0ZXNwYWNlLCBhbmQgb2JqZWN0XG5cdCMjI1xuXHR0eXBlT2Y6IChpdGVtKSAtPlxuXG5cdFx0cmV0dXJuICdudWxsJyBpZiBpdGVtIGlzIG51bGxcblxuXHRcdHJldHVybiB0eXBlb2YgaXRlbSBpZiB0eXBlb2YgaXRlbSBpc250ICdvYmplY3QnXG5cblx0XHRyZXR1cm4gJ2FycmF5JyBpZiBBcnJheS5pc0FycmF5IGl0ZW1cblxuXHRcdCMgRnJvbSBNb29Ub29sc1xuXHRcdCMgLSBkbyB3ZSBldmVuIG5lZWQgdGhpcz9cblx0XHRpZiBpdGVtLm5vZGVOYW1lXG5cblx0XHRcdGlmIGl0ZW0ubm9kZVR5cGUgaXMgMSB0aGVuIHJldHVybiAnZWxlbWVudCdcblx0XHRcdGlmIGl0ZW0ubm9kZVR5cGUgaXMgMyB0aGVuIHJldHVybiAoL1xcUy8pLnRlc3QoaXRlbS5ub2RlVmFsdWUpID8gJ3RleHRub2RlJyA6ICd3aGl0ZXNwYWNlJ1xuXG5cdFx0ZWxzZSBpZiB0eXBlb2YgaXRlbS5sZW5ndGggaXMgJ251bWJlcidcblxuXHRcdFx0aWYgaXRlbS5jYWxsZWUgdGhlbiByZXR1cm4gJ2FyZ3VtZW50cydcblxuXHRcdHJldHVybiB0eXBlb2YgaXRlbVxuXG5cdCMgRGVlcCBjbG9uZSBvZiBhbnkgdmFyaWFibGUuXG5cdCMgRnJvbSBNb29Ub29sc1xuXHRjbG9uZTogKGl0ZW0sIGluY2x1ZGVQcm90b3R5cGUgPSBmYWxzZSkgLT5cblxuXHRcdHN3aXRjaCBjb21tb24udHlwZU9mIGl0ZW1cblxuXHRcdFx0d2hlbiAnYXJyYXknIHRoZW4gcmV0dXJuIGNvbW1vbi5fY2xvbmVBcnJheSBpdGVtLCBpbmNsdWRlUHJvdG90eXBlXG5cblx0XHRcdHdoZW4gJ29iamVjdCcgdGhlbiByZXR1cm4gY29tbW9uLl9jbG9uZU9iamVjdCBpdGVtLCBpbmNsdWRlUHJvdG90eXBlXG5cblx0XHRcdGVsc2UgcmV0dXJuIGl0ZW1cblxuXHQjIyNcblx0RGVlcCBjbG9uZSBvZiBhbiBvYmplY3QuXG5cdEZyb20gTW9vVG9vbHNcblx0IyMjXG5cdF9jbG9uZU9iamVjdDogKG8sIGluY2x1ZGVQcm90b3R5cGUgPSBmYWxzZSkgLT5cblxuXHRcdGlmIGNvbW1vbi5pc0JhcmVPYmplY3Qgb1xuXG5cdFx0XHRjbG9uZSA9IHt9XG5cblx0XHRcdGZvciBrZXkgb2Ygb1xuXG5cdFx0XHRcdGNsb25lW2tleV0gPSBjb21tb24uY2xvbmUgb1trZXldLCBpbmNsdWRlUHJvdG90eXBlXG5cblx0XHRcdHJldHVybiBjbG9uZVxuXG5cdFx0ZWxzZVxuXG5cdFx0XHRyZXR1cm4gbyB1bmxlc3MgaW5jbHVkZVByb3RvdHlwZVxuXG5cdFx0XHRyZXR1cm4gbyBpZiBvIGluc3RhbmNlb2YgRnVuY3Rpb25cblxuXHRcdFx0Y2xvbmUgPSBPYmplY3QuY3JlYXRlIG8uY29uc3RydWN0b3IucHJvdG90eXBlXG5cblx0XHRcdGZvciBrZXkgb2Ygb1xuXG5cdFx0XHRcdGlmIG8uaGFzT3duUHJvcGVydHkga2V5XG5cblx0XHRcdFx0XHRjbG9uZVtrZXldID0gY29tbW9uLmNsb25lIG9ba2V5XSwgaW5jbHVkZVByb3RvdHlwZVxuXG5cdFx0XHRjbG9uZVxuXG5cdCMjI1xuXHREZWVwIGNsb25lIG9mIGFuIGFycmF5LlxuXHRGcm9tIE1vb1Rvb2xzXG5cdCMjI1xuXHRfY2xvbmVBcnJheTogKGEsIGluY2x1ZGVQcm90b3R5cGUgPSBmYWxzZSkgLT5cblxuXHRcdGkgPSBhLmxlbmd0aFxuXG5cdFx0Y2xvbmUgPSBuZXcgQXJyYXkgaVxuXG5cdFx0d2hpbGUgaS0tXG5cblx0XHRcdGNsb25lW2ldID0gY29tbW9uLmNsb25lIGFbaV0sIGluY2x1ZGVQcm90b3R5cGVcblxuXHRcdGNsb25lIiwicmVxdWlyZSAnLi9fcHJlcGFyZSdcblxuYXJyYXkgPSBtb2QgJ2FycmF5J1xuXG50ZXN0ICdmcm9tJywgLT5cblxuXHRhcnJheS5mcm9tKFsxXSkuc2hvdWxkLmJlLmFuLmluc3RhbmNlT2YgQXJyYXlcblx0YXJyYXkuZnJvbShbMV0pWzBdLnNob3VsZC5lcXVhbCAxXG5cbiMgdGVzdCAnY2xvbmUnLCAtPlxuXG4jIFx0YSA9IFswLCAxLCAyXVxuXG4jIFx0YiA9IGFycmF5LmNsb25lIGFcblxuIyBcdGJbMF0uc2hvdWxkLmVxdWFsIDBcbiMgXHRiWzFdLnNob3VsZC5lcXVhbCAxXG5cbiMgXHRiWzBdID0gM1xuXG4jIFx0YVswXS5zaG91bGQuZXF1YWwgMFxuXG50ZXN0ICdwbHVjaycsIC0+XG5cblx0YSA9IFswLCAxLCAyLCAzXVxuXG5cdGFmdGVyID0gYXJyYXkucGx1Y2sgYSwgMVxuXG5cdGFmdGVyLmxlbmd0aC5zaG91bGQuZXF1YWwgM1xuXG5cdGFmdGVyWzBdLnNob3VsZC5lcXVhbCAwXG5cdGFmdGVyWzFdLnNob3VsZC5lcXVhbCAyXG5cdGFmdGVyWzJdLnNob3VsZC5lcXVhbCAzXG5cdGFmdGVyLnNob3VsZC5lcXVhbCBhXG5cbnRlc3QgJ3BsdWNrTXVsdGlwbGUnLCAtPlxuXG5cdGEgPSBbMCwgMSwgMiwgMywgNCwgNSwgNl1cblxuXHRhcnJheS5wbHVja011bHRpcGxlIGEsIFswLCA0LCAyLCA2XVxuXG5cdGEubGVuZ3RoLnNob3VsZC5lcXVhbCAzXG5cdGFbMF0uc2hvdWxkLmVxdWFsIDFcblx0YVsxXS5zaG91bGQuZXF1YWwgM1xuXHRhWzJdLnNob3VsZC5lcXVhbCA1XG5cbnRlc3QgJ3BsdWNrSXRlbScsIC0+XG5cblx0YSA9IFswLCAxLCAyLCAzLCAyLCA0LCAyXVxuXG5cdGFycmF5LnBsdWNrSXRlbSBhLCAyXG5cblx0YVswXS5zaG91bGQuZXF1YWwgMFxuXHRhWzFdLnNob3VsZC5lcXVhbCAxXG5cdGFbMl0uc2hvdWxkLmVxdWFsIDNcblx0YVszXS5zaG91bGQuZXF1YWwgNFxuXG5cdGFycmF5LnBsdWNrSXRlbShbMV0sIDIpLmxlbmd0aC5zaG91bGQuZXF1YWwgMVxuXG5cbnRlc3QgJ3BsdWNrT25lSXRlbScsIC0+XG5cblx0YSA9IFswLCAxLCAyLCAzLCAyLCA0LCAyXVxuXG5cdGFycmF5LnBsdWNrT25lSXRlbSBhLCAyXG5cblx0YVswXS5zaG91bGQuZXF1YWwgMFxuXHRhWzFdLnNob3VsZC5lcXVhbCAxXG5cdGFbMl0uc2hvdWxkLmVxdWFsIDNcblx0YVszXS5zaG91bGQuZXF1YWwgMlxuXHRhWzRdLnNob3VsZC5lcXVhbCA0XG5cdGFbNV0uc2hvdWxkLmVxdWFsIDJcblxuXHRhID0gWzEsIDJdXG5cblx0YXJyYXkucGx1Y2tPbmVJdGVtIGEsIDFcblxuXHRhLmxlbmd0aC5zaG91bGQuZXF1YWwgMVxuXHRhWzBdLnNob3VsZC5lcXVhbCAyXG5cblx0YXJyYXkucGx1Y2tPbmVJdGVtKFtdLCAxKS5sZW5ndGguc2hvdWxkLmVxdWFsIDBcblxuXHRhcnJheS5wbHVja09uZUl0ZW0oWzFdLCAyKS5sZW5ndGguc2hvdWxkLmVxdWFsIDFcblxudGVzdCAncGxjdWtCeUNhbGxiYWNrJywgLT5cblxuXHRhID0gWzAsIDEsIDIsIDNdXG5cblx0YXJyYXkucGx1Y2tCeUNhbGxiYWNrIGEsICh2YWwsIGkpIC0+XG5cblx0XHRyZXR1cm4geWVzIGlmIHZhbCBpcyAyXG5cblx0XHRyZXR1cm4gbm9cblxuXHRhWzBdLnNob3VsZC5lcXVhbCAwXG5cdGFbMV0uc2hvdWxkLmVxdWFsIDFcblx0YVsyXS5zaG91bGQuZXF1YWwgM1xuXG50ZXN0ICdpbmplY3RCeUNhbGxiYWNrJywgLT5cblxuXHRzaG91bGRJbmplY3QgPSAodmFsQSwgdmFsQiwgdG9JbmplY3QpIC0+XG5cblx0XHR1bmxlc3MgdmFsQT9cblxuXHRcdFx0cmV0dXJuIHllcyBpZiB0b0luamVjdCA8PSB2YWxCXG5cblx0XHRcdHJldHVybiBub1xuXG5cdFx0dW5sZXNzIHZhbEI/XG5cblx0XHRcdHJldHVybiB5ZXMgaWYgdmFsQSA8PSB0b0luamVjdFxuXG5cdFx0XHRyZXR1cm4gbm9cblxuXHRcdHJldHVybiB5ZXMgaWYgdmFsQSA8PSB0b0luamVjdCA8PSB2YWxCXG5cblx0XHRyZXR1cm4gbm9cblxuXHRhID0gWzAuNSwgMSwgMi41LCAyLjUsIDIuNzUsIDIuNzUsIDNdXG5cblx0YXJyYXkuaW5qZWN0QnlDYWxsYmFjayBhLCAwLCBzaG91bGRJbmplY3RcblxuXHRhWzBdLnNob3VsZC5lcXVhbCAwXG5cdGFbMV0uc2hvdWxkLmVxdWFsIDAuNVxuXHRhWzddLnNob3VsZC5lcXVhbCAzXG5cblx0YSA9IFswLjUsIDEsIDIuNSwgMi41LCAyLjc1LCAyLjc1LCAzXVxuXG5cdGFycmF5LmluamVjdEJ5Q2FsbGJhY2sgYSwgMi43LCBzaG91bGRJbmplY3RcblxuXHRhWzBdLnNob3VsZC5lcXVhbCAwLjVcblx0YVs0XS5zaG91bGQuZXF1YWwgMi43XG5cdGFbNV0uc2hvdWxkLmVxdWFsIDIuNzVcblx0YVs3XS5zaG91bGQuZXF1YWwgM1xuXG5cdGEgPSBbMC41LCAxLCAyLjUsIDIuNSwgMi43NSwgMi43NSwgM11cblxuXHRhcnJheS5pbmplY3RCeUNhbGxiYWNrIGEsIDMuMiwgc2hvdWxkSW5qZWN0XG5cblx0YVswXS5zaG91bGQuZXF1YWwgMC41XG5cdGFbNF0uc2hvdWxkLmVxdWFsIDIuNzVcblx0YVs2XS5zaG91bGQuZXF1YWwgM1xuXHRhWzddLnNob3VsZC5lcXVhbCAzLjIiXX0= \ No newline at end of file
diff --git a/node_modules/utila/scripts/js/test/object.js b/node_modules/utila/scripts/js/test/object.js
new file mode 100644
index 000000000..a430c616d
--- /dev/null
+++ b/node_modules/utila/scripts/js/test/object.js
@@ -0,0 +1,220 @@
+var object;
+
+require('./_prepare');
+
+object = mod('object');
+
+test('isBareObject', function() {
+ object.isBareObject('a').should.equal(false);
+ return object.isBareObject({
+ 'a': 'a'
+ }).should.equal(true);
+});
+
+test('typeOf', function() {
+ object.typeOf('s').should.equal('string');
+ object.typeOf(0).should.equal('number');
+ object.typeOf(false).should.equal('boolean');
+ object.typeOf({}).should.equal('object');
+ object.typeOf(arguments).should.equal('arguments');
+ return object.typeOf([]).should.equal('array');
+});
+
+test('empty', function() {
+ var o;
+ o = {
+ a: 1,
+ b: 2
+ };
+ object.empty(o);
+ o.should.not.have.property('a');
+ return o.should.not.have.property('b');
+});
+
+test('fastEmpty', function() {
+ var o;
+ o = {
+ a: 1,
+ b: 2
+ };
+ object.fastEmpty(o);
+ o.should.not.have.property('a');
+ return o.should.not.have.property('b');
+});
+
+test('clone', function() {
+ var o;
+ object.clone([1])[0].should.equal(1);
+ object.clone({
+ a: 1
+ }).a.should.equal(1);
+ o = {
+ a: 1
+ };
+ return object.clone(o).should.not.equal(o);
+});
+
+test('clone [include prototype]', function() {
+ var C, a, b;
+ C = (function() {
+ function C(a) {
+ this.a = a;
+ }
+
+ C.prototype.sayA = function() {
+ return this.a + 'a';
+ };
+
+ return C;
+
+ })();
+ a = new C('a');
+ a.sayA().should.equal('aa');
+ b = object.clone(a, true);
+ b.should.not.equal(a);
+ b.constructor.should.equal(C);
+ b.a.should.equal('a');
+ b.a = 'a2';
+ return b.sayA().should.equal('a2a');
+});
+
+test('clone [without prototype]', function() {
+ var C, a, b;
+ C = (function() {
+ function C(a) {
+ this.a = a;
+ }
+
+ C.prototype.sayA = function() {
+ return this.a + 'a';
+ };
+
+ return C;
+
+ })();
+ a = new C('a');
+ a.sayA().should.equal('aa');
+ b = object.clone(a, false);
+ return b.should.equal(a);
+});
+
+test('overrideOnto [basic]', function() {
+ var onto, what;
+ onto = {
+ a: 'a',
+ b: {
+ c: 'c',
+ d: {
+ e: 'e'
+ }
+ }
+ };
+ what = {
+ a: 'a2',
+ b: {
+ c: 'c2',
+ d: {
+ f: 'f2'
+ }
+ }
+ };
+ object.overrideOnto(onto, what);
+ onto.a.should.equal('a2');
+ onto.b.should.have.property('c');
+ onto.b.c.should.equal('c2');
+ onto.b.d.should.not.have.property('f');
+ return onto.b.d.e.should.equal('e');
+});
+
+test('override', function() {
+ var onto, onto2, what;
+ onto = {
+ a: 'a',
+ b: {
+ c: 'c',
+ d: {
+ e: 'e'
+ }
+ }
+ };
+ what = {
+ a: 'a2',
+ b: {
+ c: 'c2',
+ d: {
+ f: 'f2'
+ }
+ }
+ };
+ onto2 = object.override(onto, what);
+ onto2.a.should.equal('a2');
+ onto2.b.should.have.property('c');
+ onto2.b.c.should.equal('c2');
+ onto2.b.d.should.not.have.property('f');
+ onto2.b.d.e.should.equal('e');
+ return onto.should.not.equal(onto2);
+});
+
+(function() {
+ var onto, what;
+ what = {
+ a: 'a2',
+ c: function() {},
+ z: 'z',
+ y: {
+ a: 'a'
+ }
+ };
+ onto = {
+ a: 'a',
+ b: 'b'
+ };
+ test('appendOnto [basic]', function() {
+ object.appendOnto(onto, what);
+ onto.a.should.equal('a2');
+ onto.b.should.equal('b');
+ return onto.z.should.equal('z');
+ });
+ test("appendOnto [shallow copies instances]", function() {
+ onto.c.should.be["instanceof"](Function);
+ return onto.c.should.equal(what.c);
+ });
+ return test("appendOnto [clones objects]", function() {
+ onto.should.have.property('y');
+ onto.y.a.should.equal('a');
+ return onto.y.should.not.equal(what.y);
+ });
+})();
+
+test('groupProps', function() {
+ var groups, obj;
+ obj = {
+ a1: '1',
+ a2: '2',
+ b1: '1',
+ b2: '2',
+ c1: '1',
+ c2: '2',
+ rest1: '1',
+ rest2: '2'
+ };
+ groups = object.groupProps(obj, {
+ a: ['a1', 'a2'],
+ b: [/^b[0-9]+$/],
+ c: function(key) {
+ return key[0] === 'c';
+ }
+ });
+ groups.a.should.have.property('a1');
+ groups.a.a1.should.equal('1');
+ groups.a.should.have.property('a2');
+ groups.b.should.have.property('b1');
+ groups.b.should.have.property('b2');
+ groups.c.should.have.property('c1');
+ groups.c.should.have.property('c2');
+ groups.rest.should.have.property('rest1');
+ groups.rest.should.have.property('rest1');
+ return groups.rest.should.not.have.property('c1');
+});
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0LmpzIiwic291cmNlUm9vdCI6Ii4uXFwuLiIsInNvdXJjZXMiOlsiY29mZmVlXFx0ZXN0XFxvYmplY3QuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLElBQUEsTUFBQTs7QVFBQSxPUUFBLENRQVEsWVFBUixDQUFBLENBQUE7O0FRRUEsTVFBQSxHUUFTLEdRQUEsQ1FBSSxRUUFKLENBRlQsQ0FBQTs7QVFJQSxJUUFBLENRQUssY1FBTCxFUUFxQixTUUFBLEdRQUE7QVFFcEIsRVFBQSxNUUFNLENRQUMsWVFBUCxDUUFvQixHUUFwQixDUUF3QixDUUFDLE1RQU0sQ1FBQyxLUUFoQyxDUUFzQyxLUUF0QyxDUUFBLENRQUE7U1FFQSxNUUFNLENRQUMsWVFBUCxDUUFvQjtBUUFBLElRQUMsR1FBQSxFUUFLLEdRQU47R1FBcEIsQ1FBK0IsQ1FBQyxNUUFNLENRQUMsS1FBdkMsQ1FBNkMsSVFBN0MsRVFKb0I7QVFBQSxDUUFyQixDQUpBLENBQUE7O0FRVUEsSVFBQSxDUUFLLFFRQUwsRVFBZSxTUUFBLEdRQUE7QVFFZCxFUUFBLE1RQU0sQ1FBQyxNUUFQLENRQWMsR1FBZCxDUUFrQixDUUFDLE1RQU0sQ1FBQyxLUUExQixDUUFnQyxRUUFoQyxDUUFBLENRQUE7QVFBQSxFUUNBLE1RQU0sQ1FBQyxNUUFQLENRQWMsQ1FBZCxDUUFnQixDUUFDLE1RQU0sQ1FBQyxLUUF4QixDUUE4QixRUUE5QixDUURBLENRQUE7QVFBQSxFUUVBLE1RQU0sQ1FBQyxNUUFQLENRQWMsS1FBZCxDUUFvQixDUUFDLE1RQU0sQ1FBQyxLUUE1QixDUUFrQyxTUUFsQyxDUUZBLENRQUE7QVFBQSxFUUdBLE1RQU0sQ1FBQyxNUUFQLENRQWMsRVFBZCxDUUFpQixDUUFDLE1RQU0sQ1FBQyxLUUF6QixDUUErQixRUUEvQixDUUhBLENRQUE7QVFBQSxFUUlBLE1RQU0sQ1FBQyxNUUFQLENRQWMsU1FBZCxDUUF3QixDUUFDLE1RQU0sQ1FBQyxLUUFoQyxDUUFzQyxXUUF0QyxDUUpBLENRQUE7U1FLQSxNUUFNLENRQUMsTVFBUCxDUUFjLEVRQWQsQ1FBaUIsQ1FBQyxNUUFNLENRQUMsS1FBekIsQ1FBK0IsT1FBL0IsRVFQYztBUUFBLENRQWYsQ0FWQSxDQUFBOztBUW1CQSxJUUFBLENRQUssT1FBTCxFUUFjLFNRQUEsR1FBQTtBUUViLE1RQUEsQ1FBQTtBUUFBLEVRQUEsQ1FBQSxHUUVDO0FRQUEsSVFBQSxDUUFBLEVRQUcsQ1FBSDtBUUFBLElRQ0EsQ1FBQSxFUUFHLENRREg7R1FGRCxDUUFBO0FRQUEsRVFNQSxNUUFNLENRQUMsS1FBUCxDUUFhLENRQWIsQ1FOQSxDUUFBO0FRQUEsRVFRQSxDUUFDLENRQUMsTVFBTSxDUUFDLEdRQUcsQ1FBQyxJUUFJLENRQUMsUVFBbEIsQ1FBMkIsR1FBM0IsQ1FSQSxDUUFBO1NRU0EsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxHUUFHLENRQUMsSVFBSSxDUUFDLFFRQWxCLENRQTJCLEdRQTNCLEVRWGE7QVFBQSxDUUFkLENBbkJBLENBQUE7O0FRZ0NBLElRQUEsQ1FBSyxXUUFMLEVRQWtCLFNRQUEsR1FBQTtBUUVqQixNUUFBLENRQUE7QVFBQSxFUUFBLENRQUEsR1FDQztBUUFBLElRQUEsQ1FBQSxFUUFHLENRQUg7QVFBQSxJUUNBLENRQUEsRVFBRyxDUURIO0dRREQsQ1FBQTtBUUFBLEVRS0EsTVFBTSxDUUFDLFNRQVAsQ1FBaUIsQ1FBakIsQ1FMQSxDUUFBO0FRQUEsRVFPQSxDUUFDLENRQUMsTVFBTSxDUUFDLEdRQUcsQ1FBQyxJUUFJLENRQUMsUVFBbEIsQ1FBMkIsR1FBM0IsQ1FQQSxDUUFBO1NRUUEsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxHUUFHLENRQUMsSVFBSSxDUUFDLFFRQWxCLENRQTJCLEdRQTNCLEVRVmlCO0FRQUEsQ1FBbEIsQ0FoQ0EsQ0FBQTs7QVE0Q0EsSVFBQSxDUUFLLE9RQUwsRVFBYyxTUUFBLEdRQUE7QVFFYixNUUFBLENRQUE7QVFBQSxFUUFBLE1RQU0sQ1FBQyxLUUFQLENRQWEsQ1FBQyxDUUFELENRQWIsQ1FBa0IsQ1FBQSxDUUFBLENRQUUsQ1FBQyxNUUFNLENRQUMsS1FBNUIsQ1FBa0MsQ1FBbEMsQ1FBQSxDUUFBO0FRQUEsRVFDQSxNUUFNLENRQUMsS1FBUCxDUUFhO0FRQUEsSVFBQyxDUUFBLEVRQUUsQ1FBSDtHUUFiLENRQW1CLENRQUMsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxLUUE3QixDUUFtQyxDUUFuQyxDUURBLENRQUE7QVFBQSxFUUdBLENRQUEsR1FBSTtBUUFBLElRQUMsQ1FBQSxFUUFHLENRQUo7R1FISixDUUFBO1NRS0EsTVFBTSxDUUFDLEtRQVAsQ1FBYSxDUUFiLENRQWUsQ1FBQyxNUUFNLENRQUMsR1FBRyxDUUFDLEtRQTNCLENRQWlDLENRQWpDLEVRUGE7QVFBQSxDUUFkLENBNUNBLENBQUE7O0FRcURBLElRQUEsQ1FBSywyQlFBTCxFUUFrQyxTUUFBLEdRQUE7QVFFakMsTVFBQSxPUUFBO0FRQUEsRVFBTTtBUUVRLElRQUEsV1FBRSxDUUFGLEdRQUE7QVFBTSxNUUFMLElRQUMsQ1FBQSxJUUFBLENRQUksQ1FBTjtJUUFBLENRQWI7O0FRQUEsZ0JRRUEsSVFBQSxHUUFNLFNRQUEsR1FBQTthUUFHLElRQUMsQ1FBQSxDUUFELEdRQUssSVFBUjtJUUFBLENRRk4sQ1FBQTs7YVFBQTs7TVFGRCxDUUFBO0FRQUEsRVFNQSxDUUFBLEdRQVEsSVFBQSxDUUFBLENRQUUsR1FBRixDUU5SLENRQUE7QVFBQSxFUVFBLENRQUMsQ1FBQyxJUUFGLENRQUEsQ1FBUSxDUUFDLE1RQU0sQ1FBQyxLUUFoQixDUUFzQixJUUF0QixDUVJBLENRQUE7QVFBQSxFUVVBLENRQUEsR1FBSSxNUUFNLENRQUMsS1FBUCxDUUFhLENRQWIsRVFBZ0IsSVFBaEIsQ1FWSixDUUFBO0FRQUEsRVFZQSxDUUFDLENRQUMsTVFBTSxDUUFDLEdRQUcsQ1FBQyxLUUFiLENRQW1CLENRQW5CLENRWkEsQ1FBQTtBUUFBLEVRY0EsQ1FBQyxDUUFDLFdRQVcsQ1FBQyxNUUFNLENRQUMsS1FBckIsQ1FBMkIsQ1FBM0IsQ1FkQSxDUUFBO0FRQUEsRVFnQkEsQ1FBQyxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsS1FBWCxDUUFpQixHUUFqQixDUWhCQSxDUUFBO0FRQUEsRVFrQkEsQ1FBQyxDUUFDLENRQUYsR1FBTSxJUWxCTixDUUFBO1NRb0JBLENRQUMsQ1FBQyxJUUFGLENRQUEsQ1FBUSxDUUFDLE1RQU0sQ1FBQyxLUUFoQixDUUFzQixLUUF0QixFUXRCaUM7QVFBQSxDUUFsQyxDQXJEQSxDQUFBOztBUTZFQSxJUUFBLENRQUssMkJRQUwsRVFBa0MsU1FBQSxHUUFBO0FRRWpDLE1RQUEsT1FBQTtBUUFBLEVRQU07QVFFUSxJUUFBLFdRQUUsQ1FBRixHUUFBO0FRQU0sTVFBTCxJUUFDLENRQUEsSVFBQSxDUUFJLENRQU47SVFBQSxDUUFiOztBUUFBLGdCUUVBLElRQUEsR1FBTSxTUUFBLEdRQUE7YVFBRyxJUUFDLENRQUEsQ1FBRCxHUUFLLElRQVI7SVFBQSxDUUZOLENRQUE7O2FRQUE7O01RRkQsQ1FBQTtBUUFBLEVRTUEsQ1FBQSxHUUFRLElRQUEsQ1FBQSxDUUFFLEdRQUYsQ1FOUixDUUFBO0FRQUEsRVFRQSxDUUFDLENRQUMsSVFBRixDUUFBLENRQVEsQ1FBQyxNUUFNLENRQUMsS1FBaEIsQ1FBc0IsSVFBdEIsQ1FSQSxDUUFBO0FRQUEsRVFVQSxDUUFBLEdRQUksTVFBTSxDUUFDLEtRQVAsQ1FBYSxDUUFiLEVRQWdCLEtRQWhCLENRVkosQ1FBQTtTUVlBLENRQUMsQ1FBQyxNUUFNLENRQUMsS1FBVCxDUUFlLENRQWYsRVFkaUM7QVFBQSxDUUFsQyxDQTdFQSxDQUFBOztBUTZGQSxJUUFBLENRQUssc0JRQUwsRVFBNkIsU1FBQSxHUUFBO0FRRTVCLE1RQUEsVVFBQTtBUUFBLEVRQUEsSVFBQSxHUUNDO0FRQUEsSVFBQSxDUUFBLEVRQUcsR1FBSDtBUUFBLElRQ0EsQ1FBQSxFUUNDO0FRQUEsTVFBQSxDUUFBLEVRQUcsR1FBSDtBUUFBLE1RQ0EsQ1FBQSxFUUNDO0FRQUEsUVFBQSxDUUFBLEVRQUcsR1FBSDtPUUZEO0tRRkQ7R1FERCxDUUFBO0FRQUEsRVFPQSxJUUFBLEdRQ0M7QVFBQSxJUUFBLENRQUEsRVFBRyxJUUFIO0FRQUEsSVFDQSxDUUFBLEVRQ0M7QVFBQSxNUUFBLENRQUEsRVFBRyxJUUFIO0FRQUEsTVFDQSxDUUFBLEVRQ0M7QVFBQSxRUUFBLENRQUEsRVFBRyxJUUFIO09RRkQ7S1FGRDtHUVJELENRQUE7QVFBQSxFUWNBLE1RQU0sQ1FBQyxZUUFQLENRQW9CLElRQXBCLEVRQTBCLElRQTFCLENRZEEsQ1FBQTtBUUFBLEVRZ0JBLElRQUksQ1FBQyxDUUFDLENRQUMsTVFBTSxDUUFDLEtRQWQsQ1FBb0IsSVFBcEIsQ1FoQkEsQ1FBQTtBUUFBLEVRaUJBLElRQUksQ1FBQyxDUUFDLENRQUMsTVFBTSxDUUFDLElRQUksQ1FBQyxRUUFuQixDUUE0QixHUUE1QixDUWpCQSxDUUFBO0FRQUEsRVFrQkEsSVFBSSxDUUFDLENRQUMsQ1FBQyxDUUFDLENRQUMsTVFBTSxDUUFDLEtRQWhCLENRQXNCLElRQXRCLENRbEJBLENRQUE7QVFBQSxFUW1CQSxJUUFJLENRQUMsQ1FBQyxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsR1FBRyxDUUFDLElRQUksQ1FBQyxRUUF6QixDUUFrQyxHUUFsQyxDUW5CQSxDUUFBO1NRb0JBLElRQUksQ1FBQyxDUUFDLENRQUMsQ1FBQyxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsS1FBbEIsQ1FBd0IsR1FBeEIsRVF0QjRCO0FRQUEsQ1FBN0IsQ0E3RkEsQ0FBQTs7QVFxSEEsSVFBQSxDUUFLLFVRQUwsRVFBaUIsU1FBQSxHUUFBO0FRRWhCLE1RQUEsaUJRQUE7QVFBQSxFUUFBLElRQUEsR1FFQztBUUFBLElRQUEsQ1FBQSxFUUFHLEdRQUg7QVFBQSxJUUVBLENRQUEsRVFFQztBUUFBLE1RQUEsQ1FBQSxFUUFHLEdRQUg7QVFBQSxNUUVBLENRQUEsRVFFQztBUUFBLFFRQUEsQ1FBQSxFUUFHLEdRQUg7T1FKRDtLUUpEO0dRRkQsQ1FBQTtBUUFBLEVRWUEsSVFBQSxHUUVDO0FRQUEsSVFBQSxDUUFBLEVRQUcsSVFBSDtBUUFBLElRRUEsQ1FBQSxFUUVDO0FRQUEsTVFBQSxDUUFBLEVRQUcsSVFBSDtBUUFBLE1RRUEsQ1FBQSxFUUVDO0FRQUEsUVFBQSxDUUFBLEVRQUcsSVFBSDtPUUpEO0tRSkQ7R1FkRCxDUUFBO0FRQUEsRVF5QkEsS1FBQSxHUUFRLE1RQU0sQ1FBQyxRUUFQLENRQWdCLElRQWhCLEVRQXNCLElRQXRCLENRekJSLENRQUE7QVFBQSxFUTJCQSxLUUFLLENRQUMsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxLUUFmLENRQXFCLElRQXJCLENRM0JBLENRQUE7QVFBQSxFUTRCQSxLUUFLLENRQUMsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxJUUFJLENRQUMsUVFBcEIsQ1FBNkIsR1FBN0IsQ1E1QkEsQ1FBQTtBUUFBLEVRNkJBLEtRQUssQ1FBQyxDUUFDLENRQUMsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxLUUFqQixDUUF1QixJUUF2QixDUTdCQSxDUUFBO0FRQUEsRVE4QkEsS1FBSyxDUUFDLENRQUMsQ1FBQyxDUUFDLENRQUMsTVFBTSxDUUFDLEdRQUcsQ1FBQyxJUUFJLENRQUMsUVFBMUIsQ1FBbUMsR1FBbkMsQ1E5QkEsQ1FBQTtBUUFBLEVRK0JBLEtRQUssQ1FBQyxDUUFDLENRQUMsQ1FBQyxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsS1FBbkIsQ1FBeUIsR1FBekIsQ1EvQkEsQ1FBQTtTUWlDQSxJUUFJLENRQUMsTVFBTSxDUUFDLEdRQUcsQ1FBQyxLUUFoQixDUUFzQixLUUF0QixFUW5DZ0I7QVFBQSxDUUFqQixDQXJIQSxDQUFBOztBUTBKRyxDUUFBLFNRQUEsR1FBQTtBUUVGLE1RQUEsVVFBQTtBUUFBLEVRQUEsSVFBQSxHUUVDO0FRQUEsSVFBQSxDUUFBLEVRQUcsSVFBSDtBUUFBLElRRUEsQ1FBQSxFUUFHLFNRQUEsR1FBQSxDUUZIO0FRQUEsSVFJQSxDUUFBLEVRQUcsR1FKSDtBUUFBLElRTUEsQ1FBQSxFUUVDO0FRQUEsTVFBQSxDUUFBLEVRQUcsR1FBSDtLUVJEO0dRRkQsQ1FBQTtBUUFBLEVRWUEsSVFBQSxHUUVDO0FRQUEsSVFBQSxDUUFBLEVRQUcsR1FBSDtBUUFBLElRRUEsQ1FBQSxFUUFHLEdRRkg7R1FkRCxDUUFBO0FRQUEsRVFrQkEsSVFBQSxDUUFLLG9CUUFMLEVRQTJCLFNRQUEsR1FBQTtBUUUxQixJUUFBLE1RQU0sQ1FBQyxVUUFQLENRQWtCLElRQWxCLEVRQXdCLElRQXhCLENRQUEsQ1FBQTtBUUFBLElRRUEsSVFBSSxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsS1FBZCxDUUFvQixJUUFwQixDUUZBLENRQUE7QVFBQSxJUUdBLElRQUksQ1FBQyxDUUFDLENRQUMsTVFBTSxDUUFDLEtRQWQsQ1FBb0IsR1FBcEIsQ1FIQSxDUUFBO1dRSUEsSVFBSSxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsS1FBZCxDUUFvQixHUUFwQixFUU4wQjtFUUFBLENRQTNCLENRbEJBLENRQUE7QVFBQSxFUTBCQSxJUUFBLENRQUssdUNRQUwsRVFBOEMsU1FBQSxHUUFBO0FRRTdDLElRQUEsSVFBSSxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsRVFBRSxDUUFDLFlRQUQsQ1FBaEIsQ1FBNEIsUVFBNUIsQ1FBQSxDUUFBO1dRQ0EsSVFBSSxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsS1FBZCxDUUFvQixJUUFJLENRQUMsQ1FBekIsRVFINkM7RVFBQSxDUUE5QyxDUTFCQSxDUUFBO1NRZ0NBLElRQUEsQ1FBSyw2QlFBTCxFUUFvQyxTUUFBLEdRQUE7QVFFbkMsSVFBQSxJUUFJLENRQUMsTVFBTSxDUUFDLElRQUksQ1FBQyxRUUFqQixDUUEwQixHUUExQixDUUFBLENRQUE7QVFBQSxJUUNBLElRQUksQ1FBQyxDUUFDLENRQUMsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxLUUFoQixDUUFzQixHUUF0QixDUURBLENRQUE7V1FFQSxJUUFJLENRQUMsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxHUUFHLENRQUMsS1FBbEIsQ1FBd0IsSVFBSSxDUUFDLENRQTdCLEVRSm1DO0VRQUEsQ1FBcEMsRVFsQ0U7QVFBQSxDUUFBLENRQUgsQ1FBQSxDQTFKQSxDQUFBOztBUWtNQSxJUUFBLENRQUssWVFBTCxFUUFtQixTUUFBLEdRQUE7QVFFbEIsTVFBQSxXUUFBO0FRQUEsRVFBQSxHUUFBLEdRRUM7QVFBQSxJUUFBLEVRQUEsRVFBSSxHUUFKO0FRQUEsSVFDQSxFUUFBLEVRQUksR1FESjtBUUFBLElRR0EsRVFBQSxFUUFJLEdRSEo7QVFBQSxJUUlBLEVRQUEsRVFBSSxHUUpKO0FRQUEsSVFNQSxFUUFBLEVRQUksR1FOSjtBUUFBLElRT0EsRVFBQSxFUUFJLEdRUEo7QVFBQSxJUVNBLEtRQUEsRVFBTyxHUVRQO0FRQUEsSVFVQSxLUUFBLEVRQU8sR1FWUDtHUUZELENRQUE7QVFBQSxFUWNBLE1RQUEsR1FBUyxNUUFNLENRQUMsVVFBUCxDUUFrQixHUUFsQixFUUVSO0FRQUEsSVFBQSxDUUFBLEVRQUcsQ1FBQyxJUUFELEVRQU8sSVFBUCxDUUFIO0FRQUEsSVFFQSxDUUFBLEVRQUcsQ1FBQyxXUUFELENRRkg7QVFBQSxJUUlBLENRQUEsRVFBRyxTUUFDLEdRQUQsR1FBQTthUUFTLEdRQUksQ1FBQSxDUUFBLENRQUosS1FBVSxJUUFuQjtJUUFBLENRSkg7R1FGUSxDUWRULENRQUE7QVFBQSxFUXNCQSxNUUFNLENRQUMsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxJUUFJLENRQUMsUVFBckIsQ1FBOEIsSVFBOUIsQ1F0QkEsQ1FBQTtBUUFBLEVRdUJBLE1RQU0sQ1FBQyxDUUFDLENRQUMsRVFBRSxDUUFDLE1RQU0sQ1FBQyxLUUFuQixDUUF5QixHUUF6QixDUXZCQSxDUUFBO0FRQUEsRVF5QkEsTVFBTSxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsSVFBSSxDUUFDLFFRQXJCLENRQThCLElRQTlCLENRekJBLENRQUE7QVFBQSxFUTJCQSxNUUFNLENRQUMsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxJUUFJLENRQUMsUVFBckIsQ1FBOEIsSVFBOUIsQ1EzQkEsQ1FBQTtBUUFBLEVRNEJBLE1RQU0sQ1FBQyxDUUFDLENRQUMsTVFBTSxDUUFDLElRQUksQ1FBQyxRUUFyQixDUUE4QixJUUE5QixDUTVCQSxDUUFBO0FRQUEsRVE4QkEsTVFBTSxDUUFDLENRQUMsQ1FBQyxNUUFNLENRQUMsSVFBSSxDUUFDLFFRQXJCLENRQThCLElRQTlCLENROUJBLENRQUE7QVFBQSxFUStCQSxNUUFNLENRQUMsQ1FBQyxDUUFDLE1RQU0sQ1FBQyxJUUFJLENRQUMsUVFBckIsQ1FBOEIsSVFBOUIsQ1EvQkEsQ1FBQTtBUUFBLEVRaUNBLE1RQU0sQ1FBQyxJUUFJLENRQUMsTVFBTSxDUUFDLElRQUksQ1FBQyxRUUF4QixDUUFpQyxPUUFqQyxDUWpDQSxDUUFBO0FRQUEsRVFrQ0EsTVFBTSxDUUFDLElRQUksQ1FBQyxNUUFNLENRQUMsSVFBSSxDUUFDLFFRQXhCLENRQWlDLE9RQWpDLENRbENBLENRQUE7U1FvQ0EsTVFBTSxDUUFDLElRQUksQ1FBQyxNUUFNLENRQUMsR1FBRyxDUUFDLElRQUksQ1FBQyxRUUE1QixDUUFxQyxJUUFyQyxFUXRDa0I7QVFBQSxDUUFuQixDQWxNQSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHMgPSBhcnJheSA9XG5cblx0IyMjXG5cdFRyaWVzIHRvIHR1cm4gYW55dGhpbmcgaW50byBhbiBhcnJheS5cblx0IyMjXG5cdGZyb206IChyKSAtPlxuXG5cdFx0QXJyYXk6OnNsaWNlLmNhbGwgclxuXG5cdCMjI1xuXHRDbG9uZSBvZiBhbiBhcnJheS4gUHJvcGVydGllcyB3aWxsIGJlIHNoYWxsb3cgY29waWVzLlxuXHQjIyNcblx0c2ltcGxlQ2xvbmU6IChhKSAtPlxuXG5cdFx0YS5zbGljZSAwXG5cblx0c2hhbGxvd0VxdWFsOiAoYTEsIGEyKSAtPlxuXG5cdFx0cmV0dXJuIG5vIHVubGVzcyBBcnJheS5pc0FycmF5KGExKSBhbmQgQXJyYXkuaXNBcnJheShhMikgYW5kIGExLmxlbmd0aCBpcyBhMi5sZW5ndGhcblxuXHRcdGZvciB2YWwsIGkgaW4gYTFcblxuXHRcdFx0cmV0dXJuIG5vIHVubGVzcyBhMltpXSBpcyB2YWxcblxuXHRcdHllc1xuXG5cdHBsdWNrOiAoYSwgaSkgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgaW5kZXggPiBpXG5cblx0XHRcdFx0YVtpbmRleCAtIDFdID0gYVtpbmRleF1cblxuXHRcdGEubGVuZ3RoID0gYS5sZW5ndGggLSAxXG5cblx0XHRhXG5cblx0cGx1Y2tJdGVtOiAoYSwgaXRlbSkgLT5cblxuXHRcdHJldHVybiBhIGlmIGEubGVuZ3RoIDwgMVxuXG5cblx0XHRyZW1vdmVkID0gMFxuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIHZhbHVlIGlzIGl0ZW1cblxuXHRcdFx0XHRyZW1vdmVkKytcblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRpZiByZW1vdmVkIGlzbnQgMFxuXG5cdFx0XHRcdGFbaW5kZXggLSByZW1vdmVkXSA9IGFbaW5kZXhdXG5cblx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gcmVtb3ZlZCBpZiByZW1vdmVkID4gMFxuXG5cdFx0YVxuXG5cdHBsdWNrT25lSXRlbTogKGEsIGl0ZW0pIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXHRcdHJlYWNoZWQgPSBub1xuXG5cdFx0Zm9yIHZhbHVlLCBpbmRleCBpbiBhXG5cblx0XHRcdGlmIG5vdCByZWFjaGVkXG5cblx0XHRcdFx0aWYgdmFsdWUgaXMgaXRlbVxuXG5cdFx0XHRcdFx0cmVhY2hlZCA9IHllc1xuXG5cdFx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0ZWxzZVxuXG5cdFx0XHRcdGFbaW5kZXggLSAxXSA9IGFbaW5kZXhdXG5cblx0XHRhLmxlbmd0aCA9IGEubGVuZ3RoIC0gMSBpZiByZWFjaGVkXG5cblx0XHRhXG5cblx0cGx1Y2tCeUNhbGxiYWNrOiAoYSwgY2IpIC0+XG5cblx0XHRyZXR1cm4gYSBpZiBhLmxlbmd0aCA8IDFcblxuXHRcdHJlbW92ZWQgPSAwXG5cblx0XHRmb3IgdmFsdWUsIGluZGV4IGluIGFcblxuXHRcdFx0aWYgY2IgdmFsdWUsIGluZGV4XG5cblx0XHRcdFx0cmVtb3ZlZCsrXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0aWYgcmVtb3ZlZCBpc250IDBcblxuXHRcdFx0XHRhW2luZGV4IC0gcmVtb3ZlZF0gPSBhW2luZGV4XVxuXG5cdFx0aWYgcmVtb3ZlZCA+IDBcblxuXHRcdFx0YS5sZW5ndGggPSBhLmxlbmd0aCAtIHJlbW92ZWRcblxuXHRcdGFcblxuXHRwbHVja011bHRpcGxlOiAoYXJyYXksIGluZGV4ZXNUb1JlbW92ZSkgLT5cblxuXHRcdHJldHVybiBhcnJheSBpZiBhcnJheS5sZW5ndGggPCAxXG5cblx0XHRyZW1vdmVkU29GYXIgPSAwXG5cblx0XHRpbmRleGVzVG9SZW1vdmUuc29ydCgpXG5cblx0XHRmb3IgaSBpbiBpbmRleGVzVG9SZW1vdmVcblxuXHRcdFx0QHBsdWNrIGFycmF5LCBpIC0gcmVtb3ZlZFNvRmFyXG5cblx0XHRcdHJlbW92ZWRTb0ZhcisrXG5cblx0XHRhcnJheVxuXG5cdGluamVjdEJ5Q2FsbGJhY2s6IChhLCB0b0luamVjdCwgc2hvdWxkSW5qZWN0KSAtPlxuXG5cdFx0dmFsQSA9IG51bGxcblxuXHRcdHZhbEIgPSBudWxsXG5cblx0XHRsZW4gPSBhLmxlbmd0aFxuXG5cdFx0aWYgbGVuIDwgMVxuXG5cdFx0XHRhLnB1c2ggdG9JbmplY3RcblxuXHRcdFx0cmV0dXJuIGFcblxuXG5cdFx0Zm9yIHZhbCwgaSBpbiBhXG5cblx0XHRcdHZhbEEgPSB2YWxCXG5cblx0XHRcdHZhbEIgPSB2YWxcblxuXHRcdFx0aWYgc2hvdWxkSW5qZWN0IHZhbEEsIHZhbEIsIHRvSW5qZWN0XG5cblx0XHRcdFx0cmV0dXJuIGEuc3BsaWNlIGksIDAsIHRvSW5qZWN0XG5cblx0XHRhLnB1c2ggdG9JbmplY3RcblxuXHRcdGFcblxuXHRpbmplY3RJbkluZGV4OiAoYSwgaW5kZXgsIHRvSW5qZWN0KSAtPlxuXG5cdFx0bGVuID0gYS5sZW5ndGhcblxuXHRcdGkgPSBpbmRleFxuXG5cdFx0aWYgbGVuIDwgMVxuXG5cdFx0XHRhLnB1c2ggdG9JbmplY3RcblxuXHRcdFx0cmV0dXJuIGFcblxuXHRcdHRvUHV0ID0gdG9JbmplY3RcblxuXHRcdHRvUHV0TmV4dCA9IG51bGxcblxuXHRcdGBmb3IoOyBpIDw9IGxlbjsgaSsrKXtcblxuXHRcdFx0dG9QdXROZXh0ID0gYVtpXTtcblxuXHRcdFx0YVtpXSA9IHRvUHV0O1xuXG5cdFx0XHR0b1B1dCA9IHRvUHV0TmV4dDtcblxuXHRcdH1gXG5cblx0XHQjIGFbaV0gPSB0b1B1dFxuXG5cdFx0bnVsbCIsIm1vZHVsZS5leHBvcnRzID0gY2xhc3NpYyA9IHt9XG5cbiMgTGl0dGxlIGhlbHBlciBmb3IgbWl4aW5zIGZyb20gQ29mZmVlU2NyaXB0IEZBUSxcbiMgY291cnRlc3kgb2YgU2V0aGF1cnVzIChodHRwOi8vZ2l0aHViLmNvbS9zZXRoYXVydXMpXG5jbGFzc2ljLmltcGxlbWVudCA9IChtaXhpbnMuLi4sIGNsYXNzUmVmZXJlbmNlKSAtPlxuXG5cdGZvciBtaXhpbiBpbiBtaXhpbnNcblxuXHRcdGNsYXNzUHJvdG8gPSBjbGFzc1JlZmVyZW5jZTo6XG5cblx0XHRmb3IgbWVtYmVyIG9mIG1peGluOjpcblxuXHRcdFx0dW5sZXNzIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgY2xhc3NQcm90bywgbWVtYmVyXG5cblx0XHRcdFx0ZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgbWl4aW46OiwgbWVtYmVyXG5cblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5IGNsYXNzUHJvdG8sIG1lbWJlciwgZGVzY1xuXG5cdGNsYXNzUmVmZXJlbmNlXG5cbmNsYXNzaWMubWl4ID0gKG1peGlucy4uLiwgY2xhc3NSZWZlcmVuY2UpIC0+XG5cblx0Y2xhc3NQcm90byA9IGNsYXNzUmVmZXJlbmNlOjpcblxuXHRjbGFzc1JlZmVyZW5jZS5fX21peGluQ2xvbmVycyA9IFtdXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19hcHBseUNsb25lcnNGb3IgPSAoaW5zdGFuY2UsIGFyZ3MgPSBudWxsKSAtPlxuXG5cdFx0Zm9yIGNsb25lciBpbiBjbGFzc1JlZmVyZW5jZS5fX21peGluQ2xvbmVyc1xuXG5cdFx0XHRjbG9uZXIuYXBwbHkgaW5zdGFuY2UsIGFyZ3NcblxuXHRcdHJldHVyblxuXG5cdGNsYXNzUmVmZXJlbmNlLl9fbWl4aW5Jbml0aWFsaXplcnMgPSBbXVxuXG5cdGNsYXNzUmVmZXJlbmNlLl9faW5pdE1peGluc0ZvciA9IChpbnN0YW5jZSwgYXJncyA9IG51bGwpIC0+XG5cblx0XHRmb3IgaW5pdGlhbGl6ZXIgaW4gY2xhc3NSZWZlcmVuY2UuX19taXhpbkluaXRpYWxpemVyc1xuXG5cdFx0XHRpbml0aWFsaXplci5hcHBseSBpbnN0YW5jZSwgYXJnc1xuXG5cdFx0cmV0dXJuXG5cblx0Y2xhc3NSZWZlcmVuY2UuX19taXhpblF1aXR0ZXJzID0gW11cblxuXHRjbGFzc1JlZmVyZW5jZS5fX2FwcGx5UXVpdHRlcnNGb3IgPSAoaW5zdGFuY2UsIGFyZ3MgPSBudWxsKSAtPlxuXG5cdFx0Zm9yIHF1aXR0ZXIgaW4gY2xhc3NSZWZlcmVuY2UuX19taXhpblF1aXR0ZXJzXG5cblx0XHRcdHF1aXR0ZXIuYXBwbHkgaW5zdGFuY2UsIGFyZ3NcblxuXHRcdHJldHVyblxuXG5cdGZvciBtaXhpbiBpbiBtaXhpbnNcblxuXHRcdHVubGVzcyBtaXhpbi5jb25zdHJ1Y3RvciBpbnN0YW5jZW9mIEZ1bmN0aW9uXG5cblx0XHRcdHRocm93IEVycm9yIFwiTWl4aW4gc2hvdWxkIGJlIGEgZnVuY3Rpb25cIlxuXG5cdFx0Zm9yIG1lbWJlciBvZiBtaXhpbjo6XG5cblx0XHRcdGlmIG1lbWJlci5zdWJzdHIoMCwgMTEpIGlzICdfX2luaXRNaXhpbidcblxuXHRcdFx0XHRjbGFzc1JlZmVyZW5jZS5fX21peGluSW5pdGlhbGl6ZXJzLnB1c2ggbWl4aW46OlttZW1iZXJdXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0ZWxzZSBpZiBtZW1iZXIuc3Vic3RyKDAsIDExKSBpcyAnX19jbG9uZXJGb3InXG5cblx0XHRcdFx0Y2xhc3NSZWZlcmVuY2UuX19taXhpbkNsb25lcnMucHVzaCBtaXhpbjo6W21lbWJlcl1cblxuXHRcdFx0XHRjb250aW51ZVxuXG5cdFx0XHRlbHNlIGlmIG1lbWJlci5zdWJzdHIoMCwgMTIpIGlzICdfX3F1aXR0ZXJGb3InXG5cblx0XHRcdFx0Y2xhc3NSZWZlcmVuY2UuX19taXhpblF1aXR0ZXJzLnB1c2ggbWl4aW46OlttZW1iZXJdXG5cblx0XHRcdFx0Y29udGludWVcblxuXHRcdFx0dW5sZXNzIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgY2xhc3NQcm90bywgbWVtYmVyXG5cblx0XHRcdFx0ZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgbWl4aW46OiwgbWVtYmVyXG5cblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5IGNsYXNzUHJvdG8sIG1lbWJlciwgZGVzY1xuXG5cdGNsYXNzUmVmZXJlbmNlIiwiYXJyYXkgPSByZXF1aXJlICcuL2FycmF5J1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjbGFzcyBFbWl0dGVyXHJcblxyXG5cdGNvbnN0cnVjdG9yOiAtPlxyXG5cclxuXHRcdEBfbGlzdGVuZXJzID0ge31cclxuXHJcblx0XHRAX2xpc3RlbmVyc0ZvckFueUV2ZW50ID0gW11cclxuXHJcblx0XHRAX2Rpc2FibGVkRW1pdHRlcnMgPSB7fVxyXG5cclxuXHRvbjogKGV2ZW50TmFtZSwgbGlzdGVuZXIpIC0+XHJcblxyXG5cdFx0dW5sZXNzIEBfbGlzdGVuZXJzW2V2ZW50TmFtZV0/XHJcblxyXG5cdFx0XHRAX2xpc3RlbmVyc1tldmVudE5hbWVdID0gW11cclxuXHJcblx0XHRAX2xpc3RlbmVyc1tldmVudE5hbWVdLnB1c2ggbGlzdGVuZXJcclxuXHJcblx0XHRAXHJcblxyXG5cdG9uY2U6IChldmVudE5hbWUsIGxpc3RlbmVyKSAtPlxyXG5cclxuXHRcdHJhbiA9IG5vXHJcblxyXG5cdFx0Y2IgPSA9PlxyXG5cclxuXHRcdFx0cmV0dXJuIGlmIHJhblxyXG5cclxuXHRcdFx0cmFuID0geWVzXHJcblxyXG5cdFx0XHRkbyBsaXN0ZW5lclxyXG5cclxuXHRcdFx0c2V0VGltZW91dCA9PlxyXG5cclxuXHRcdFx0XHRAcmVtb3ZlRXZlbnQgZXZlbnROYW1lLCBjYlxyXG5cclxuXHRcdFx0LCAwXHJcblxyXG5cdFx0QG9uIGV2ZW50TmFtZSwgY2JcclxuXHJcblx0XHRAXHJcblxyXG5cdG9uQW55RXZlbnQ6IChsaXN0ZW5lcikgLT5cclxuXHJcblx0XHRAX2xpc3RlbmVyc0ZvckFueUV2ZW50LnB1c2ggbGlzdGVuZXJcclxuXHJcblx0XHRAXHJcblxyXG5cdHJlbW92ZUV2ZW50OiAoZXZlbnROYW1lLCBsaXN0ZW5lcikgLT5cclxuXHJcblx0XHRyZXR1cm4gQCB1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRhcnJheS5wbHVja09uZUl0ZW0gQF9saXN0ZW5lcnNbZXZlbnROYW1lXSwgbGlzdGVuZXJcclxuXHJcblx0XHRAXHJcblxyXG5cdHJlbW92ZUxpc3RlbmVyczogKGV2ZW50TmFtZSkgLT5cclxuXHJcblx0XHRyZXR1cm4gQCB1bmxlc3MgQF9saXN0ZW5lcnNbZXZlbnROYW1lXT9cclxuXHJcblx0XHRAX2xpc3RlbmVyc1tldmVudE5hbWVdLmxlbmd0aCA9IDBcclxuXHJcblx0XHRAXHJcblxyXG5cdHJlbW92ZUFsbExpc3RlbmVyczogLT5cclxuXHJcblx0XHRmb3IgbmFtZSwgbGlzdGVuZXJzIG9mIEBfbGlzdGVuZXJzXHJcblxyXG5cdFx0XHRsaXN0ZW5lcnMubGVuZ3RoID0gMFxyXG5cclxuXHRcdEBcclxuXHJcblx0X2VtaXQ6IChldmVudE5hbWUsIGRhdGEpIC0+XHJcblxyXG5cdFx0Zm9yIGxpc3RlbmVyIGluIEBfbGlzdGVuZXJzRm9yQW55RXZlbnRcclxuXHJcblx0XHRcdGxpc3RlbmVyLmNhbGwgQCwgZGF0YSwgZXZlbnROYW1lXHJcblxyXG5cdFx0cmV0dXJuIHVubGVzcyBAX2xpc3RlbmVyc1tldmVudE5hbWVdP1xyXG5cclxuXHRcdGZvciBsaXN0ZW5lciBpbiBAX2xpc3RlbmVyc1tldmVudE5hbWVdXHJcblxyXG5cdFx0XHRsaXN0ZW5lci5jYWxsIEAsIGRhdGFcclxuXHJcblx0XHRyZXR1cm5cclxuXHJcblx0IyB0aGlzIG1ha2VzIHN1cmUgdGhhdCBhbGwgdGhlIGNhbGxzIHRvIHRoaXMgY2xhc3MncyBtZXRob2QgJ2ZuTmFtZSdcclxuXHQjIGFyZSB0aHJvdHRsZWRcclxuXHRfdGhyb3R0bGVFbWl0dGVyTWV0aG9kOiAoZm5OYW1lLCB0aW1lID0gMTAwMCkgLT5cclxuXHJcblx0XHRvcmlnaW5hbEZuID0gQFtmbk5hbWVdXHJcblxyXG5cdFx0aWYgdHlwZW9mIG9yaWdpbmFsRm4gaXNudCAnZnVuY3Rpb24nXHJcblxyXG5cdFx0XHR0aHJvdyBFcnJvciBcInRoaXMgY2xhc3MgZG9lcyBub3QgaGF2ZSBhIG1ldGhvZCBjYWxsZWQgJyN7Zm5OYW1lfSdcIlxyXG5cclxuXHRcdGxhc3RDYWxsQXJncyA9IG51bGxcclxuXHRcdHBlbmRpbmcgPSBub1xyXG5cdFx0dGltZXIgPSBudWxsXHJcblxyXG5cdFx0QFtmbk5hbWVdID0gPT5cclxuXHJcblx0XHRcdGxhc3RDYWxsQXJncyA9IGFyZ3VtZW50c1xyXG5cclxuXHRcdFx0ZG8gcGVuZFxyXG5cclxuXHRcdHBlbmQgPSA9PlxyXG5cclxuXHRcdFx0aWYgcGVuZGluZ1xyXG5cclxuXHRcdFx0XHRjbGVhclRpbWVvdXQgdGltZXJcclxuXHJcblx0XHRcdHRpbWVyID0gc2V0VGltZW91dCBydW5JdCwgdGltZVxyXG5cclxuXHRcdFx0cGVuZGluZyA9IHllc1xyXG5cclxuXHRcdHJ1bkl0ID0gPT5cclxuXHJcblx0XHRcdHBlbmRpbmcgPSBub1xyXG5cclxuXHRcdFx0b3JpZ2luYWxGbi5hcHBseSBALCBsYXN0Q2FsbEFyZ3NcclxuXHJcblx0X2Rpc2FibGVFbWl0dGVyOiAoZm5OYW1lKSAtPlxyXG5cclxuXHRcdGlmIEBfZGlzYWJsZWRFbWl0dGVyc1tmbk5hbWVdP1xyXG5cclxuXHRcdFx0dGhyb3cgRXJyb3IgXCIje2ZuTmFtZX0gaXMgYWxyZWFkeSBhIGRpc2FibGVkIGVtaXR0ZXJcIlxyXG5cclxuXHRcdEBfZGlzYWJsZWRFbWl0dGVyc1tmbk5hbWVdID0gQFtmbk5hbWVdXHJcblxyXG5cdFx0QFtmbk5hbWVdID0gLT5cclxuXHJcblx0X2VuYWJsZUVtaXR0ZXI6IChmbk5hbWUpIC0+XHJcblxyXG5cdFx0Zm4gPSBAX2Rpc2FibGVkRW1pdHRlcnNbZm5OYW1lXVxyXG5cclxuXHRcdHVubGVzcyBmbj9cclxuXHJcblx0XHRcdHRocm93IEVycm9yIFwiI3tmbk5hbWV9IGlzIG5vdCBhIGRpc2FibGVkIGVtaXR0ZXJcIlxyXG5cclxuXHRcdEBbZm5OYW1lXSA9IGZuXHJcblxyXG5cdFx0ZGVsZXRlIEBfZGlzYWJsZWRFbWl0dGVyc1tmbk5hbWVdIiwiX2NvbW1vbiA9IHJlcXVpcmUgJy4vX2NvbW1vbidcblxubW9kdWxlLmV4cG9ydHMgPSBvYmplY3QgPVxuXG5cdGlzQmFyZU9iamVjdDogX2NvbW1vbi5pc0JhcmVPYmplY3QuYmluZCBfY29tbW9uXG5cblx0IyMjXG5cdGlmIG9iamVjdCBpcyBhbiBpbnN0YW5jZSBvZiBhIGNsYXNzXG5cdCMjI1xuXHRpc0luc3RhbmNlOiAod2hhdCkgLT5cblxuXHRcdG5vdCBAaXNCYXJlT2JqZWN0IHdoYXRcblxuXHQjIyNcblx0QWxpYXMgdG8gX2NvbW1vbi50eXBlT2Zcblx0IyMjXG5cdHR5cGVPZjogX2NvbW1vbi50eXBlT2YuYmluZCBfY29tbW9uXG5cblx0IyMjXG5cdEFsaWFzIHRvIF9jb21tb24uY2xvbmVcblx0IyMjXG5cdGNsb25lOiBfY29tbW9uLmNsb25lLmJpbmQgX2NvbW1vblxuXG5cdCMjI1xuXHRFbXB0aWVzIGFuIG9iamVjdCBvZiBpdHMgcHJvcGVydGllcy5cblx0IyMjXG5cdGVtcHR5OiAobykgLT5cblxuXHRcdGZvciBwcm9wIG9mIG9cblxuXHRcdFx0ZGVsZXRlIG9bcHJvcF0gaWYgby5oYXNPd25Qcm9wZXJ0eSBwcm9wXG5cblx0XHRvXG5cblx0IyMjXG5cdEVtcHRpZXMgYW4gb2JqZWN0LiBEb2Vzbid0IGNoZWNrIGZvciBoYXNPd25Qcm9wZXJ0eSwgc28gaXQncyBhIHRpbnlcblx0Yml0IGZhc3Rlci4gVXNlIGl0IGZvciBwbGFpbiBvYmplY3RzLlxuXHQjIyNcblx0ZmFzdEVtcHR5OiAobykgLT5cblxuXHRcdGRlbGV0ZSBvW3Byb3BlcnR5XSBmb3IgcHJvcGVydHkgb2Ygb1xuXG5cdFx0b1xuXG5cdCMjI1xuXHRPdmVycmlkZXMgdmFsdWVzIGZvbXIgYG5ld1ZhbHVlc2Agb24gYGJhc2VgLCBhcyBsb25nIGFzIHRoZXlcblx0YWxyZWFkeSBleGlzdCBpbiBiYXNlLlxuXHQjIyNcblx0b3ZlcnJpZGVPbnRvOiAoYmFzZSwgbmV3VmFsdWVzKSAtPlxuXG5cdFx0cmV0dXJuIGJhc2UgaWYgbm90IEBpc0JhcmVPYmplY3QobmV3VmFsdWVzKSBvciBub3QgQGlzQmFyZU9iamVjdChiYXNlKVxuXG5cdFx0Zm9yIGtleSwgb2xkVmFsIG9mIGJhc2VcblxuXHRcdFx0bmV3VmFsID0gbmV3VmFsdWVzW2tleV1cblxuXHRcdFx0Y29udGludWUgaWYgbmV3VmFsIGlzIHVuZGVmaW5lZFxuXG5cdFx0XHRpZiB0eXBlb2YgbmV3VmFsIGlzbnQgJ29iamVjdCcgb3IgQGlzSW5zdGFuY2UgbmV3VmFsXG5cblx0XHRcdFx0YmFzZVtrZXldID0gQGNsb25lIG5ld1ZhbFxuXG5cdFx0XHQjIG5ld1ZhbCBpcyBhIHBsYWluIG9iamVjdFxuXHRcdFx0ZWxzZVxuXG5cdFx0XHRcdGlmIHR5cGVvZiBvbGRWYWwgaXNudCAnb2JqZWN0JyBvciBAaXNJbnN0YW5jZSBvbGRWYWxcblxuXHRcdFx0XHRcdGJhc2Vba2V5XSA9IEBjbG9uZSBuZXdWYWxcblxuXHRcdFx0XHRlbHNlXG5cblx0XHRcdFx0XHRAb3ZlcnJpZGVPbnRvIG9sZFZhbCwgbmV3VmFsXG5cdFx0YmFzZVxuXG5cdCMjI1xuXHRUYWtlcyBhIGNsb25lIG9mICdiYXNlJyBhbmQgcnVucyAjb3ZlcnJpZGVPbnRvIG9uIGl0XG5cdCMjI1xuXHRvdmVycmlkZTogKGJhc2UsIG5ld1ZhbHVlcykgLT5cblxuXHRcdEBvdmVycmlkZU9udG8gQGNsb25lKGJhc2UpLCBuZXdWYWx1ZXNcblxuXHRhcHBlbmQ6IChiYXNlLCB0b0FwcGVuZCkgLT5cblxuXHRcdEBhcHBlbmRPbnRvIEBjbG9uZShiYXNlKSwgdG9BcHBlbmRcblxuXHQjIERlZXAgYXBwZW5kcyB2YWx1ZXMgZnJvbSBgdG9BcHBlbmRgIHRvIGBiYXNlYFxuXHRhcHBlbmRPbnRvOiAoYmFzZSwgdG9BcHBlbmQpIC0+XG5cblx0XHRyZXR1cm4gYmFzZSBpZiBub3QgQGlzQmFyZU9iamVjdCh0b0FwcGVuZCkgb3Igbm90IEBpc0JhcmVPYmplY3QoYmFzZSlcblxuXHRcdGZvciBvd24ga2V5LCBuZXdWYWwgb2YgdG9BcHBlbmRcblxuXHRcdFx0Y29udGludWUgdW5sZXNzIG5ld1ZhbCBpc250IHVuZGVmaW5lZFxuXG5cdFx0XHRpZiB0eXBlb2YgbmV3VmFsIGlzbnQgJ29iamVjdCcgb3IgQGlzSW5zdGFuY2UgbmV3VmFsXG5cblx0XHRcdFx0YmFzZVtrZXldID0gbmV3VmFsXG5cblx0XHRcdGVsc2VcblxuXHRcdFx0XHQjIG5ld1ZhbCBpcyBhIGJhcmUgb2JqZWN0XG5cblx0XHRcdFx0b2xkVmFsID0gYmFzZVtrZXldXG5cblx0XHRcdFx0aWYgdHlwZW9mIG9sZFZhbCBpc250ICdvYmplY3QnIG9yIEBpc0luc3RhbmNlIG9sZFZhbFxuXG5cdFx0XHRcdFx0YmFzZVtrZXldID0gQGNsb25lIG5ld1ZhbFxuXG5cdFx0XHRcdGVsc2VcblxuXHRcdFx0XHRcdEBhcHBlbmRPbnRvIG9sZFZhbCwgbmV3VmFsXG5cblx0XHRiYXNlXG5cblx0IyBHcm91cHNcblx0Z3JvdXBQcm9wczogKG9iaiwgZ3JvdXBzKSAtPlxuXG5cdFx0Z3JvdXBlZCA9IHt9XG5cblx0XHRmb3IgbmFtZSwgZGVmcyBvZiBncm91cHNcblxuXHRcdFx0Z3JvdXBlZFtuYW1lXSA9IHt9XG5cblx0XHRncm91cGVkWydyZXN0J10gPSB7fVxuXG5cdFx0YHRvcDogLy9gXG5cdFx0Zm9yIGtleSwgdmFsIG9mIG9ialxuXG5cdFx0XHRzaG91bGRBZGQgPSBub1xuXG5cdFx0XHRmb3IgbmFtZSwgZGVmcyBvZiBncm91cHNcblxuXHRcdFx0XHR1bmxlc3MgQXJyYXkuaXNBcnJheSBkZWZzXG5cblx0XHRcdFx0XHRkZWZzID0gW2RlZnNdXG5cblx0XHRcdFx0Zm9yIGRlZiBpbiBkZWZzXG5cblx0XHRcdFx0XHRpZiB0eXBlb2YgZGVmIGlzICdzdHJpbmcnXG5cblx0XHRcdFx0XHRcdGlmIGtleSBpcyBkZWZcblxuXHRcdFx0XHRcdFx0XHRzaG91bGRBZGQgPSB5ZXNcblxuXHRcdFx0XHRcdGVsc2UgaWYgZGVmIGluc3RhbmNlb2YgUmVnRXhwXG5cblx0XHRcdFx0XHRcdGlmIGRlZi50ZXN0IGtleVxuXG5cdFx0XHRcdFx0XHRcdHNob3VsZEFkZCA9IHllc1xuXG5cdFx0XHRcdFx0ZWxzZSBpZiBkZWYgaW5zdGFuY2VvZiBGdW5jdGlvblxuXG5cdFx0XHRcdFx0XHRpZiBkZWYga2V5XG5cblx0XHRcdFx0XHRcdFx0c2hvdWxkQWRkID0geWVzXG5cblx0XHRcdFx0XHRlbHNlXG5cblx0XHRcdFx0XHRcdHRocm93IEVycm9yICdHcm91cCBkZWZpbml0aW9ucyBtdXN0IGVpdGhlclxuXHRcdFx0XHRcdFx0YmUgc3RyaW5ncywgcmVnZXhlcywgb3IgZnVuY3Rpb25zLidcblxuXHRcdFx0XHRcdGlmIHNob3VsZEFkZFxuXG5cdFx0XHRcdFx0XHRncm91cGVkW25hbWVdW2tleV0gPSB2YWxcblxuXHRcdFx0XHRcdFx0YGNvbnRpbnVlIHRvcGBcblxuXHRcdFx0Z3JvdXBlZFsncmVzdCddW2tleV0gPSB2YWxcblxuXHRcdGdyb3VwZWQiLCJtb2R1bGUuZXhwb3J0cyA9XHJcblxyXG5cdCMgcGFkcyBhIG51bWJlciB3aXRoIGxlYWRpbmcgemVyb2VzXHJcblx0I1xyXG5cdCMgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTAwNzM3ODgvNjA3OTk3XHJcblx0cGFkOiAobiwgd2lkdGgsIHogPSAnMCcpIC0+XHJcblxyXG5cdFx0biA9IG4gKyAnJ1xyXG5cclxuXHRcdGlmIG4ubGVuZ3RoID49IHdpZHRoXHJcblxyXG5cdFx0XHRuXHJcblxyXG5cdFx0ZWxzZVxyXG5cclxuXHRcdFx0bmV3IEFycmF5KHdpZHRoIC0gbi5sZW5ndGggKyAxKS5qb2luKHopICsgbiIsIm1vZHVsZS5leHBvcnRzID0gdXRpbGEgPVxuXG5cdGFycmF5OiByZXF1aXJlICcuL2FycmF5J1xuXHRjbGFzc2ljOiByZXF1aXJlICcuL2NsYXNzaWMnXG5cdG9iamVjdDogcmVxdWlyZSAnLi9vYmplY3QnXG5cdHN0cmluZzogcmVxdWlyZSAnLi9zdHJpbmcnXG5cdEVtaXR0ZXI6IHJlcXVpcmUgJy4vRW1pdHRlciciLCJtb2R1bGUuZXhwb3J0cyA9IGNvbW1vbiA9XG5cblx0IyMjXG5cdENoZWNrcyB0byBzZWUgaWYgbyBpcyBhbiBvYmplY3QsIGFuZCBpdCBpc24ndCBhbiBpbnN0YW5jZVxuXHRvZiBzb21lIGNsYXNzLlxuXHQjIyNcblx0aXNCYXJlT2JqZWN0OiAobykgLT5cblxuXHRcdGlmIG8/IGFuZCBvLmNvbnN0cnVjdG9yIGlzIE9iamVjdFxuXG5cdFx0XHRyZXR1cm4gdHJ1ZVxuXG5cdFx0ZmFsc2VcblxuXHQjIyNcblx0UmV0dXJucyB0eXBlIG9mIGFuIG9iamVjdCwgaW5jbHVkaW5nOlxuXHR1bmRlZmluZWQsIG51bGwsIHN0cmluZywgbnVtYmVyLCBhcnJheSxcblx0YXJndW1lbnRzLCBlbGVtZW50LCB0ZXh0bm9kZSwgd2hpdGVzcGFjZSwgYW5kIG9iamVjdFxuXHQjIyNcblx0dHlwZU9mOiAoaXRlbSkgLT5cblxuXHRcdHJldHVybiAnbnVsbCcgaWYgaXRlbSBpcyBudWxsXG5cblx0XHRyZXR1cm4gdHlwZW9mIGl0ZW0gaWYgdHlwZW9mIGl0ZW0gaXNudCAnb2JqZWN0J1xuXG5cdFx0cmV0dXJuICdhcnJheScgaWYgQXJyYXkuaXNBcnJheSBpdGVtXG5cblx0XHQjIEZyb20gTW9vVG9vbHNcblx0XHQjIC0gZG8gd2UgZXZlbiBuZWVkIHRoaXM/XG5cdFx0aWYgaXRlbS5ub2RlTmFtZVxuXG5cdFx0XHRpZiBpdGVtLm5vZGVUeXBlIGlzIDEgdGhlbiByZXR1cm4gJ2VsZW1lbnQnXG5cdFx0XHRpZiBpdGVtLm5vZGVUeXBlIGlzIDMgdGhlbiByZXR1cm4gKC9cXFMvKS50ZXN0KGl0ZW0ubm9kZVZhbHVlKSA/ICd0ZXh0bm9kZScgOiAnd2hpdGVzcGFjZSdcblxuXHRcdGVsc2UgaWYgdHlwZW9mIGl0ZW0ubGVuZ3RoIGlzICdudW1iZXInXG5cblx0XHRcdGlmIGl0ZW0uY2FsbGVlIHRoZW4gcmV0dXJuICdhcmd1bWVudHMnXG5cblx0XHRyZXR1cm4gdHlwZW9mIGl0ZW1cblxuXHQjIERlZXAgY2xvbmUgb2YgYW55IHZhcmlhYmxlLlxuXHQjIEZyb20gTW9vVG9vbHNcblx0Y2xvbmU6IChpdGVtLCBpbmNsdWRlUHJvdG90eXBlID0gZmFsc2UpIC0+XG5cblx0XHRzd2l0Y2ggY29tbW9uLnR5cGVPZiBpdGVtXG5cblx0XHRcdHdoZW4gJ2FycmF5JyB0aGVuIHJldHVybiBjb21tb24uX2Nsb25lQXJyYXkgaXRlbSwgaW5jbHVkZVByb3RvdHlwZVxuXG5cdFx0XHR3aGVuICdvYmplY3QnIHRoZW4gcmV0dXJuIGNvbW1vbi5fY2xvbmVPYmplY3QgaXRlbSwgaW5jbHVkZVByb3RvdHlwZVxuXG5cdFx0XHRlbHNlIHJldHVybiBpdGVtXG5cblx0IyMjXG5cdERlZXAgY2xvbmUgb2YgYW4gb2JqZWN0LlxuXHRGcm9tIE1vb1Rvb2xzXG5cdCMjI1xuXHRfY2xvbmVPYmplY3Q6IChvLCBpbmNsdWRlUHJvdG90eXBlID0gZmFsc2UpIC0+XG5cblx0XHRpZiBjb21tb24uaXNCYXJlT2JqZWN0IG9cblxuXHRcdFx0Y2xvbmUgPSB7fVxuXG5cdFx0XHRmb3Iga2V5IG9mIG9cblxuXHRcdFx0XHRjbG9uZVtrZXldID0gY29tbW9uLmNsb25lIG9ba2V5XSwgaW5jbHVkZVByb3RvdHlwZVxuXG5cdFx0XHRyZXR1cm4gY2xvbmVcblxuXHRcdGVsc2VcblxuXHRcdFx0cmV0dXJuIG8gdW5sZXNzIGluY2x1ZGVQcm90b3R5cGVcblxuXHRcdFx0cmV0dXJuIG8gaWYgbyBpbnN0YW5jZW9mIEZ1bmN0aW9uXG5cblx0XHRcdGNsb25lID0gT2JqZWN0LmNyZWF0ZSBvLmNvbnN0cnVjdG9yLnByb3RvdHlwZVxuXG5cdFx0XHRmb3Iga2V5IG9mIG9cblxuXHRcdFx0XHRpZiBvLmhhc093blByb3BlcnR5IGtleVxuXG5cdFx0XHRcdFx0Y2xvbmVba2V5XSA9IGNvbW1vbi5jbG9uZSBvW2tleV0sIGluY2x1ZGVQcm90b3R5cGVcblxuXHRcdFx0Y2xvbmVcblxuXHQjIyNcblx0RGVlcCBjbG9uZSBvZiBhbiBhcnJheS5cblx0RnJvbSBNb29Ub29sc1xuXHQjIyNcblx0X2Nsb25lQXJyYXk6IChhLCBpbmNsdWRlUHJvdG90eXBlID0gZmFsc2UpIC0+XG5cblx0XHRpID0gYS5sZW5ndGhcblxuXHRcdGNsb25lID0gbmV3IEFycmF5IGlcblxuXHRcdHdoaWxlIGktLVxuXG5cdFx0XHRjbG9uZVtpXSA9IGNvbW1vbi5jbG9uZSBhW2ldLCBpbmNsdWRlUHJvdG90eXBlXG5cblx0XHRjbG9uZSIsInJlcXVpcmUgJy4vX3ByZXBhcmUnXG5cbmFycmF5ID0gbW9kICdhcnJheSdcblxudGVzdCAnZnJvbScsIC0+XG5cblx0YXJyYXkuZnJvbShbMV0pLnNob3VsZC5iZS5hbi5pbnN0YW5jZU9mIEFycmF5XG5cdGFycmF5LmZyb20oWzFdKVswXS5zaG91bGQuZXF1YWwgMVxuXG4jIHRlc3QgJ2Nsb25lJywgLT5cblxuIyBcdGEgPSBbMCwgMSwgMl1cblxuIyBcdGIgPSBhcnJheS5jbG9uZSBhXG5cbiMgXHRiWzBdLnNob3VsZC5lcXVhbCAwXG4jIFx0YlsxXS5zaG91bGQuZXF1YWwgMVxuXG4jIFx0YlswXSA9IDNcblxuIyBcdGFbMF0uc2hvdWxkLmVxdWFsIDBcblxudGVzdCAncGx1Y2snLCAtPlxuXG5cdGEgPSBbMCwgMSwgMiwgM11cblxuXHRhZnRlciA9IGFycmF5LnBsdWNrIGEsIDFcblxuXHRhZnRlci5sZW5ndGguc2hvdWxkLmVxdWFsIDNcblxuXHRhZnRlclswXS5zaG91bGQuZXF1YWwgMFxuXHRhZnRlclsxXS5zaG91bGQuZXF1YWwgMlxuXHRhZnRlclsyXS5zaG91bGQuZXF1YWwgM1xuXHRhZnRlci5zaG91bGQuZXF1YWwgYVxuXG50ZXN0ICdwbHVja011bHRpcGxlJywgLT5cblxuXHRhID0gWzAsIDEsIDIsIDMsIDQsIDUsIDZdXG5cblx0YXJyYXkucGx1Y2tNdWx0aXBsZSBhLCBbMCwgNCwgMiwgNl1cblxuXHRhLmxlbmd0aC5zaG91bGQuZXF1YWwgM1xuXHRhWzBdLnNob3VsZC5lcXVhbCAxXG5cdGFbMV0uc2hvdWxkLmVxdWFsIDNcblx0YVsyXS5zaG91bGQuZXF1YWwgNVxuXG50ZXN0ICdwbHVja0l0ZW0nLCAtPlxuXG5cdGEgPSBbMCwgMSwgMiwgMywgMiwgNCwgMl1cblxuXHRhcnJheS5wbHVja0l0ZW0gYSwgMlxuXG5cdGFbMF0uc2hvdWxkLmVxdWFsIDBcblx0YVsxXS5zaG91bGQuZXF1YWwgMVxuXHRhWzJdLnNob3VsZC5lcXVhbCAzXG5cdGFbM10uc2hvdWxkLmVxdWFsIDRcblxuXHRhcnJheS5wbHVja0l0ZW0oWzFdLCAyKS5sZW5ndGguc2hvdWxkLmVxdWFsIDFcblxuXG50ZXN0ICdwbHVja09uZUl0ZW0nLCAtPlxuXG5cdGEgPSBbMCwgMSwgMiwgMywgMiwgNCwgMl1cblxuXHRhcnJheS5wbHVja09uZUl0ZW0gYSwgMlxuXG5cdGFbMF0uc2hvdWxkLmVxdWFsIDBcblx0YVsxXS5zaG91bGQuZXF1YWwgMVxuXHRhWzJdLnNob3VsZC5lcXVhbCAzXG5cdGFbM10uc2hvdWxkLmVxdWFsIDJcblx0YVs0XS5zaG91bGQuZXF1YWwgNFxuXHRhWzVdLnNob3VsZC5lcXVhbCAyXG5cblx0YSA9IFsxLCAyXVxuXG5cdGFycmF5LnBsdWNrT25lSXRlbSBhLCAxXG5cblx0YS5sZW5ndGguc2hvdWxkLmVxdWFsIDFcblx0YVswXS5zaG91bGQuZXF1YWwgMlxuXG5cdGFycmF5LnBsdWNrT25lSXRlbShbXSwgMSkubGVuZ3RoLnNob3VsZC5lcXVhbCAwXG5cblx0YXJyYXkucGx1Y2tPbmVJdGVtKFsxXSwgMikubGVuZ3RoLnNob3VsZC5lcXVhbCAxXG5cbnRlc3QgJ3BsY3VrQnlDYWxsYmFjaycsIC0+XG5cblx0YSA9IFswLCAxLCAyLCAzXVxuXG5cdGFycmF5LnBsdWNrQnlDYWxsYmFjayBhLCAodmFsLCBpKSAtPlxuXG5cdFx0cmV0dXJuIHllcyBpZiB2YWwgaXMgMlxuXG5cdFx0cmV0dXJuIG5vXG5cblx0YVswXS5zaG91bGQuZXF1YWwgMFxuXHRhWzFdLnNob3VsZC5lcXVhbCAxXG5cdGFbMl0uc2hvdWxkLmVxdWFsIDNcblxudGVzdCAnaW5qZWN0QnlDYWxsYmFjaycsIC0+XG5cblx0c2hvdWxkSW5qZWN0ID0gKHZhbEEsIHZhbEIsIHRvSW5qZWN0KSAtPlxuXG5cdFx0dW5sZXNzIHZhbEE/XG5cblx0XHRcdHJldHVybiB5ZXMgaWYgdG9JbmplY3QgPD0gdmFsQlxuXG5cdFx0XHRyZXR1cm4gbm9cblxuXHRcdHVubGVzcyB2YWxCP1xuXG5cdFx0XHRyZXR1cm4geWVzIGlmIHZhbEEgPD0gdG9JbmplY3RcblxuXHRcdFx0cmV0dXJuIG5vXG5cblx0XHRyZXR1cm4geWVzIGlmIHZhbEEgPD0gdG9JbmplY3QgPD0gdmFsQlxuXG5cdFx0cmV0dXJuIG5vXG5cblx0YSA9IFswLjUsIDEsIDIuNSwgMi41LCAyLjc1LCAyLjc1LCAzXVxuXG5cdGFycmF5LmluamVjdEJ5Q2FsbGJhY2sgYSwgMCwgc2hvdWxkSW5qZWN0XG5cblx0YVswXS5zaG91bGQuZXF1YWwgMFxuXHRhWzFdLnNob3VsZC5lcXVhbCAwLjVcblx0YVs3XS5zaG91bGQuZXF1YWwgM1xuXG5cdGEgPSBbMC41LCAxLCAyLjUsIDIuNSwgMi43NSwgMi43NSwgM11cblxuXHRhcnJheS5pbmplY3RCeUNhbGxiYWNrIGEsIDIuNywgc2hvdWxkSW5qZWN0XG5cblx0YVswXS5zaG91bGQuZXF1YWwgMC41XG5cdGFbNF0uc2hvdWxkLmVxdWFsIDIuN1xuXHRhWzVdLnNob3VsZC5lcXVhbCAyLjc1XG5cdGFbN10uc2hvdWxkLmVxdWFsIDNcblxuXHRhID0gWzAuNSwgMSwgMi41LCAyLjUsIDIuNzUsIDIuNzUsIDNdXG5cblx0YXJyYXkuaW5qZWN0QnlDYWxsYmFjayBhLCAzLjIsIHNob3VsZEluamVjdFxuXG5cdGFbMF0uc2hvdWxkLmVxdWFsIDAuNVxuXHRhWzRdLnNob3VsZC5lcXVhbCAyLjc1XG5cdGFbNl0uc2hvdWxkLmVxdWFsIDNcblx0YVs3XS5zaG91bGQuZXF1YWwgMy4yIiwicmVxdWlyZSAnLi9fcHJlcGFyZSdcblxub2JqZWN0ID0gbW9kICdvYmplY3QnXG5cbnRlc3QgJ2lzQmFyZU9iamVjdCcsIC0+XG5cblx0b2JqZWN0LmlzQmFyZU9iamVjdCgnYScpLnNob3VsZC5lcXVhbCBmYWxzZVxuXG5cdG9iamVjdC5pc0JhcmVPYmplY3QoeydhJzogJ2EnfSkuc2hvdWxkLmVxdWFsIHRydWVcblxudGVzdCAndHlwZU9mJywgLT5cblxuXHRvYmplY3QudHlwZU9mKCdzJykuc2hvdWxkLmVxdWFsICdzdHJpbmcnXG5cdG9iamVjdC50eXBlT2YoMCkuc2hvdWxkLmVxdWFsICdudW1iZXInXG5cdG9iamVjdC50eXBlT2YoZmFsc2UpLnNob3VsZC5lcXVhbCAnYm9vbGVhbidcblx0b2JqZWN0LnR5cGVPZih7fSkuc2hvdWxkLmVxdWFsICdvYmplY3QnXG5cdG9iamVjdC50eXBlT2YoYXJndW1lbnRzKS5zaG91bGQuZXF1YWwgJ2FyZ3VtZW50cydcblx0b2JqZWN0LnR5cGVPZihbXSkuc2hvdWxkLmVxdWFsICdhcnJheSdcblxudGVzdCAnZW1wdHknLCAtPlxuXG5cdG8gPVxuXG5cdFx0YTogMVxuXHRcdGI6IDJcblxuXG5cdG9iamVjdC5lbXB0eSBvXG5cblx0by5zaG91bGQubm90LmhhdmUucHJvcGVydHkgJ2EnXG5cdG8uc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5ICdiJ1xuXG50ZXN0ICdmYXN0RW1wdHknLCAtPlxuXG5cdG8gPVxuXHRcdGE6IDFcblx0XHRiOiAyXG5cblxuXHRvYmplY3QuZmFzdEVtcHR5IG9cblxuXHRvLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSAnYSdcblx0by5zaG91bGQubm90LmhhdmUucHJvcGVydHkgJ2InXG5cbnRlc3QgJ2Nsb25lJywgLT5cblxuXHRvYmplY3QuY2xvbmUoWzFdKVswXS5zaG91bGQuZXF1YWwgMVxuXHRvYmplY3QuY2xvbmUoe2E6MX0pLmEuc2hvdWxkLmVxdWFsIDFcblxuXHRvID0ge2E6IDF9XG5cblx0b2JqZWN0LmNsb25lKG8pLnNob3VsZC5ub3QuZXF1YWwgb1xuXG50ZXN0ICdjbG9uZSBbaW5jbHVkZSBwcm90b3R5cGVdJywgLT5cblxuXHRjbGFzcyBDXG5cblx0XHRjb25zdHJ1Y3RvcjogKEBhKSAtPlxuXG5cdFx0c2F5QTogLT4gQGEgKyAnYSdcblxuXHRhID0gbmV3IEMgJ2EnXG5cblx0YS5zYXlBKCkuc2hvdWxkLmVxdWFsICdhYSdcblxuXHRiID0gb2JqZWN0LmNsb25lIGEsIHllc1xuXG5cdGIuc2hvdWxkLm5vdC5lcXVhbCBhXG5cblx0Yi5jb25zdHJ1Y3Rvci5zaG91bGQuZXF1YWwgQ1xuXG5cdGIuYS5zaG91bGQuZXF1YWwgJ2EnXG5cblx0Yi5hID0gJ2EyJ1xuXG5cdGIuc2F5QSgpLnNob3VsZC5lcXVhbCAnYTJhJ1xuXG50ZXN0ICdjbG9uZSBbd2l0aG91dCBwcm90b3R5cGVdJywgLT5cblxuXHRjbGFzcyBDXG5cblx0XHRjb25zdHJ1Y3RvcjogKEBhKSAtPlxuXG5cdFx0c2F5QTogLT4gQGEgKyAnYSdcblxuXHRhID0gbmV3IEMgJ2EnXG5cblx0YS5zYXlBKCkuc2hvdWxkLmVxdWFsICdhYSdcblxuXHRiID0gb2JqZWN0LmNsb25lIGEsIG5vXG5cblx0Yi5zaG91bGQuZXF1YWwgYVxuXG50ZXN0ICdvdmVycmlkZU9udG8gW2Jhc2ljXScsIC0+XG5cblx0b250byA9XG5cdFx0YTogJ2EnXG5cdFx0Yjpcblx0XHRcdGM6ICdjJ1xuXHRcdFx0ZDpcblx0XHRcdFx0ZTogJ2UnXG5cblx0d2hhdCA9XG5cdFx0YTogJ2EyJ1xuXHRcdGI6XG5cdFx0XHRjOiAnYzInXG5cdFx0XHRkOlxuXHRcdFx0XHRmOiAnZjInXG5cblx0b2JqZWN0Lm92ZXJyaWRlT250byBvbnRvLCB3aGF0XG5cblx0b250by5hLnNob3VsZC5lcXVhbCAnYTInXG5cdG9udG8uYi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSAnYydcblx0b250by5iLmMuc2hvdWxkLmVxdWFsICdjMidcblx0b250by5iLmQuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5ICdmJ1xuXHRvbnRvLmIuZC5lLnNob3VsZC5lcXVhbCAnZSdcblxudGVzdCAnb3ZlcnJpZGUnLCAtPlxuXG5cdG9udG8gPVxuXG5cdFx0YTogJ2EnXG5cblx0XHRiOlxuXG5cdFx0XHRjOiAnYydcblxuXHRcdFx0ZDpcblxuXHRcdFx0XHRlOiAnZSdcblxuXHR3aGF0ID1cblxuXHRcdGE6ICdhMidcblxuXHRcdGI6XG5cblx0XHRcdGM6ICdjMidcblxuXHRcdFx0ZDpcblxuXHRcdFx0XHRmOiAnZjInXG5cblxuXHRvbnRvMiA9IG9iamVjdC5vdmVycmlkZSBvbnRvLCB3aGF0XG5cblx0b250bzIuYS5zaG91bGQuZXF1YWwgJ2EyJ1xuXHRvbnRvMi5iLnNob3VsZC5oYXZlLnByb3BlcnR5ICdjJ1xuXHRvbnRvMi5iLmMuc2hvdWxkLmVxdWFsICdjMidcblx0b250bzIuYi5kLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSAnZidcblx0b250bzIuYi5kLmUuc2hvdWxkLmVxdWFsICdlJ1xuXG5cdG9udG8uc2hvdWxkLm5vdC5lcXVhbCBvbnRvMlxuXG5kbyAtPlxuXG5cdHdoYXQgPVxuXG5cdFx0YTogJ2EyJ1xuXG5cdFx0YzogLT5cblxuXHRcdHo6ICd6J1xuXG5cdFx0eTpcblxuXHRcdFx0YTogJ2EnXG5cblx0b250byA9XG5cblx0XHRhOiAnYSdcblxuXHRcdGI6ICdiJ1xuXG5cdHRlc3QgJ2FwcGVuZE9udG8gW2Jhc2ljXScsIC0+XG5cblx0XHRvYmplY3QuYXBwZW5kT250byBvbnRvLCB3aGF0XG5cblx0XHRvbnRvLmEuc2hvdWxkLmVxdWFsICdhMidcblx0XHRvbnRvLmIuc2hvdWxkLmVxdWFsICdiJ1xuXHRcdG9udG8uei5zaG91bGQuZXF1YWwgJ3onXG5cblx0dGVzdCBcImFwcGVuZE9udG8gW3NoYWxsb3cgY29waWVzIGluc3RhbmNlc11cIiwgLT5cblxuXHRcdG9udG8uYy5zaG91bGQuYmUuaW5zdGFuY2VvZiBGdW5jdGlvblxuXHRcdG9udG8uYy5zaG91bGQuZXF1YWwgd2hhdC5jXG5cblxuXHR0ZXN0IFwiYXBwZW5kT250byBbY2xvbmVzIG9iamVjdHNdXCIsIC0+XG5cblx0XHRvbnRvLnNob3VsZC5oYXZlLnByb3BlcnR5ICd5J1xuXHRcdG9udG8ueS5hLnNob3VsZC5lcXVhbCAnYSdcblx0XHRvbnRvLnkuc2hvdWxkLm5vdC5lcXVhbCB3aGF0LnlcblxudGVzdCAnZ3JvdXBQcm9wcycsIC0+XG5cblx0b2JqID1cblxuXHRcdGExOiAnMSdcblx0XHRhMjogJzInXG5cblx0XHRiMTogJzEnXG5cdFx0YjI6ICcyJ1xuXG5cdFx0YzE6ICcxJ1xuXHRcdGMyOiAnMidcblxuXHRcdHJlc3QxOiAnMSdcblx0XHRyZXN0MjogJzInXG5cblx0Z3JvdXBzID0gb2JqZWN0Lmdyb3VwUHJvcHMgb2JqLFxuXG5cdFx0YTogWydhMScsICdhMiddXG5cblx0XHRiOiBbL15iWzAtOV0rJC9dXG5cblx0XHRjOiAoa2V5KSAtPiBrZXlbMF0gaXMgJ2MnXG5cblx0Z3JvdXBzLmEuc2hvdWxkLmhhdmUucHJvcGVydHkgJ2ExJ1xuXHRncm91cHMuYS5hMS5zaG91bGQuZXF1YWwgJzEnXG5cblx0Z3JvdXBzLmEuc2hvdWxkLmhhdmUucHJvcGVydHkgJ2EyJ1xuXG5cdGdyb3Vwcy5iLnNob3VsZC5oYXZlLnByb3BlcnR5ICdiMSdcblx0Z3JvdXBzLmIuc2hvdWxkLmhhdmUucHJvcGVydHkgJ2IyJ1xuXG5cdGdyb3Vwcy5jLnNob3VsZC5oYXZlLnByb3BlcnR5ICdjMSdcblx0Z3JvdXBzLmMuc2hvdWxkLmhhdmUucHJvcGVydHkgJ2MyJ1xuXG5cdGdyb3Vwcy5yZXN0LnNob3VsZC5oYXZlLnByb3BlcnR5ICdyZXN0MSdcblx0Z3JvdXBzLnJlc3Quc2hvdWxkLmhhdmUucHJvcGVydHkgJ3Jlc3QxJ1xuXG5cdGdyb3Vwcy5yZXN0LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSAnYzEnIl19 \ No newline at end of file