made with requirebin
Last active
November 9, 2016 15:49
-
-
Save vorg/bd641eadffff6ba6b8a6dca1835f3c2f to your computer and use it in GitHub Desktop.
requirebin sketch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Streams implementation for mouse events. | |
| // Started based thinking in https://github.com/pex-gl/pex-gui/issues/8 | |
| // IMPORT DEPENDENCIES | |
| // Flyd is "The less is more, modular, functional reactive programming library" | |
| const flyd = require('flyd') | |
| // emit events from one stream until another stream fires | |
| const takeUntil = require('flyd/module/takeuntil') | |
| // merge multiple streams into one | |
| const mergeAll = require('flyd/module/mergeall') | |
| // filter stream events based on predicate | |
| const filterStream = require('flyd/module/filter') | |
| // map events from a stream using a function | |
| const mapStream = flyd.map | |
| // check if point is inside a rectangle | |
| const containsPoint = require('pex-geom/Rect').containsPoint | |
| // UI | |
| // Draw a red canvas with yellow "button" on the left | |
| const btnRect = [[10, 10], [100, 100]] | |
| const canvas = document.createElement('canvas') | |
| canvas.style.background = 'red' | |
| document.body.appendChild(canvas) | |
| const ctx = canvas.getContext('2d') | |
| ctx.fillStyle = '#FFFF00' | |
| ctx.fillRect(btnRect[0][0], btnRect[0][1], btnRect[1][0] - btnRect[0][0], btnRect[1][1] - btnRect[0][1]) | |
| // crate streams for all mouse events | |
| const mousedown = flyd.stream() | |
| const mouseup = flyd.stream() | |
| const mousemove = flyd.stream() | |
| const windowmouseup = flyd.stream() | |
| canvas.addEventListener('mousedown', mousedown) | |
| canvas.addEventListener('mouseup', mouseup) | |
| canvas.addEventListener('mousemove', mousemove) | |
| window.addEventListener('mouseup', windowmouseup) | |
| //flyd.on((e) => console.log('windowmouseup', e), windowmouseup) | |
| // DRAG event stream implementation | |
| // This shows how to combine streams (down, move, up) into a new stream | |
| function createMouseDragStream (mousedown, mousemove, mouseup) { | |
| const mousedrag = flyd.stream() | |
| // on each mousedown event | |
| flyd.on((e) => { | |
| // create new stream that take events from mousemove | |
| // until mouse up on canvas or window | |
| const drag = takeUntil(mousemove, mergeAll([mouseup, windowmouseup])) | |
| // then forward all events from drag to mousedrag | |
| flyd.on(mousedrag, drag) | |
| }, mousedown) | |
| return mousedrag | |
| } | |
| const mousedrag = createMouseDragStream(mousedown, mousemove, mouseup) | |
| // print mousedrag when dragging mouse over canvas | |
| //flyd.on((e) => console.log('mousedrag', e), mousedrag) | |
| // filter functon checking if mouse event is inside rectangle | |
| function inRect (rect) { | |
| return function (e) { | |
| // TODO: curry this! | |
| return containsPoint(rect, [e.clientX, e.clientY]) | |
| } | |
| } | |
| // we use preventDefault to mark handled streams | |
| function markAsHandled (e) { | |
| e.preventDefault() | |
| return e | |
| } | |
| function notHandledYet (e) { | |
| return !e.defaultPrevented | |
| } | |
| // we add background event listener first as we go from broad to more specific | |
| const bgmousedown = filterStream(notHandledYet, mousedown) | |
| flyd.on((e) => console.log('bg mousedown', e), bgmousedown) | |
| /* | |
| const bgmousedrag = mapStream(markAsHandled, createMouseDragStream( | |
| bgmousedown, | |
| mousemove, | |
| mouseup | |
| ) | |
| ) | |
| flyd.on((e) => console.log('bg mousedrag', e), bgmousedrag) | |
| */ | |
| // mouse clicks inside yellow rect | |
| //const buttonmousedown = mapStream(markAsHandled, filterStream(inRect(btnRect), mousedown)) | |
| // mouse clicks outside yellow rect | |
| //flyd.on((e) => console.log('button mousedown', e), buttonmousedown) | |
| // crate drag event stream that happens only if we click inside button | |
| const buttonmousedrag = createMouseDragStream( | |
| mapStream(markAsHandled, filterStream(inRect(btnRect), mousedown)), | |
| mousemove, | |
| mouseup | |
| ) | |
| //flyd.on((e) => console.log('button drag', e), buttonmousedrag) | |
| /* | |
| const a = flyd.stream() | |
| const g = flyd.stream() | |
| window.addEventListener('mousedown', a) | |
| window.addEventListener('mousedown', g) | |
| flyd.on((e) => console.log('a', e), a) | |
| flyd.on((e) => console.log('g background', e), g) | |
| flyd.on((e) => console.log('g slider', e), g) | |
| */ | |
| //const pointer = require('pointer-events-stream')(gl.canvas) | |
| canvas.addEventListener('mousedown', (e) => { | |
| e.preventDefault() | |
| console.log('canvas down') | |
| }) | |
| canvas.addEventListener('mouseup', (e) => { | |
| console.log('canvas up', e.defaultPrevented) | |
| }) | |
| window.addEventListener('mouseup', (e) => { | |
| console.log('window up', e.defaultPrevented) | |
| }) | |
| window.addEventListener('mouseout', (e) => { | |
| console.log('window out', e.defaultPrevented) | |
| }) | |
| /* Ideal scenario | |
| var mouseclicks = stream() | |
| var leftoferclicks = gui.addMouse(mouseclicks) | |
| // inside gui | |
| var click = mouseclicks.peak() | |
| if (insideSlier(click)) { | |
| mouseclicks.take() | |
| } | |
| */ | |
| // PROBLEM | |
| // - calling e.preventDefault in canvas.mousedown prevents window.mouseup released outside of browser bounds | |
| // - gui and arcball / scene are using same canvas events. That wouldn't happen with canvas + dom dat.gui | |
| // SCENARIOS | |
| // gui vs arcball conflicks, picking bounding boxes vs arcball | |
| // SOLUTIONS | |
| // - keep using pex-sys/MouseEvent | |
| // - flyd: add a handled flag to the Event object | |
| // - create sepate window for gui |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| setTimeout(function(){ | |
| ;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
| var _arity = require('./internal/_arity'); | |
| var _curry1 = require('./internal/_curry1'); | |
| var _curry2 = require('./internal/_curry2'); | |
| var _curryN = require('./internal/_curryN'); | |
| /** | |
| * Returns a curried equivalent of the provided function, with the specified | |
| * arity. The curried function has two unusual capabilities. First, its | |
| * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the | |
| * following are equivalent: | |
| * | |
| * - `g(1)(2)(3)` | |
| * - `g(1)(2, 3)` | |
| * - `g(1, 2)(3)` | |
| * - `g(1, 2, 3)` | |
| * | |
| * Secondly, the special placeholder value `R.__` may be used to specify | |
| * "gaps", allowing partial application of any combination of arguments, | |
| * regardless of their positions. If `g` is as above and `_` is `R.__`, the | |
| * following are equivalent: | |
| * | |
| * - `g(1, 2, 3)` | |
| * - `g(_, 2, 3)(1)` | |
| * - `g(_, _, 3)(1)(2)` | |
| * - `g(_, _, 3)(1, 2)` | |
| * - `g(_, 2)(1)(3)` | |
| * - `g(_, 2)(1, 3)` | |
| * - `g(_, 2)(_, 3)(1)` | |
| * | |
| * @func | |
| * @memberOf R | |
| * @since v0.5.0 | |
| * @category Function | |
| * @sig Number -> (* -> a) -> (* -> a) | |
| * @param {Number} length The arity for the returned function. | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} A new, curried function. | |
| * @see R.curry | |
| * @example | |
| * | |
| * var sumArgs = (...args) => R.sum(args); | |
| * | |
| * var curriedAddFourNumbers = R.curryN(4, sumArgs); | |
| * var f = curriedAddFourNumbers(1, 2); | |
| * var g = f(3); | |
| * g(4); //=> 10 | |
| */ | |
| module.exports = _curry2(function curryN(length, fn) { | |
| if (length === 1) { | |
| return _curry1(fn); | |
| } | |
| return _arity(length, _curryN(length, [], fn)); | |
| }); | |
| },{"./internal/_arity":2,"./internal/_curry1":3,"./internal/_curry2":4,"./internal/_curryN":5}],2:[function(require,module,exports){ | |
| module.exports = function _arity(n, fn) { | |
| /* eslint-disable no-unused-vars */ | |
| switch (n) { | |
| case 0: return function() { return fn.apply(this, arguments); }; | |
| case 1: return function(a0) { return fn.apply(this, arguments); }; | |
| case 2: return function(a0, a1) { return fn.apply(this, arguments); }; | |
| case 3: return function(a0, a1, a2) { return fn.apply(this, arguments); }; | |
| case 4: return function(a0, a1, a2, a3) { return fn.apply(this, arguments); }; | |
| case 5: return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments); }; | |
| case 6: return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments); }; | |
| case 7: return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments); }; | |
| case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments); }; | |
| case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments); }; | |
| case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments); }; | |
| default: throw new Error('First argument to _arity must be a non-negative integer no greater than ten'); | |
| } | |
| }; | |
| },{}],3:[function(require,module,exports){ | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Optimized internal one-arity curry function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curry1(fn) { | |
| return function f1(a) { | |
| if (arguments.length === 0 || _isPlaceholder(a)) { | |
| return f1; | |
| } else { | |
| return fn.apply(this, arguments); | |
| } | |
| }; | |
| }; | |
| },{"./_isPlaceholder":6}],4:[function(require,module,exports){ | |
| var _curry1 = require('./_curry1'); | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Optimized internal two-arity curry function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curry2(fn) { | |
| return function f2(a, b) { | |
| switch (arguments.length) { | |
| case 0: | |
| return f2; | |
| case 1: | |
| return _isPlaceholder(a) ? f2 | |
| : _curry1(function(_b) { return fn(a, _b); }); | |
| default: | |
| return _isPlaceholder(a) && _isPlaceholder(b) ? f2 | |
| : _isPlaceholder(a) ? _curry1(function(_a) { return fn(_a, b); }) | |
| : _isPlaceholder(b) ? _curry1(function(_b) { return fn(a, _b); }) | |
| : fn(a, b); | |
| } | |
| }; | |
| }; | |
| },{"./_curry1":3,"./_isPlaceholder":6}],5:[function(require,module,exports){ | |
| var _arity = require('./_arity'); | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Internal curryN function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Number} length The arity of the curried function. | |
| * @param {Array} received An array of arguments received thus far. | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curryN(length, received, fn) { | |
| return function() { | |
| var combined = []; | |
| var argsIdx = 0; | |
| var left = length; | |
| var combinedIdx = 0; | |
| while (combinedIdx < received.length || argsIdx < arguments.length) { | |
| var result; | |
| if (combinedIdx < received.length && | |
| (!_isPlaceholder(received[combinedIdx]) || | |
| argsIdx >= arguments.length)) { | |
| result = received[combinedIdx]; | |
| } else { | |
| result = arguments[argsIdx]; | |
| argsIdx += 1; | |
| } | |
| combined[combinedIdx] = result; | |
| if (!_isPlaceholder(result)) { | |
| left -= 1; | |
| } | |
| combinedIdx += 1; | |
| } | |
| return left <= 0 ? fn.apply(this, combined) | |
| : _arity(left, _curryN(length, combined, fn)); | |
| }; | |
| }; | |
| },{"./_arity":2,"./_isPlaceholder":6}],6:[function(require,module,exports){ | |
| module.exports = function _isPlaceholder(a) { | |
| return a != null && | |
| typeof a === 'object' && | |
| a['@@functional/placeholder'] === true; | |
| }; | |
| },{}],"flyd":[function(require,module,exports){ | |
| 'use strict'; | |
| var curryN = require('ramda/src/curryN'); | |
| // Utility | |
| function isFunction(obj) { | |
| return !!(obj && obj.constructor && obj.call && obj.apply); | |
| } | |
| function trueFn() { return true; } | |
| // Globals | |
| var toUpdate = []; | |
| var inStream; | |
| var order = []; | |
| var orderNextIdx = -1; | |
| var flushing = false; | |
| /** @namespace */ | |
| var flyd = {} | |
| // /////////////////////////// API ///////////////////////////////// // | |
| /** | |
| * Creates a new stream | |
| * | |
| * __Signature__: `a -> Stream a` | |
| * | |
| * @name flyd.stream | |
| * @param {*} initialValue - (Optional) the initial value of the stream | |
| * @return {stream} the stream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); // Stream with initial value `1` | |
| * var s = flyd.stream(); // Stream with no initial value | |
| */ | |
| flyd.stream = function(initialValue) { | |
| var endStream = createDependentStream([], trueFn); | |
| var s = createStream(); | |
| s.end = endStream; | |
| s.fnArgs = []; | |
| endStream.listeners.push(s); | |
| if (arguments.length > 0) s(initialValue); | |
| return s; | |
| } | |
| /** | |
| * Create a new dependent stream | |
| * | |
| * __Signature__: `(...Stream * -> Stream b -> b) -> [Stream *] -> Stream b` | |
| * | |
| * @name flyd.combine | |
| * @param {Function} fn - the function used to combine the streams | |
| * @param {Array<stream>} dependencies - the streams that this one depends on | |
| * @return {stream} the dependent stream | |
| * | |
| * @example | |
| * var n1 = flyd.stream(0); | |
| * var n2 = flyd.stream(0); | |
| * var max = flyd.combine(function(n1, n2, self, changed) { | |
| * return n1() > n2() ? n1() : n2(); | |
| * }, [n1, n2]); | |
| */ | |
| flyd.combine = curryN(2, combine); | |
| function combine(fn, streams) { | |
| var i, s, deps, depEndStreams; | |
| var endStream = createDependentStream([], trueFn); | |
| deps = []; depEndStreams = []; | |
| for (i = 0; i < streams.length; ++i) { | |
| if (streams[i] !== undefined) { | |
| deps.push(streams[i]); | |
| if (streams[i].end !== undefined) depEndStreams.push(streams[i].end); | |
| } | |
| } | |
| s = createDependentStream(deps, fn); | |
| s.depsChanged = []; | |
| s.fnArgs = s.deps.concat([s, s.depsChanged]); | |
| s.end = endStream; | |
| endStream.listeners.push(s); | |
| addListeners(depEndStreams, endStream); | |
| endStream.deps = depEndStreams; | |
| updateStream(s); | |
| return s; | |
| } | |
| /** | |
| * Returns `true` if the supplied argument is a Flyd stream and `false` otherwise. | |
| * | |
| * __Signature__: `* -> Boolean` | |
| * | |
| * @name flyd.isStream | |
| * @param {*} value - the value to test | |
| * @return {Boolean} `true` if is a Flyd streamn, `false` otherwise | |
| * | |
| * @example | |
| * var s = flyd.stream(1); | |
| * var n = 1; | |
| * flyd.isStream(s); //=> true | |
| * flyd.isStream(n); //=> false | |
| */ | |
| flyd.isStream = function(stream) { | |
| return isFunction(stream) && 'hasVal' in stream; | |
| } | |
| /** | |
| * Invokes the body (the function to calculate the value) of a dependent stream | |
| * | |
| * By default the body of a dependent stream is only called when all the streams | |
| * upon which it depends has a value. `immediate` can circumvent this behaviour. | |
| * It immediately invokes the body of a dependent stream. | |
| * | |
| * __Signature__: `Stream a -> Stream a` | |
| * | |
| * @name flyd.immediate | |
| * @param {stream} stream - the dependent stream | |
| * @return {stream} the same stream | |
| * | |
| * @example | |
| * var s = flyd.stream(); | |
| * var hasItems = flyd.immediate(flyd.combine(function(s) { | |
| * return s() !== undefined && s().length > 0; | |
| * }, [s]); | |
| * console.log(hasItems()); // logs `false`. Had `immediate` not been | |
| * // used `hasItems()` would've returned `undefined` | |
| * s([1]); | |
| * console.log(hasItems()); // logs `true`. | |
| * s([]); | |
| * console.log(hasItems()); // logs `false`. | |
| */ | |
| flyd.immediate = function(s) { | |
| if (s.depsMet === false) { | |
| s.depsMet = true; | |
| updateStream(s); | |
| } | |
| return s; | |
| } | |
| /** | |
| * Changes which `endsStream` should trigger the ending of `s`. | |
| * | |
| * __Signature__: `Stream a -> Stream b -> Stream b` | |
| * | |
| * @name flyd.endsOn | |
| * @param {stream} endStream - the stream to trigger the ending | |
| * @param {stream} stream - the stream to be ended by the endStream | |
| * @param {stream} the stream modified to be ended by endStream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); | |
| * var killer = flyd.stream(); | |
| * // `double` ends when `n` ends or when `killer` emits any value | |
| * var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.combine(function(n) { | |
| * return 2 * n(); | |
| * }, [n]); | |
| */ | |
| flyd.endsOn = function(endS, s) { | |
| detachDeps(s.end); | |
| endS.listeners.push(s.end); | |
| s.end.deps.push(endS); | |
| return s; | |
| } | |
| /** | |
| * Map a stream | |
| * | |
| * Returns a new stream consisting of every value from `s` passed through | |
| * `fn`. I.e. `map` creates a new stream that listens to `s` and | |
| * applies `fn` to every new value. | |
| * __Signature__: `(a -> result) -> Stream a -> Stream result` | |
| * | |
| * @name flyd.map | |
| * @param {Function} fn - the function that produces the elements of the new stream | |
| * @param {stream} stream - the stream to map | |
| * @return {stream} a new stream with the mapped values | |
| * | |
| * @example | |
| * var numbers = flyd.stream(0); | |
| * var squaredNumbers = flyd.map(function(n) { return n*n; }, numbers); | |
| */ | |
| // Library functions use self callback to accept (null, undefined) update triggers. | |
| flyd.map = curryN(2, function(f, s) { | |
| return combine(function(s, self) { self(f(s.val)); }, [s]); | |
| }) | |
| /** | |
| * Listen to stream events | |
| * | |
| * Similar to `map` except that the returned stream is empty. Use `on` for doing | |
| * side effects in reaction to stream changes. Use the returned stream only if you | |
| * need to manually end it. | |
| * | |
| * __Signature__: `(a -> result) -> Stream a -> Stream undefined` | |
| * | |
| * @name flyd.on | |
| * @param {Function} cb - the callback | |
| * @param {stream} stream - the stream | |
| * @return {stream} an empty stream (can be ended) | |
| */ | |
| flyd.on = curryN(2, function(f, s) { | |
| return combine(function(s) { f(s.val); }, [s]); | |
| }) | |
| /** | |
| * Creates a new stream with the results of calling the function on every incoming | |
| * stream with and accumulator and the incoming value. | |
| * | |
| * __Signature__: `(a -> b -> a) -> a -> Stream b -> Stream a` | |
| * | |
| * @name flyd.scan | |
| * @param {Function} fn - the function to call | |
| * @param {*} val - the initial value of the accumulator | |
| * @param {stream} stream - the stream source | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var numbers = flyd.stream(); | |
| * var sum = flyd.scan(function(sum, n) { return sum+n; }, 0, numbers); | |
| * numbers(2)(3)(5); | |
| * sum(); // 10 | |
| */ | |
| flyd.scan = curryN(3, function(f, acc, s) { | |
| var ns = combine(function(s, self) { | |
| self(acc = f(acc, s.val)); | |
| }, [s]); | |
| if (!ns.hasVal) ns(acc); | |
| return ns; | |
| }); | |
| /** | |
| * Creates a new stream down which all values from both `stream1` and `stream2` | |
| * will be sent. | |
| * | |
| * __Signature__: `Stream a -> Stream a -> Stream a` | |
| * | |
| * @name flyd.merge | |
| * @param {stream} source1 - one stream to be merged | |
| * @param {stream} source2 - the other stream to be merged | |
| * @return {stream} a stream with the values from both sources | |
| * | |
| * @example | |
| * var btn1Clicks = flyd.stream(); | |
| * button1Elm.addEventListener(btn1Clicks); | |
| * var btn2Clicks = flyd.stream(); | |
| * button2Elm.addEventListener(btn2Clicks); | |
| * var allClicks = flyd.merge(btn1Clicks, btn2Clicks); | |
| */ | |
| flyd.merge = curryN(2, function(s1, s2) { | |
| var s = flyd.immediate(combine(function(s1, s2, self, changed) { | |
| if (changed[0]) { | |
| self(changed[0]()); | |
| } else if (s1.hasVal) { | |
| self(s1.val); | |
| } else if (s2.hasVal) { | |
| self(s2.val); | |
| } | |
| }, [s1, s2])); | |
| flyd.endsOn(combine(function() { | |
| return true; | |
| }, [s1.end, s2.end]), s); | |
| return s; | |
| }); | |
| /** | |
| * Creates a new stream resulting from applying `transducer` to `stream`. | |
| * | |
| * __Signature__: `Transducer -> Stream a -> Stream b` | |
| * | |
| * @name flyd.transduce | |
| * @param {Transducer} xform - the transducer transformation | |
| * @param {stream} source - the stream source | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var t = require('transducers.js'); | |
| * | |
| * var results = []; | |
| * var s1 = flyd.stream(); | |
| * var tx = t.compose(t.map(function(x) { return x * 2; }), t.dedupe()); | |
| * var s2 = flyd.transduce(tx, s1); | |
| * flyd.combine(function(s2) { results.push(s2()); }, [s2]); | |
| * s1(1)(1)(2)(3)(3)(3)(4); | |
| * results; // => [2, 4, 6, 8] | |
| */ | |
| flyd.transduce = curryN(2, function(xform, source) { | |
| xform = xform(new StreamTransformer()); | |
| return combine(function(source, self) { | |
| var res = xform['@@transducer/step'](undefined, source.val); | |
| if (res && res['@@transducer/reduced'] === true) { | |
| self.end(true); | |
| return res['@@transducer/value']; | |
| } else { | |
| return res; | |
| } | |
| }, [source]); | |
| }); | |
| /** | |
| * Returns `fn` curried to `n`. Use this function to curry functions exposed by | |
| * modules for Flyd. | |
| * | |
| * @name flyd.curryN | |
| * @function | |
| * @param {Integer} arity - the function arity | |
| * @param {Function} fn - the function to curry | |
| * @return {Function} the curried function | |
| * | |
| * @example | |
| * function add(x, y) { return x + y; }; | |
| * var a = flyd.curryN(2, add); | |
| * a(2)(4) // => 6 | |
| */ | |
| flyd.curryN = curryN | |
| /** | |
| * Returns a new stream identical to the original except every | |
| * value will be passed through `f`. | |
| * | |
| * _Note:_ This function is included in order to support the fantasy land | |
| * specification. | |
| * | |
| * __Signature__: Called bound to `Stream a`: `(a -> b) -> Stream b` | |
| * | |
| * @name stream.map | |
| * @param {Function} function - the function to apply | |
| * @return {stream} a new stream with the values mapped | |
| * | |
| * @example | |
| * var numbers = flyd.stream(0); | |
| * var squaredNumbers = numbers.map(function(n) { return n*n; }); | |
| */ | |
| function boundMap(f) { return flyd.map(f, this); } | |
| /** | |
| * Returns a new stream which is the result of applying the | |
| * functions from `this` stream to the values in `stream` parameter. | |
| * | |
| * `this` stream must be a stream of functions. | |
| * | |
| * _Note:_ This function is included in order to support the fantasy land | |
| * specification. | |
| * | |
| * __Signature__: Called bound to `Stream (a -> b)`: `a -> Stream b` | |
| * | |
| * @name stream.ap | |
| * @param {stream} stream - the values stream | |
| * @return {stream} a new stram with the functions applied to values | |
| * | |
| * @example | |
| * var add = flyd.curryN(2, function(x, y) { return x + y; }); | |
| * var numbers1 = flyd.stream(); | |
| * var numbers2 = flyd.stream(); | |
| * var addToNumbers1 = flyd.map(add, numbers1); | |
| * var added = addToNumbers1.ap(numbers2); | |
| */ | |
| function ap(s2) { | |
| var s1 = this; | |
| return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]); | |
| } | |
| /** | |
| * Get a human readable view of a stream | |
| * @name stream.toString | |
| * @return {String} the stream string representation | |
| */ | |
| function streamToString() { | |
| return 'stream(' + this.val + ')'; | |
| } | |
| /** | |
| * @name stream.end | |
| * @memberof stream | |
| * A stream that emits `true` when the stream ends. If `true` is pushed down the | |
| * stream the parent stream ends. | |
| */ | |
| /** | |
| * @name stream.of | |
| * @function | |
| * @memberof stream | |
| * Returns a new stream with `value` as its initial value. It is identical to | |
| * calling `flyd.stream` with one argument. | |
| * | |
| * __Signature__: Called bound to `Stream (a)`: `b -> Stream b` | |
| * | |
| * @param {*} value - the initial value | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); | |
| * var m = n.of(1); | |
| */ | |
| // /////////////////////////// PRIVATE ///////////////////////////////// // | |
| /** | |
| * @private | |
| * Create a stream with no dependencies and no value | |
| * @return {Function} a flyd stream | |
| */ | |
| function createStream() { | |
| function s(n) { | |
| if (arguments.length === 0) return s.val | |
| updateStreamValue(s, n) | |
| return s | |
| } | |
| s.hasVal = false; | |
| s.val = undefined; | |
| s.vals = []; | |
| s.listeners = []; | |
| s.queued = false; | |
| s.end = undefined; | |
| s.map = boundMap; | |
| s.ap = ap; | |
| s.of = flyd.stream; | |
| s.toString = streamToString; | |
| return s; | |
| } | |
| /** | |
| * @private | |
| * Create a dependent stream | |
| * @param {Array<stream>} dependencies - an array of the streams | |
| * @param {Function} fn - the function used to calculate the new stream value | |
| * from the dependencies | |
| * @return {stream} the created stream | |
| */ | |
| function createDependentStream(deps, fn) { | |
| var s = createStream(); | |
| s.fn = fn; | |
| s.deps = deps; | |
| s.depsMet = false; | |
| s.depsChanged = deps.length > 0 ? [] : undefined; | |
| s.shouldUpdate = false; | |
| addListeners(deps, s); | |
| return s; | |
| } | |
| /** | |
| * @private | |
| * Check if all the dependencies have values | |
| * @param {stream} stream - the stream to check depencencies from | |
| * @return {Boolean} `true` if all dependencies have vales, `false` otherwise | |
| */ | |
| function initialDepsNotMet(stream) { | |
| stream.depsMet = stream.deps.every(function(s) { | |
| return s.hasVal; | |
| }); | |
| return !stream.depsMet; | |
| } | |
| /** | |
| * @private | |
| * Update a dependent stream using its dependencies in an atomic way | |
| * @param {stream} stream - the stream to update | |
| */ | |
| function updateStream(s) { | |
| if ((s.depsMet !== true && initialDepsNotMet(s)) || | |
| (s.end !== undefined && s.end.val === true)) return; | |
| if (inStream !== undefined) { | |
| toUpdate.push(s); | |
| return; | |
| } | |
| inStream = s; | |
| if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged; | |
| var returnVal = s.fn.apply(s.fn, s.fnArgs); | |
| if (returnVal !== undefined) { | |
| s(returnVal); | |
| } | |
| inStream = undefined; | |
| if (s.depsChanged !== undefined) s.depsChanged = []; | |
| s.shouldUpdate = false; | |
| if (flushing === false) flushUpdate(); | |
| } | |
| /** | |
| * @private | |
| * Update the dependencies of a stream | |
| * @param {stream} stream | |
| */ | |
| function updateDeps(s) { | |
| var i, o, list | |
| var listeners = s.listeners; | |
| for (i = 0; i < listeners.length; ++i) { | |
| list = listeners[i]; | |
| if (list.end === s) { | |
| endStream(list); | |
| } else { | |
| if (list.depsChanged !== undefined) list.depsChanged.push(s); | |
| list.shouldUpdate = true; | |
| findDeps(list); | |
| } | |
| } | |
| for (; orderNextIdx >= 0; --orderNextIdx) { | |
| o = order[orderNextIdx]; | |
| if (o.shouldUpdate === true) updateStream(o); | |
| o.queued = false; | |
| } | |
| } | |
| /** | |
| * @private | |
| * Add stream dependencies to the global `order` queue. | |
| * @param {stream} stream | |
| * @see updateDeps | |
| */ | |
| function findDeps(s) { | |
| var i | |
| var listeners = s.listeners; | |
| if (s.queued === false) { | |
| s.queued = true; | |
| for (i = 0; i < listeners.length; ++i) { | |
| findDeps(listeners[i]); | |
| } | |
| order[++orderNextIdx] = s; | |
| } | |
| } | |
| /** | |
| * @private | |
| */ | |
| function flushUpdate() { | |
| flushing = true; | |
| while (toUpdate.length > 0) { | |
| var s = toUpdate.shift(); | |
| if (s.vals.length > 0) s.val = s.vals.shift(); | |
| updateDeps(s); | |
| } | |
| flushing = false; | |
| } | |
| /** | |
| * @private | |
| * Push down a value into a stream | |
| * @param {stream} stream | |
| * @param {*} value | |
| */ | |
| function updateStreamValue(s, n) { | |
| if (n !== undefined && n !== null && isFunction(n.then)) { | |
| n.then(s); | |
| return; | |
| } | |
| s.val = n; | |
| s.hasVal = true; | |
| if (inStream === undefined) { | |
| flushing = true; | |
| updateDeps(s); | |
| if (toUpdate.length > 0) flushUpdate(); else flushing = false; | |
| } else if (inStream === s) { | |
| markListeners(s, s.listeners); | |
| } else { | |
| s.vals.push(n); | |
| toUpdate.push(s); | |
| } | |
| } | |
| /** | |
| * @private | |
| */ | |
| function markListeners(s, lists) { | |
| var i, list; | |
| for (i = 0; i < lists.length; ++i) { | |
| list = lists[i]; | |
| if (list.end !== s) { | |
| if (list.depsChanged !== undefined) { | |
| list.depsChanged.push(s); | |
| } | |
| list.shouldUpdate = true; | |
| } else { | |
| endStream(list); | |
| } | |
| } | |
| } | |
| /** | |
| * @private | |
| * Add dependencies to a stream | |
| * @param {Array<stream>} dependencies | |
| * @param {stream} stream | |
| */ | |
| function addListeners(deps, s) { | |
| for (var i = 0; i < deps.length; ++i) { | |
| deps[i].listeners.push(s); | |
| } | |
| } | |
| /** | |
| * @private | |
| * Removes an stream from a dependency array | |
| * @param {stream} stream | |
| * @param {Array<stream>} dependencies | |
| */ | |
| function removeListener(s, listeners) { | |
| var idx = listeners.indexOf(s); | |
| listeners[idx] = listeners[listeners.length - 1]; | |
| listeners.length--; | |
| } | |
| /** | |
| * @private | |
| * Detach a stream from its dependencies | |
| * @param {stream} stream | |
| */ | |
| function detachDeps(s) { | |
| for (var i = 0; i < s.deps.length; ++i) { | |
| removeListener(s, s.deps[i].listeners); | |
| } | |
| s.deps.length = 0; | |
| } | |
| /** | |
| * @private | |
| * Ends a stream | |
| */ | |
| function endStream(s) { | |
| if (s.deps !== undefined) detachDeps(s); | |
| if (s.end !== undefined) detachDeps(s.end); | |
| } | |
| /** | |
| * @private | |
| * transducer stream transformer | |
| */ | |
| function StreamTransformer() { } | |
| StreamTransformer.prototype['@@transducer/init'] = function() { }; | |
| StreamTransformer.prototype['@@transducer/result'] = function() { }; | |
| StreamTransformer.prototype['@@transducer/step'] = function(s, v) { return v; }; | |
| module.exports = flyd; | |
| },{"ramda/src/curryN":1}]},{},[]) | |
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm5vZGVfbW9kdWxlcy9yYW1kYS9zcmMvY3VycnlOLmpzIiwibm9kZV9tb2R1bGVzL3JhbWRhL3NyYy9pbnRlcm5hbC9fYXJpdHkuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTEuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTIuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeU4uanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19pc1BsYWNlaG9sZGVyLmpzIiwibGliL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsInZhciBfYXJpdHkgPSByZXF1aXJlKCcuL2ludGVybmFsL19hcml0eScpO1xudmFyIF9jdXJyeTEgPSByZXF1aXJlKCcuL2ludGVybmFsL19jdXJyeTEnKTtcbnZhciBfY3VycnkyID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9fY3VycnkyJyk7XG52YXIgX2N1cnJ5TiA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2N1cnJ5TicpO1xuXG5cbi8qKlxuICogUmV0dXJucyBhIGN1cnJpZWQgZXF1aXZhbGVudCBvZiB0aGUgcHJvdmlkZWQgZnVuY3Rpb24sIHdpdGggdGhlIHNwZWNpZmllZFxuICogYXJpdHkuIFRoZSBjdXJyaWVkIGZ1bmN0aW9uIGhhcyB0d28gdW51c3VhbCBjYXBhYmlsaXRpZXMuIEZpcnN0LCBpdHNcbiAqIGFyZ3VtZW50cyBuZWVkbid0IGJlIHByb3ZpZGVkIG9uZSBhdCBhIHRpbWUuIElmIGBnYCBpcyBgUi5jdXJyeU4oMywgZilgLCB0aGVcbiAqIGZvbGxvd2luZyBhcmUgZXF1aXZhbGVudDpcbiAqXG4gKiAgIC0gYGcoMSkoMikoMylgXG4gKiAgIC0gYGcoMSkoMiwgMylgXG4gKiAgIC0gYGcoMSwgMikoMylgXG4gKiAgIC0gYGcoMSwgMiwgMylgXG4gKlxuICogU2Vjb25kbHksIHRoZSBzcGVjaWFsIHBsYWNlaG9sZGVyIHZhbHVlIGBSLl9fYCBtYXkgYmUgdXNlZCB0byBzcGVjaWZ5XG4gKiBcImdhcHNcIiwgYWxsb3dpbmcgcGFydGlhbCBhcHBsaWNhdGlvbiBvZiBhbnkgY29tYmluYXRpb24gb2YgYXJndW1lbnRzLFxuICogcmVnYXJkbGVzcyBvZiB0aGVpciBwb3NpdGlvbnMuIElmIGBnYCBpcyBhcyBhYm92ZSBhbmQgYF9gIGlzIGBSLl9fYCwgdGhlXG4gKiBmb2xsb3dpbmcgYXJlIGVxdWl2YWxlbnQ6XG4gKlxuICogICAtIGBnKDEsIDIsIDMpYFxuICogICAtIGBnKF8sIDIsIDMpKDEpYFxuICogICAtIGBnKF8sIF8sIDMpKDEpKDIpYFxuICogICAtIGBnKF8sIF8sIDMpKDEsIDIpYFxuICogICAtIGBnKF8sIDIpKDEpKDMpYFxuICogICAtIGBnKF8sIDIpKDEsIDMpYFxuICogICAtIGBnKF8sIDIpKF8sIDMpKDEpYFxuICpcbiAqIEBmdW5jXG4gKiBAbWVtYmVyT2YgUlxuICogQHNpbmNlIHYwLjUuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAc2lnIE51bWJlciAtPiAoKiAtPiBhKSAtPiAoKiAtPiBhKVxuICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgYXJpdHkgZm9yIHRoZSByZXR1cm5lZCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjdXJyeS5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG5ldywgY3VycmllZCBmdW5jdGlvbi5cbiAqIEBzZWUgUi5jdXJyeVxuICogQGV4YW1wbGVcbiAqXG4gKiAgICAgIHZhciBzdW1BcmdzID0gKC4uLmFyZ3MpID0+IFIuc3VtKGFyZ3MpO1xuICpcbiAqICAgICAgdmFyIGN1cnJpZWRBZGRGb3VyTnVtYmVycyA9IFIuY3VycnlOKDQsIHN1bUFyZ3MpO1xuICogICAgICB2YXIgZiA9IGN1cnJpZWRBZGRGb3VyTnVtYmVycygxLCAyKTtcbiAqICAgICAgdmFyIGcgPSBmKDMpO1xuICogICAgICBnKDQpOyAvLz0+IDEwXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gX2N1cnJ5MihmdW5jdGlvbiBjdXJyeU4obGVuZ3RoLCBmbikge1xuICBpZiAobGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIF9jdXJyeTEoZm4pO1xuICB9XG4gIHJldHVybiBfYXJpdHkobGVuZ3RoLCBfY3VycnlOKGxlbmd0aCwgW10sIGZuKSk7XG59KTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2FyaXR5KG4sIGZuKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4gIHN3aXRjaCAobikge1xuICAgIGNhc2UgMDogcmV0dXJuIGZ1bmN0aW9uKCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbihhMCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbihhMCwgYTEpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMikgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDQ6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMykgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDU6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSA2OiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDc6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNikgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDg6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSA5OiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDEwOiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCwgYTkpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCB0byBfYXJpdHkgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyIG5vIGdyZWF0ZXIgdGhhbiB0ZW4nKTtcbiAgfVxufTtcbiIsInZhciBfaXNQbGFjZWhvbGRlciA9IHJlcXVpcmUoJy4vX2lzUGxhY2Vob2xkZXInKTtcblxuXG4vKipcbiAqIE9wdGltaXplZCBpbnRlcm5hbCBvbmUtYXJpdHkgY3VycnkgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeTEoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGYxKGEpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCBfaXNQbGFjZWhvbGRlcihhKSkge1xuICAgICAgcmV0dXJuIGYxO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH07XG59O1xuIiwidmFyIF9jdXJyeTEgPSByZXF1aXJlKCcuL19jdXJyeTEnKTtcbnZhciBfaXNQbGFjZWhvbGRlciA9IHJlcXVpcmUoJy4vX2lzUGxhY2Vob2xkZXInKTtcblxuXG4vKipcbiAqIE9wdGltaXplZCBpbnRlcm5hbCB0d28tYXJpdHkgY3VycnkgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeTIoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGYyKGEsIGIpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIGYyO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gX2lzUGxhY2Vob2xkZXIoYSkgPyBmMlxuICAgICAgICAgICAgIDogX2N1cnJ5MShmdW5jdGlvbihfYikgeyByZXR1cm4gZm4oYSwgX2IpOyB9KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBfaXNQbGFjZWhvbGRlcihhKSAmJiBfaXNQbGFjZWhvbGRlcihiKSA/IGYyXG4gICAgICAgICAgICAgOiBfaXNQbGFjZWhvbGRlcihhKSA/IF9jdXJyeTEoZnVuY3Rpb24oX2EpIHsgcmV0dXJuIGZuKF9hLCBiKTsgfSlcbiAgICAgICAgICAgICA6IF9pc1BsYWNlaG9sZGVyKGIpID8gX2N1cnJ5MShmdW5jdGlvbihfYikgeyByZXR1cm4gZm4oYSwgX2IpOyB9KVxuICAgICAgICAgICAgIDogZm4oYSwgYik7XG4gICAgfVxuICB9O1xufTtcbiIsInZhciBfYXJpdHkgPSByZXF1aXJlKCcuL19hcml0eScpO1xudmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogSW50ZXJuYWwgY3VycnlOIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGggVGhlIGFyaXR5IG9mIHRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gcmVjZWl2ZWQgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlY2VpdmVkIHRodXMgZmFyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeU4obGVuZ3RoLCByZWNlaXZlZCwgZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBjb21iaW5lZCA9IFtdO1xuICAgIHZhciBhcmdzSWR4ID0gMDtcbiAgICB2YXIgbGVmdCA9IGxlbmd0aDtcbiAgICB2YXIgY29tYmluZWRJZHggPSAwO1xuICAgIHdoaWxlIChjb21iaW5lZElkeCA8IHJlY2VpdmVkLmxlbmd0aCB8fCBhcmdzSWR4IDwgYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIGlmIChjb21iaW5lZElkeCA8IHJlY2VpdmVkLmxlbmd0aCAmJlxuICAgICAgICAgICghX2lzUGxhY2Vob2xkZXIocmVjZWl2ZWRbY29tYmluZWRJZHhdKSB8fFxuICAgICAgICAgICBhcmdzSWR4ID49IGFyZ3VtZW50cy5sZW5ndGgpKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlY2VpdmVkW2NvbWJpbmVkSWR4XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IGFyZ3VtZW50c1thcmdzSWR4XTtcbiAgICAgICAgYXJnc0lkeCArPSAxO1xuICAgICAgfVxuICAgICAgY29tYmluZWRbY29tYmluZWRJZHhdID0gcmVzdWx0O1xuICAgICAgaWYgKCFfaXNQbGFjZWhvbGRlcihyZXN1bHQpKSB7XG4gICAgICAgIGxlZnQgLT0gMTtcbiAgICAgIH1cbiAgICAgIGNvbWJpbmVkSWR4ICs9IDE7XG4gICAgfVxuICAgIHJldHVybiBsZWZ0IDw9IDAgPyBmbi5hcHBseSh0aGlzLCBjb21iaW5lZClcbiAgICAgICAgICAgICAgICAgICAgIDogX2FyaXR5KGxlZnQsIF9jdXJyeU4obGVuZ3RoLCBjb21iaW5lZCwgZm4pKTtcbiAgfTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9pc1BsYWNlaG9sZGVyKGEpIHtcbiAgcmV0dXJuIGEgIT0gbnVsbCAmJlxuICAgICAgICAgdHlwZW9mIGEgPT09ICdvYmplY3QnICYmXG4gICAgICAgICBhWydAQGZ1bmN0aW9uYWwvcGxhY2Vob2xkZXInXSA9PT0gdHJ1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjdXJyeU4gPSByZXF1aXJlKCdyYW1kYS9zcmMvY3VycnlOJyk7XG5cbi8vIFV0aWxpdHlcbmZ1bmN0aW9uIGlzRnVuY3Rpb24ob2JqKSB7XG4gIHJldHVybiAhIShvYmogJiYgb2JqLmNvbnN0cnVjdG9yICYmIG9iai5jYWxsICYmIG9iai5hcHBseSk7XG59XG5mdW5jdGlvbiB0cnVlRm4oKSB7IHJldHVybiB0cnVlOyB9XG5cbi8vIEdsb2JhbHNcbnZhciB0b1VwZGF0ZSA9IFtdO1xudmFyIGluU3RyZWFtO1xudmFyIG9yZGVyID0gW107XG52YXIgb3JkZXJOZXh0SWR4ID0gLTE7XG52YXIgZmx1c2hpbmcgPSBmYWxzZTtcblxuLyoqIEBuYW1lc3BhY2UgKi9cbnZhciBmbHlkID0ge31cblxuLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIEFQSSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gLy9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHN0cmVhbVxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBhIC0+IFN0cmVhbSBhYFxuICpcbiAqIEBuYW1lIGZseWQuc3RyZWFtXG4gKiBAcGFyYW0geyp9IGluaXRpYWxWYWx1ZSAtIChPcHRpb25hbCkgdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBuID0gZmx5ZC5zdHJlYW0oMSk7IC8vIFN0cmVhbSB3aXRoIGluaXRpYWwgdmFsdWUgYDFgXG4gKiB2YXIgcyA9IGZseWQuc3RyZWFtKCk7IC8vIFN0cmVhbSB3aXRoIG5vIGluaXRpYWwgdmFsdWVcbiAqL1xuZmx5ZC5zdHJlYW0gPSBmdW5jdGlvbihpbml0aWFsVmFsdWUpIHtcbiAgdmFyIGVuZFN0cmVhbSA9IGNyZWF0ZURlcGVuZGVudFN0cmVhbShbXSwgdHJ1ZUZuKTtcbiAgdmFyIHMgPSBjcmVhdGVTdHJlYW0oKTtcbiAgcy5lbmQgPSBlbmRTdHJlYW07XG4gIHMuZm5BcmdzID0gW107XG4gIGVuZFN0cmVhbS5saXN0ZW5lcnMucHVzaChzKTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSBzKGluaXRpYWxWYWx1ZSk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBkZXBlbmRlbnQgc3RyZWFtXG4gKlxuICogX19TaWduYXR1cmVfXzogYCguLi5TdHJlYW0gKiAtPiBTdHJlYW0gYiAtPiBiKSAtPiBbU3RyZWFtICpdIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIGZseWQuY29tYmluZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdXNlZCB0byBjb21iaW5lIHRoZSBzdHJlYW1zXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llcyAtIHRoZSBzdHJlYW1zIHRoYXQgdGhpcyBvbmUgZGVwZW5kcyBvblxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgZGVwZW5kZW50IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbjEgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBuMiA9IGZseWQuc3RyZWFtKDApO1xuICogdmFyIG1heCA9IGZseWQuY29tYmluZShmdW5jdGlvbihuMSwgbjIsIHNlbGYsIGNoYW5nZWQpIHtcbiAqICAgcmV0dXJuIG4xKCkgPiBuMigpID8gbjEoKSA6IG4yKCk7XG4gKiB9LCBbbjEsIG4yXSk7XG4gKi9cbmZseWQuY29tYmluZSA9IGN1cnJ5TigyLCBjb21iaW5lKTtcbmZ1bmN0aW9uIGNvbWJpbmUoZm4sIHN0cmVhbXMpIHtcbiAgdmFyIGksIHMsIGRlcHMsIGRlcEVuZFN0cmVhbXM7XG4gIHZhciBlbmRTdHJlYW0gPSBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oW10sIHRydWVGbik7XG4gIGRlcHMgPSBbXTsgZGVwRW5kU3RyZWFtcyA9IFtdO1xuICBmb3IgKGkgPSAwOyBpIDwgc3RyZWFtcy5sZW5ndGg7ICsraSkge1xuICAgIGlmIChzdHJlYW1zW2ldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlcHMucHVzaChzdHJlYW1zW2ldKTtcbiAgICAgIGlmIChzdHJlYW1zW2ldLmVuZCAhPT0gdW5kZWZpbmVkKSBkZXBFbmRTdHJlYW1zLnB1c2goc3RyZWFtc1tpXS5lbmQpO1xuICAgIH1cbiAgfVxuICBzID0gY3JlYXRlRGVwZW5kZW50U3RyZWFtKGRlcHMsIGZuKTtcbiAgcy5kZXBzQ2hhbmdlZCA9IFtdO1xuICBzLmZuQXJncyA9IHMuZGVwcy5jb25jYXQoW3MsIHMuZGVwc0NoYW5nZWRdKTtcbiAgcy5lbmQgPSBlbmRTdHJlYW07XG4gIGVuZFN0cmVhbS5saXN0ZW5lcnMucHVzaChzKTtcbiAgYWRkTGlzdGVuZXJzKGRlcEVuZFN0cmVhbXMsIGVuZFN0cmVhbSk7XG4gIGVuZFN0cmVhbS5kZXBzID0gZGVwRW5kU3RyZWFtcztcbiAgdXBkYXRlU3RyZWFtKHMpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgc3VwcGxpZWQgYXJndW1lbnQgaXMgYSBGbHlkIHN0cmVhbSBhbmQgYGZhbHNlYCBvdGhlcndpc2UuXG4gKlxuICogX19TaWduYXR1cmVfXzogYCogLT4gQm9vbGVhbmBcbiAqXG4gKiBAbmFtZSBmbHlkLmlzU3RyZWFtXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gdGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm4ge0Jvb2xlYW59IGB0cnVlYCBpZiBpcyBhIEZseWQgc3RyZWFtbiwgYGZhbHNlYCBvdGhlcndpc2VcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgxKTtcbiAqIHZhciBuID0gMTtcbiAqIGZseWQuaXNTdHJlYW0ocyk7IC8vPT4gdHJ1ZVxuICogZmx5ZC5pc1N0cmVhbShuKTsgLy89PiBmYWxzZVxuICovXG5mbHlkLmlzU3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHJldHVybiBpc0Z1bmN0aW9uKHN0cmVhbSkgJiYgJ2hhc1ZhbCcgaW4gc3RyZWFtO1xufVxuXG4vKipcbiAqIEludm9rZXMgdGhlIGJvZHkgKHRoZSBmdW5jdGlvbiB0byBjYWxjdWxhdGUgdGhlIHZhbHVlKSBvZiBhIGRlcGVuZGVudCBzdHJlYW1cbiAqXG4gKiBCeSBkZWZhdWx0IHRoZSBib2R5IG9mIGEgZGVwZW5kZW50IHN0cmVhbSBpcyBvbmx5IGNhbGxlZCB3aGVuIGFsbCB0aGUgc3RyZWFtc1xuICogdXBvbiB3aGljaCBpdCBkZXBlbmRzIGhhcyBhIHZhbHVlLiBgaW1tZWRpYXRlYCBjYW4gY2lyY3VtdmVudCB0aGlzIGJlaGF2aW91ci5cbiAqIEl0IGltbWVkaWF0ZWx5IGludm9rZXMgdGhlIGJvZHkgb2YgYSBkZXBlbmRlbnQgc3RyZWFtLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLmltbWVkaWF0ZVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBkZXBlbmRlbnQgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBzYW1lIHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgcyA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgaGFzSXRlbXMgPSBmbHlkLmltbWVkaWF0ZShmbHlkLmNvbWJpbmUoZnVuY3Rpb24ocykge1xuICogICByZXR1cm4gcygpICE9PSB1bmRlZmluZWQgJiYgcygpLmxlbmd0aCA+IDA7XG4gKiB9LCBbc10pO1xuICogY29uc29sZS5sb2coaGFzSXRlbXMoKSk7IC8vIGxvZ3MgYGZhbHNlYC4gSGFkIGBpbW1lZGlhdGVgIG5vdCBiZWVuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlZCBgaGFzSXRlbXMoKWAgd291bGQndmUgcmV0dXJuZWQgYHVuZGVmaW5lZGBcbiAqIHMoWzFdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGB0cnVlYC5cbiAqIHMoW10pO1xuICogY29uc29sZS5sb2coaGFzSXRlbXMoKSk7IC8vIGxvZ3MgYGZhbHNlYC5cbiAqL1xuZmx5ZC5pbW1lZGlhdGUgPSBmdW5jdGlvbihzKSB7XG4gIGlmIChzLmRlcHNNZXQgPT09IGZhbHNlKSB7XG4gICAgcy5kZXBzTWV0ID0gdHJ1ZTtcbiAgICB1cGRhdGVTdHJlYW0ocyk7XG4gIH1cbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQ2hhbmdlcyB3aGljaCBgZW5kc1N0cmVhbWAgc2hvdWxkIHRyaWdnZXIgdGhlIGVuZGluZyBvZiBgc2AuXG4gKlxuICogX19TaWduYXR1cmVfXzogYFN0cmVhbSBhIC0+IFN0cmVhbSBiIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIGZseWQuZW5kc09uXG4gKiBAcGFyYW0ge3N0cmVhbX0gZW5kU3RyZWFtIC0gdGhlIHN0cmVhbSB0byB0cmlnZ2VyIHRoZSBlbmRpbmdcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHRvIGJlIGVuZGVkIGJ5IHRoZSBlbmRTdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSB0aGUgc3RyZWFtIG1vZGlmaWVkIHRvIGJlIGVuZGVkIGJ5IGVuZFN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpO1xuICogdmFyIGtpbGxlciA9IGZseWQuc3RyZWFtKCk7XG4gKiAvLyBgZG91YmxlYCBlbmRzIHdoZW4gYG5gIGVuZHMgb3Igd2hlbiBga2lsbGVyYCBlbWl0cyBhbnkgdmFsdWVcbiAqIHZhciBkb3VibGUgPSBmbHlkLmVuZHNPbihmbHlkLm1lcmdlKG4uZW5kLCBraWxsZXIpLCBmbHlkLmNvbWJpbmUoZnVuY3Rpb24obikge1xuICogICByZXR1cm4gMiAqIG4oKTtcbiAqIH0sIFtuXSk7XG4qL1xuZmx5ZC5lbmRzT24gPSBmdW5jdGlvbihlbmRTLCBzKSB7XG4gIGRldGFjaERlcHMocy5lbmQpO1xuICBlbmRTLmxpc3RlbmVycy5wdXNoKHMuZW5kKTtcbiAgcy5lbmQuZGVwcy5wdXNoKGVuZFMpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBNYXAgYSBzdHJlYW1cbiAqXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSBjb25zaXN0aW5nIG9mIGV2ZXJ5IHZhbHVlIGZyb20gYHNgIHBhc3NlZCB0aHJvdWdoXG4gKiBgZm5gLiBJLmUuIGBtYXBgIGNyZWF0ZXMgYSBuZXcgc3RyZWFtIHRoYXQgbGlzdGVucyB0byBgc2AgYW5kXG4gKiBhcHBsaWVzIGBmbmAgdG8gZXZlcnkgbmV3IHZhbHVlLlxuICogX19TaWduYXR1cmVfXzogYChhIC0+IHJlc3VsdCkgLT4gU3RyZWFtIGEgLT4gU3RyZWFtIHJlc3VsdGBcbiAqXG4gKiBAbmFtZSBmbHlkLm1hcFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyB0aGUgZWxlbWVudHMgb2YgdGhlIG5ldyBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHRvIG1hcFxuICogQHJldHVybiB7c3RyZWFtfSBhIG5ldyBzdHJlYW0gd2l0aCB0aGUgbWFwcGVkIHZhbHVlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbnVtYmVycyA9IGZseWQuc3RyZWFtKDApO1xuICogdmFyIHNxdWFyZWROdW1iZXJzID0gZmx5ZC5tYXAoZnVuY3Rpb24obikgeyByZXR1cm4gbipuOyB9LCBudW1iZXJzKTtcbiAqL1xuLy8gTGlicmFyeSBmdW5jdGlvbnMgdXNlIHNlbGYgY2FsbGJhY2sgdG8gYWNjZXB0IChudWxsLCB1bmRlZmluZWQpIHVwZGF0ZSB0cmlnZ2Vycy5cbmZseWQubWFwID0gY3VycnlOKDIsIGZ1bmN0aW9uKGYsIHMpIHtcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24ocywgc2VsZikgeyBzZWxmKGYocy52YWwpKTsgfSwgW3NdKTtcbn0pXG5cbi8qKlxuICogTGlzdGVuIHRvIHN0cmVhbSBldmVudHNcbiAqXG4gKiBTaW1pbGFyIHRvIGBtYXBgIGV4Y2VwdCB0aGF0IHRoZSByZXR1cm5lZCBzdHJlYW0gaXMgZW1wdHkuIFVzZSBgb25gIGZvciBkb2luZ1xuICogc2lkZSBlZmZlY3RzIGluIHJlYWN0aW9uIHRvIHN0cmVhbSBjaGFuZ2VzLiBVc2UgdGhlIHJldHVybmVkIHN0cmVhbSBvbmx5IGlmIHlvdVxuICogbmVlZCB0byBtYW51YWxseSBlbmQgaXQuXG4gKlxuICogX19TaWduYXR1cmVfXzogYChhIC0+IHJlc3VsdCkgLT4gU3RyZWFtIGEgLT4gU3RyZWFtIHVuZGVmaW5lZGBcbiAqXG4gKiBAbmFtZSBmbHlkLm9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYiAtIHRoZSBjYWxsYmFja1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gYW4gZW1wdHkgc3RyZWFtIChjYW4gYmUgZW5kZWQpXG4gKi9cbmZseWQub24gPSBjdXJyeU4oMiwgZnVuY3Rpb24oZiwgcykge1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzKSB7IGYocy52YWwpOyB9LCBbc10pO1xufSlcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHN0cmVhbSB3aXRoIHRoZSByZXN1bHRzIG9mIGNhbGxpbmcgdGhlIGZ1bmN0aW9uIG9uIGV2ZXJ5IGluY29taW5nXG4gKiBzdHJlYW0gd2l0aCBhbmQgYWNjdW11bGF0b3IgYW5kIHRoZSBpbmNvbWluZyB2YWx1ZS5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgKGEgLT4gYiAtPiBhKSAtPiBhIC0+IFN0cmVhbSBiIC0+IFN0cmVhbSBhYFxuICpcbiAqIEBuYW1lIGZseWQuc2NhblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdG8gY2FsbFxuICogQHBhcmFtIHsqfSB2YWwgLSB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgYWNjdW11bGF0b3JcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHNvdXJjZVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgbmV3IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbnVtYmVycyA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgc3VtID0gZmx5ZC5zY2FuKGZ1bmN0aW9uKHN1bSwgbikgeyByZXR1cm4gc3VtK247IH0sIDAsIG51bWJlcnMpO1xuICogbnVtYmVycygyKSgzKSg1KTtcbiAqIHN1bSgpOyAvLyAxMFxuICovXG5mbHlkLnNjYW4gPSBjdXJyeU4oMywgZnVuY3Rpb24oZiwgYWNjLCBzKSB7XG4gIHZhciBucyA9IGNvbWJpbmUoZnVuY3Rpb24ocywgc2VsZikge1xuICAgIHNlbGYoYWNjID0gZihhY2MsIHMudmFsKSk7XG4gIH0sIFtzXSk7XG4gIGlmICghbnMuaGFzVmFsKSBucyhhY2MpO1xuICByZXR1cm4gbnM7XG59KTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHN0cmVhbSBkb3duIHdoaWNoIGFsbCB2YWx1ZXMgZnJvbSBib3RoIGBzdHJlYW0xYCBhbmQgYHN0cmVhbTJgXG4gKiB3aWxsIGJlIHNlbnQuXG4gKlxuICogX19TaWduYXR1cmVfXzogYFN0cmVhbSBhIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSBhYFxuICpcbiAqIEBuYW1lIGZseWQubWVyZ2VcbiAqIEBwYXJhbSB7c3RyZWFtfSBzb3VyY2UxIC0gb25lIHN0cmVhbSB0byBiZSBtZXJnZWRcbiAqIEBwYXJhbSB7c3RyZWFtfSBzb3VyY2UyIC0gdGhlIG90aGVyIHN0cmVhbSB0byBiZSBtZXJnZWRcbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBzdHJlYW0gd2l0aCB0aGUgdmFsdWVzIGZyb20gYm90aCBzb3VyY2VzXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBidG4xQ2xpY2tzID0gZmx5ZC5zdHJlYW0oKTtcbiAqIGJ1dHRvbjFFbG0uYWRkRXZlbnRMaXN0ZW5lcihidG4xQ2xpY2tzKTtcbiAqIHZhciBidG4yQ2xpY2tzID0gZmx5ZC5zdHJlYW0oKTtcbiAqIGJ1dHRvbjJFbG0uYWRkRXZlbnRMaXN0ZW5lcihidG4yQ2xpY2tzKTtcbiAqIHZhciBhbGxDbGlja3MgPSBmbHlkLm1lcmdlKGJ0bjFDbGlja3MsIGJ0bjJDbGlja3MpO1xuICovXG5mbHlkLm1lcmdlID0gY3VycnlOKDIsIGZ1bmN0aW9uKHMxLCBzMikge1xuICB2YXIgcyA9IGZseWQuaW1tZWRpYXRlKGNvbWJpbmUoZnVuY3Rpb24oczEsIHMyLCBzZWxmLCBjaGFuZ2VkKSB7XG4gICAgaWYgKGNoYW5nZWRbMF0pIHtcbiAgICAgIHNlbGYoY2hhbmdlZFswXSgpKTtcbiAgICB9IGVsc2UgaWYgKHMxLmhhc1ZhbCkge1xuICAgICAgc2VsZihzMS52YWwpO1xuICAgIH0gZWxzZSBpZiAoczIuaGFzVmFsKSB7XG4gICAgICBzZWxmKHMyLnZhbCk7XG4gICAgfVxuICB9LCBbczEsIHMyXSkpO1xuICBmbHlkLmVuZHNPbihjb21iaW5lKGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9LCBbczEuZW5kLCBzMi5lbmRdKSwgcyk7XG4gIHJldHVybiBzO1xufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gcmVzdWx0aW5nIGZyb20gYXBwbHlpbmcgYHRyYW5zZHVjZXJgIHRvIGBzdHJlYW1gLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBUcmFuc2R1Y2VyIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIGZseWQudHJhbnNkdWNlXG4gKiBAcGFyYW0ge1RyYW5zZHVjZXJ9IHhmb3JtIC0gdGhlIHRyYW5zZHVjZXIgdHJhbnNmb3JtYXRpb25cbiAqIEBwYXJhbSB7c3RyZWFtfSBzb3VyY2UgLSB0aGUgc3RyZWFtIHNvdXJjZVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgbmV3IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgdCA9IHJlcXVpcmUoJ3RyYW5zZHVjZXJzLmpzJyk7XG4gKlxuICogdmFyIHJlc3VsdHMgPSBbXTtcbiAqIHZhciBzMSA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgdHggPSB0LmNvbXBvc2UodC5tYXAoZnVuY3Rpb24oeCkgeyByZXR1cm4geCAqIDI7IH0pLCB0LmRlZHVwZSgpKTtcbiAqIHZhciBzMiA9IGZseWQudHJhbnNkdWNlKHR4LCBzMSk7XG4gKiBmbHlkLmNvbWJpbmUoZnVuY3Rpb24oczIpIHsgcmVzdWx0cy5wdXNoKHMyKCkpOyB9LCBbczJdKTtcbiAqIHMxKDEpKDEpKDIpKDMpKDMpKDMpKDQpO1xuICogcmVzdWx0czsgLy8gPT4gWzIsIDQsIDYsIDhdXG4gKi9cbmZseWQudHJhbnNkdWNlID0gY3VycnlOKDIsIGZ1bmN0aW9uKHhmb3JtLCBzb3VyY2UpIHtcbiAgeGZvcm0gPSB4Zm9ybShuZXcgU3RyZWFtVHJhbnNmb3JtZXIoKSk7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHNvdXJjZSwgc2VsZikge1xuICAgIHZhciByZXMgPSB4Zm9ybVsnQEB0cmFuc2R1Y2VyL3N0ZXAnXSh1bmRlZmluZWQsIHNvdXJjZS52YWwpO1xuICAgIGlmIChyZXMgJiYgcmVzWydAQHRyYW5zZHVjZXIvcmVkdWNlZCddID09PSB0cnVlKSB7XG4gICAgICBzZWxmLmVuZCh0cnVlKTtcbiAgICAgIHJldHVybiByZXNbJ0BAdHJhbnNkdWNlci92YWx1ZSddO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgfSwgW3NvdXJjZV0pO1xufSk7XG5cbi8qKlxuICogUmV0dXJucyBgZm5gIGN1cnJpZWQgdG8gYG5gLiBVc2UgdGhpcyBmdW5jdGlvbiB0byBjdXJyeSBmdW5jdGlvbnMgZXhwb3NlZCBieVxuICogbW9kdWxlcyBmb3IgRmx5ZC5cbiAqXG4gKiBAbmFtZSBmbHlkLmN1cnJ5TlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGFyaXR5IC0gdGhlIGZ1bmN0aW9uIGFyaXR5XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBjdXJyeVxuICogQHJldHVybiB7RnVuY3Rpb259IHRoZSBjdXJyaWVkIGZ1bmN0aW9uXG4gKlxuICogQGV4YW1wbGVcbiAqIGZ1bmN0aW9uIGFkZCh4LCB5KSB7IHJldHVybiB4ICsgeTsgfTtcbiAqIHZhciBhID0gZmx5ZC5jdXJyeU4oMiwgYWRkKTtcbiAqIGEoMikoNCkgLy8gPT4gNlxuICovXG5mbHlkLmN1cnJ5TiA9IGN1cnJ5TlxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIGlkZW50aWNhbCB0byB0aGUgb3JpZ2luYWwgZXhjZXB0IGV2ZXJ5XG4gKiB2YWx1ZSB3aWxsIGJlIHBhc3NlZCB0aHJvdWdoIGBmYC5cbiAqXG4gKiBfTm90ZTpfIFRoaXMgZnVuY3Rpb24gaXMgaW5jbHVkZWQgaW4gb3JkZXIgdG8gc3VwcG9ydCB0aGUgZmFudGFzeSBsYW5kXG4gKiBzcGVjaWZpY2F0aW9uLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IENhbGxlZCBib3VuZCB0byBgU3RyZWFtIGFgOiBgKGEgLT4gYikgLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgc3RyZWFtLm1hcFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY3Rpb24gLSB0aGUgZnVuY3Rpb24gdG8gYXBwbHlcbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBuZXcgc3RyZWFtIHdpdGggdGhlIHZhbHVlcyBtYXBwZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBzcXVhcmVkTnVtYmVycyA9IG51bWJlcnMubWFwKGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4qbjsgfSk7XG4gKi9cbmZ1bmN0aW9uIGJvdW5kTWFwKGYpIHsgcmV0dXJuIGZseWQubWFwKGYsIHRoaXMpOyB9XG5cbi8qKlxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gd2hpY2ggaXMgdGhlIHJlc3VsdCBvZiBhcHBseWluZyB0aGVcbiAqIGZ1bmN0aW9ucyBmcm9tIGB0aGlzYCBzdHJlYW0gdG8gdGhlIHZhbHVlcyBpbiBgc3RyZWFtYCBwYXJhbWV0ZXIuXG4gKlxuICogYHRoaXNgIHN0cmVhbSBtdXN0IGJlIGEgc3RyZWFtIG9mIGZ1bmN0aW9ucy5cbiAqXG4gKiBfTm90ZTpfIFRoaXMgZnVuY3Rpb24gaXMgaW5jbHVkZWQgaW4gb3JkZXIgdG8gc3VwcG9ydCB0aGUgZmFudGFzeSBsYW5kXG4gKiBzcGVjaWZpY2F0aW9uLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IENhbGxlZCBib3VuZCB0byBgU3RyZWFtIChhIC0+IGIpYDogYGEgLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgc3RyZWFtLmFwXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHZhbHVlcyBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBuZXcgc3RyYW0gd2l0aCB0aGUgZnVuY3Rpb25zIGFwcGxpZWQgdG8gdmFsdWVzXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBmbHlkLmN1cnJ5TigyLCBmdW5jdGlvbih4LCB5KSB7IHJldHVybiB4ICsgeTsgfSk7XG4gKiB2YXIgbnVtYmVyczEgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIG51bWJlcnMyID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBhZGRUb051bWJlcnMxID0gZmx5ZC5tYXAoYWRkLCBudW1iZXJzMSk7XG4gKiB2YXIgYWRkZWQgPSBhZGRUb051bWJlcnMxLmFwKG51bWJlcnMyKTtcbiAqL1xuZnVuY3Rpb24gYXAoczIpIHtcbiAgdmFyIHMxID0gdGhpcztcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24oczEsIHMyLCBzZWxmKSB7IHNlbGYoczEudmFsKHMyLnZhbCkpOyB9LCBbczEsIHMyXSk7XG59XG5cbi8qKlxuICogR2V0IGEgaHVtYW4gcmVhZGFibGUgdmlldyBvZiBhIHN0cmVhbVxuICogQG5hbWUgc3RyZWFtLnRvU3RyaW5nXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSBzdHJlYW0gc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gKi9cbmZ1bmN0aW9uIHN0cmVhbVRvU3RyaW5nKCkge1xuICByZXR1cm4gJ3N0cmVhbSgnICsgdGhpcy52YWwgKyAnKSc7XG59XG5cbi8qKlxuICogQG5hbWUgc3RyZWFtLmVuZFxuICogQG1lbWJlcm9mIHN0cmVhbVxuICogQSBzdHJlYW0gdGhhdCBlbWl0cyBgdHJ1ZWAgd2hlbiB0aGUgc3RyZWFtIGVuZHMuIElmIGB0cnVlYCBpcyBwdXNoZWQgZG93biB0aGVcbiAqIHN0cmVhbSB0aGUgcGFyZW50IHN0cmVhbSBlbmRzLlxuICovXG5cbi8qKlxuICogQG5hbWUgc3RyZWFtLm9mXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiBzdHJlYW1cbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIHdpdGggYHZhbHVlYCBhcyBpdHMgaW5pdGlhbCB2YWx1ZS4gSXQgaXMgaWRlbnRpY2FsIHRvXG4gKiBjYWxsaW5nIGBmbHlkLnN0cmVhbWAgd2l0aCBvbmUgYXJndW1lbnQuXG4gKlxuICogX19TaWduYXR1cmVfXzogQ2FsbGVkIGJvdW5kIHRvIGBTdHJlYW0gKGEpYDogYGIgLT4gU3RyZWFtIGJgXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIHRoZSBpbml0aWFsIHZhbHVlXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBuZXcgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBuID0gZmx5ZC5zdHJlYW0oMSk7XG4gKiB2YXIgbSA9IG4ub2YoMSk7XG4gKi9cblxuLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIFBSSVZBVEUgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIC8vXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDcmVhdGUgYSBzdHJlYW0gd2l0aCBubyBkZXBlbmRlbmNpZXMgYW5kIG5vIHZhbHVlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gYSBmbHlkIHN0cmVhbVxuICovXG5mdW5jdGlvbiBjcmVhdGVTdHJlYW0oKSB7XG4gIGZ1bmN0aW9uIHMobikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gcy52YWxcbiAgICB1cGRhdGVTdHJlYW1WYWx1ZShzLCBuKVxuICAgIHJldHVybiBzXG4gIH1cbiAgcy5oYXNWYWwgPSBmYWxzZTtcbiAgcy52YWwgPSB1bmRlZmluZWQ7XG4gIHMudmFscyA9IFtdO1xuICBzLmxpc3RlbmVycyA9IFtdO1xuICBzLnF1ZXVlZCA9IGZhbHNlO1xuICBzLmVuZCA9IHVuZGVmaW5lZDtcbiAgcy5tYXAgPSBib3VuZE1hcDtcbiAgcy5hcCA9IGFwO1xuICBzLm9mID0gZmx5ZC5zdHJlYW07XG4gIHMudG9TdHJpbmcgPSBzdHJlYW1Ub1N0cmluZztcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIENyZWF0ZSBhIGRlcGVuZGVudCBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzIC0gYW4gYXJyYXkgb2YgdGhlIHN0cmVhbXNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBuZXcgc3RyZWFtIHZhbHVlXG4gKiBmcm9tIHRoZSBkZXBlbmRlbmNpZXNcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIGNyZWF0ZWQgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZURlcGVuZGVudFN0cmVhbShkZXBzLCBmbikge1xuICB2YXIgcyA9IGNyZWF0ZVN0cmVhbSgpO1xuICBzLmZuID0gZm47XG4gIHMuZGVwcyA9IGRlcHM7XG4gIHMuZGVwc01ldCA9IGZhbHNlO1xuICBzLmRlcHNDaGFuZ2VkID0gZGVwcy5sZW5ndGggPiAwID8gW10gOiB1bmRlZmluZWQ7XG4gIHMuc2hvdWxkVXBkYXRlID0gZmFsc2U7XG4gIGFkZExpc3RlbmVycyhkZXBzLCBzKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIENoZWNrIGlmIGFsbCB0aGUgZGVwZW5kZW5jaWVzIGhhdmUgdmFsdWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBjaGVjayBkZXBlbmNlbmNpZXMgZnJvbVxuICogQHJldHVybiB7Qm9vbGVhbn0gYHRydWVgIGlmIGFsbCBkZXBlbmRlbmNpZXMgaGF2ZSB2YWxlcywgYGZhbHNlYCBvdGhlcndpc2VcbiAqL1xuZnVuY3Rpb24gaW5pdGlhbERlcHNOb3RNZXQoc3RyZWFtKSB7XG4gIHN0cmVhbS5kZXBzTWV0ID0gc3RyZWFtLmRlcHMuZXZlcnkoZnVuY3Rpb24ocykge1xuICAgIHJldHVybiBzLmhhc1ZhbDtcbiAgfSk7XG4gIHJldHVybiAhc3RyZWFtLmRlcHNNZXQ7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFVwZGF0ZSBhIGRlcGVuZGVudCBzdHJlYW0gdXNpbmcgaXRzIGRlcGVuZGVuY2llcyBpbiBhbiBhdG9taWMgd2F5XG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byB1cGRhdGVcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU3RyZWFtKHMpIHtcbiAgaWYgKChzLmRlcHNNZXQgIT09IHRydWUgJiYgaW5pdGlhbERlcHNOb3RNZXQocykpIHx8XG4gICAgICAocy5lbmQgIT09IHVuZGVmaW5lZCAmJiBzLmVuZC52YWwgPT09IHRydWUpKSByZXR1cm47XG4gIGlmIChpblN0cmVhbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdG9VcGRhdGUucHVzaChzKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaW5TdHJlYW0gPSBzO1xuICBpZiAocy5kZXBzQ2hhbmdlZCkgcy5mbkFyZ3Nbcy5mbkFyZ3MubGVuZ3RoIC0gMV0gPSBzLmRlcHNDaGFuZ2VkO1xuICB2YXIgcmV0dXJuVmFsID0gcy5mbi5hcHBseShzLmZuLCBzLmZuQXJncyk7XG4gIGlmIChyZXR1cm5WYWwgIT09IHVuZGVmaW5lZCkge1xuICAgIHMocmV0dXJuVmFsKTtcbiAgfVxuICBpblN0cmVhbSA9IHVuZGVmaW5lZDtcbiAgaWYgKHMuZGVwc0NoYW5nZWQgIT09IHVuZGVmaW5lZCkgcy5kZXBzQ2hhbmdlZCA9IFtdO1xuICBzLnNob3VsZFVwZGF0ZSA9IGZhbHNlO1xuICBpZiAoZmx1c2hpbmcgPT09IGZhbHNlKSBmbHVzaFVwZGF0ZSgpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBVcGRhdGUgdGhlIGRlcGVuZGVuY2llcyBvZiBhIHN0cmVhbVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICovXG5mdW5jdGlvbiB1cGRhdGVEZXBzKHMpIHtcbiAgdmFyIGksIG8sIGxpc3RcbiAgdmFyIGxpc3RlbmVycyA9IHMubGlzdGVuZXJzO1xuICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgKytpKSB7XG4gICAgbGlzdCA9IGxpc3RlbmVyc1tpXTtcbiAgICBpZiAobGlzdC5lbmQgPT09IHMpIHtcbiAgICAgIGVuZFN0cmVhbShsaXN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGxpc3QuZGVwc0NoYW5nZWQgIT09IHVuZGVmaW5lZCkgbGlzdC5kZXBzQ2hhbmdlZC5wdXNoKHMpO1xuICAgICAgbGlzdC5zaG91bGRVcGRhdGUgPSB0cnVlO1xuICAgICAgZmluZERlcHMobGlzdCk7XG4gICAgfVxuICB9XG4gIGZvciAoOyBvcmRlck5leHRJZHggPj0gMDsgLS1vcmRlck5leHRJZHgpIHtcbiAgICBvID0gb3JkZXJbb3JkZXJOZXh0SWR4XTtcbiAgICBpZiAoby5zaG91bGRVcGRhdGUgPT09IHRydWUpIHVwZGF0ZVN0cmVhbShvKTtcbiAgICBvLnF1ZXVlZCA9IGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEFkZCBzdHJlYW0gZGVwZW5kZW5jaWVzIHRvIHRoZSBnbG9iYWwgYG9yZGVyYCBxdWV1ZS5cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBzZWUgdXBkYXRlRGVwc1xuICovXG5mdW5jdGlvbiBmaW5kRGVwcyhzKSB7XG4gIHZhciBpXG4gIHZhciBsaXN0ZW5lcnMgPSBzLmxpc3RlbmVycztcbiAgaWYgKHMucXVldWVkID09PSBmYWxzZSkge1xuICAgIHMucXVldWVkID0gdHJ1ZTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgKytpKSB7XG4gICAgICBmaW5kRGVwcyhsaXN0ZW5lcnNbaV0pO1xuICAgIH1cbiAgICBvcmRlclsrK29yZGVyTmV4dElkeF0gPSBzO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZmx1c2hVcGRhdGUoKSB7XG4gIGZsdXNoaW5nID0gdHJ1ZTtcbiAgd2hpbGUgKHRvVXBkYXRlLmxlbmd0aCA+IDApIHtcbiAgICB2YXIgcyA9IHRvVXBkYXRlLnNoaWZ0KCk7XG4gICAgaWYgKHMudmFscy5sZW5ndGggPiAwKSBzLnZhbCA9IHMudmFscy5zaGlmdCgpO1xuICAgIHVwZGF0ZURlcHMocyk7XG4gIH1cbiAgZmx1c2hpbmcgPSBmYWxzZTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogUHVzaCBkb3duIGEgdmFsdWUgaW50byBhIHN0cmVhbVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICovXG5mdW5jdGlvbiB1cGRhdGVTdHJlYW1WYWx1ZShzLCBuKSB7XG4gIGlmIChuICE9PSB1bmRlZmluZWQgJiYgbiAhPT0gbnVsbCAmJiBpc0Z1bmN0aW9uKG4udGhlbikpIHtcbiAgICBuLnRoZW4ocyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHMudmFsID0gbjtcbiAgcy5oYXNWYWwgPSB0cnVlO1xuICBpZiAoaW5TdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICB1cGRhdGVEZXBzKHMpO1xuICAgIGlmICh0b1VwZGF0ZS5sZW5ndGggPiAwKSBmbHVzaFVwZGF0ZSgpOyBlbHNlIGZsdXNoaW5nID0gZmFsc2U7XG4gIH0gZWxzZSBpZiAoaW5TdHJlYW0gPT09IHMpIHtcbiAgICBtYXJrTGlzdGVuZXJzKHMsIHMubGlzdGVuZXJzKTtcbiAgfSBlbHNlIHtcbiAgICBzLnZhbHMucHVzaChuKTtcbiAgICB0b1VwZGF0ZS5wdXNoKHMpO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gbWFya0xpc3RlbmVycyhzLCBsaXN0cykge1xuICB2YXIgaSwgbGlzdDtcbiAgZm9yIChpID0gMDsgaSA8IGxpc3RzLmxlbmd0aDsgKytpKSB7XG4gICAgbGlzdCA9IGxpc3RzW2ldO1xuICAgIGlmIChsaXN0LmVuZCAhPT0gcykge1xuICAgICAgaWYgKGxpc3QuZGVwc0NoYW5nZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsaXN0LmRlcHNDaGFuZ2VkLnB1c2gocyk7XG4gICAgICB9XG4gICAgICBsaXN0LnNob3VsZFVwZGF0ZSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVuZFN0cmVhbShsaXN0KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQWRkIGRlcGVuZGVuY2llcyB0byBhIHN0cmVhbVxuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXNcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gYWRkTGlzdGVuZXJzKGRlcHMsIHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZXBzLmxlbmd0aDsgKytpKSB7XG4gICAgZGVwc1tpXS5saXN0ZW5lcnMucHVzaChzKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBSZW1vdmVzIGFuIHN0cmVhbSBmcm9tIGEgZGVwZW5kZW5jeSBhcnJheVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXNcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIocywgbGlzdGVuZXJzKSB7XG4gIHZhciBpZHggPSBsaXN0ZW5lcnMuaW5kZXhPZihzKTtcbiAgbGlzdGVuZXJzW2lkeF0gPSBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdO1xuICBsaXN0ZW5lcnMubGVuZ3RoLS07XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIERldGFjaCBhIHN0cmVhbSBmcm9tIGl0cyBkZXBlbmRlbmNpZXNcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gZGV0YWNoRGVwcyhzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcy5kZXBzLmxlbmd0aDsgKytpKSB7XG4gICAgcmVtb3ZlTGlzdGVuZXIocywgcy5kZXBzW2ldLmxpc3RlbmVycyk7XG4gIH1cbiAgcy5kZXBzLmxlbmd0aCA9IDA7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEVuZHMgYSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gZW5kU3RyZWFtKHMpIHtcbiAgaWYgKHMuZGVwcyAhPT0gdW5kZWZpbmVkKSBkZXRhY2hEZXBzKHMpO1xuICBpZiAocy5lbmQgIT09IHVuZGVmaW5lZCkgZGV0YWNoRGVwcyhzLmVuZCk7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIHRyYW5zZHVjZXIgc3RyZWFtIHRyYW5zZm9ybWVyXG4gKi9cbmZ1bmN0aW9uIFN0cmVhbVRyYW5zZm9ybWVyKCkgeyB9XG5TdHJlYW1UcmFuc2Zvcm1lci5wcm90b3R5cGVbJ0BAdHJhbnNkdWNlci9pbml0J10gPSBmdW5jdGlvbigpIHsgfTtcblN0cmVhbVRyYW5zZm9ybWVyLnByb3RvdHlwZVsnQEB0cmFuc2R1Y2VyL3Jlc3VsdCddID0gZnVuY3Rpb24oKSB7IH07XG5TdHJlYW1UcmFuc2Zvcm1lci5wcm90b3R5cGVbJ0BAdHJhbnNkdWNlci9zdGVwJ10gPSBmdW5jdGlvbihzLCB2KSB7IHJldHVybiB2OyB9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZseWQ7XG4iXX0= | |
| require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
| 'use strict'; | |
| var curryN = require('ramda/src/curryN'); | |
| // Utility | |
| function isFunction(obj) { | |
| return !!(obj && obj.constructor && obj.call && obj.apply); | |
| } | |
| function trueFn() { return true; } | |
| // Globals | |
| var toUpdate = []; | |
| var inStream; | |
| var order = []; | |
| var orderNextIdx = -1; | |
| var flushing = false; | |
| /** @namespace */ | |
| var flyd = {} | |
| // /////////////////////////// API ///////////////////////////////// // | |
| /** | |
| * Creates a new stream | |
| * | |
| * __Signature__: `a -> Stream a` | |
| * | |
| * @name flyd.stream | |
| * @param {*} initialValue - (Optional) the initial value of the stream | |
| * @return {stream} the stream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); // Stream with initial value `1` | |
| * var s = flyd.stream(); // Stream with no initial value | |
| */ | |
| flyd.stream = function(initialValue) { | |
| var endStream = createDependentStream([], trueFn); | |
| var s = createStream(); | |
| s.end = endStream; | |
| s.fnArgs = []; | |
| endStream.listeners.push(s); | |
| if (arguments.length > 0) s(initialValue); | |
| return s; | |
| } | |
| /** | |
| * Create a new dependent stream | |
| * | |
| * __Signature__: `(...Stream * -> Stream b -> b) -> [Stream *] -> Stream b` | |
| * | |
| * @name flyd.combine | |
| * @param {Function} fn - the function used to combine the streams | |
| * @param {Array<stream>} dependencies - the streams that this one depends on | |
| * @return {stream} the dependent stream | |
| * | |
| * @example | |
| * var n1 = flyd.stream(0); | |
| * var n2 = flyd.stream(0); | |
| * var max = flyd.combine(function(n1, n2, self, changed) { | |
| * return n1() > n2() ? n1() : n2(); | |
| * }, [n1, n2]); | |
| */ | |
| flyd.combine = curryN(2, combine); | |
| function combine(fn, streams) { | |
| var i, s, deps, depEndStreams; | |
| var endStream = createDependentStream([], trueFn); | |
| deps = []; depEndStreams = []; | |
| for (i = 0; i < streams.length; ++i) { | |
| if (streams[i] !== undefined) { | |
| deps.push(streams[i]); | |
| if (streams[i].end !== undefined) depEndStreams.push(streams[i].end); | |
| } | |
| } | |
| s = createDependentStream(deps, fn); | |
| s.depsChanged = []; | |
| s.fnArgs = s.deps.concat([s, s.depsChanged]); | |
| s.end = endStream; | |
| endStream.listeners.push(s); | |
| addListeners(depEndStreams, endStream); | |
| endStream.deps = depEndStreams; | |
| updateStream(s); | |
| return s; | |
| } | |
| /** | |
| * Returns `true` if the supplied argument is a Flyd stream and `false` otherwise. | |
| * | |
| * __Signature__: `* -> Boolean` | |
| * | |
| * @name flyd.isStream | |
| * @param {*} value - the value to test | |
| * @return {Boolean} `true` if is a Flyd streamn, `false` otherwise | |
| * | |
| * @example | |
| * var s = flyd.stream(1); | |
| * var n = 1; | |
| * flyd.isStream(s); //=> true | |
| * flyd.isStream(n); //=> false | |
| */ | |
| flyd.isStream = function(stream) { | |
| return isFunction(stream) && 'hasVal' in stream; | |
| } | |
| /** | |
| * Invokes the body (the function to calculate the value) of a dependent stream | |
| * | |
| * By default the body of a dependent stream is only called when all the streams | |
| * upon which it depends has a value. `immediate` can circumvent this behaviour. | |
| * It immediately invokes the body of a dependent stream. | |
| * | |
| * __Signature__: `Stream a -> Stream a` | |
| * | |
| * @name flyd.immediate | |
| * @param {stream} stream - the dependent stream | |
| * @return {stream} the same stream | |
| * | |
| * @example | |
| * var s = flyd.stream(); | |
| * var hasItems = flyd.immediate(flyd.combine(function(s) { | |
| * return s() !== undefined && s().length > 0; | |
| * }, [s]); | |
| * console.log(hasItems()); // logs `false`. Had `immediate` not been | |
| * // used `hasItems()` would've returned `undefined` | |
| * s([1]); | |
| * console.log(hasItems()); // logs `true`. | |
| * s([]); | |
| * console.log(hasItems()); // logs `false`. | |
| */ | |
| flyd.immediate = function(s) { | |
| if (s.depsMet === false) { | |
| s.depsMet = true; | |
| updateStream(s); | |
| } | |
| return s; | |
| } | |
| /** | |
| * Changes which `endsStream` should trigger the ending of `s`. | |
| * | |
| * __Signature__: `Stream a -> Stream b -> Stream b` | |
| * | |
| * @name flyd.endsOn | |
| * @param {stream} endStream - the stream to trigger the ending | |
| * @param {stream} stream - the stream to be ended by the endStream | |
| * @param {stream} the stream modified to be ended by endStream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); | |
| * var killer = flyd.stream(); | |
| * // `double` ends when `n` ends or when `killer` emits any value | |
| * var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.combine(function(n) { | |
| * return 2 * n(); | |
| * }, [n]); | |
| */ | |
| flyd.endsOn = function(endS, s) { | |
| detachDeps(s.end); | |
| endS.listeners.push(s.end); | |
| s.end.deps.push(endS); | |
| return s; | |
| } | |
| /** | |
| * Map a stream | |
| * | |
| * Returns a new stream consisting of every value from `s` passed through | |
| * `fn`. I.e. `map` creates a new stream that listens to `s` and | |
| * applies `fn` to every new value. | |
| * __Signature__: `(a -> result) -> Stream a -> Stream result` | |
| * | |
| * @name flyd.map | |
| * @param {Function} fn - the function that produces the elements of the new stream | |
| * @param {stream} stream - the stream to map | |
| * @return {stream} a new stream with the mapped values | |
| * | |
| * @example | |
| * var numbers = flyd.stream(0); | |
| * var squaredNumbers = flyd.map(function(n) { return n*n; }, numbers); | |
| */ | |
| // Library functions use self callback to accept (null, undefined) update triggers. | |
| flyd.map = curryN(2, function(f, s) { | |
| return combine(function(s, self) { self(f(s.val)); }, [s]); | |
| }) | |
| /** | |
| * Listen to stream events | |
| * | |
| * Similar to `map` except that the returned stream is empty. Use `on` for doing | |
| * side effects in reaction to stream changes. Use the returned stream only if you | |
| * need to manually end it. | |
| * | |
| * __Signature__: `(a -> result) -> Stream a -> Stream undefined` | |
| * | |
| * @name flyd.on | |
| * @param {Function} cb - the callback | |
| * @param {stream} stream - the stream | |
| * @return {stream} an empty stream (can be ended) | |
| */ | |
| flyd.on = curryN(2, function(f, s) { | |
| return combine(function(s) { f(s.val); }, [s]); | |
| }) | |
| /** | |
| * Creates a new stream with the results of calling the function on every incoming | |
| * stream with and accumulator and the incoming value. | |
| * | |
| * __Signature__: `(a -> b -> a) -> a -> Stream b -> Stream a` | |
| * | |
| * @name flyd.scan | |
| * @param {Function} fn - the function to call | |
| * @param {*} val - the initial value of the accumulator | |
| * @param {stream} stream - the stream source | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var numbers = flyd.stream(); | |
| * var sum = flyd.scan(function(sum, n) { return sum+n; }, 0, numbers); | |
| * numbers(2)(3)(5); | |
| * sum(); // 10 | |
| */ | |
| flyd.scan = curryN(3, function(f, acc, s) { | |
| var ns = combine(function(s, self) { | |
| self(acc = f(acc, s.val)); | |
| }, [s]); | |
| if (!ns.hasVal) ns(acc); | |
| return ns; | |
| }); | |
| /** | |
| * Creates a new stream down which all values from both `stream1` and `stream2` | |
| * will be sent. | |
| * | |
| * __Signature__: `Stream a -> Stream a -> Stream a` | |
| * | |
| * @name flyd.merge | |
| * @param {stream} source1 - one stream to be merged | |
| * @param {stream} source2 - the other stream to be merged | |
| * @return {stream} a stream with the values from both sources | |
| * | |
| * @example | |
| * var btn1Clicks = flyd.stream(); | |
| * button1Elm.addEventListener(btn1Clicks); | |
| * var btn2Clicks = flyd.stream(); | |
| * button2Elm.addEventListener(btn2Clicks); | |
| * var allClicks = flyd.merge(btn1Clicks, btn2Clicks); | |
| */ | |
| flyd.merge = curryN(2, function(s1, s2) { | |
| var s = flyd.immediate(combine(function(s1, s2, self, changed) { | |
| if (changed[0]) { | |
| self(changed[0]()); | |
| } else if (s1.hasVal) { | |
| self(s1.val); | |
| } else if (s2.hasVal) { | |
| self(s2.val); | |
| } | |
| }, [s1, s2])); | |
| flyd.endsOn(combine(function() { | |
| return true; | |
| }, [s1.end, s2.end]), s); | |
| return s; | |
| }); | |
| /** | |
| * Creates a new stream resulting from applying `transducer` to `stream`. | |
| * | |
| * __Signature__: `Transducer -> Stream a -> Stream b` | |
| * | |
| * @name flyd.transduce | |
| * @param {Transducer} xform - the transducer transformation | |
| * @param {stream} source - the stream source | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var t = require('transducers.js'); | |
| * | |
| * var results = []; | |
| * var s1 = flyd.stream(); | |
| * var tx = t.compose(t.map(function(x) { return x * 2; }), t.dedupe()); | |
| * var s2 = flyd.transduce(tx, s1); | |
| * flyd.combine(function(s2) { results.push(s2()); }, [s2]); | |
| * s1(1)(1)(2)(3)(3)(3)(4); | |
| * results; // => [2, 4, 6, 8] | |
| */ | |
| flyd.transduce = curryN(2, function(xform, source) { | |
| xform = xform(new StreamTransformer()); | |
| return combine(function(source, self) { | |
| var res = xform['@@transducer/step'](undefined, source.val); | |
| if (res && res['@@transducer/reduced'] === true) { | |
| self.end(true); | |
| return res['@@transducer/value']; | |
| } else { | |
| return res; | |
| } | |
| }, [source]); | |
| }); | |
| /** | |
| * Returns `fn` curried to `n`. Use this function to curry functions exposed by | |
| * modules for Flyd. | |
| * | |
| * @name flyd.curryN | |
| * @function | |
| * @param {Integer} arity - the function arity | |
| * @param {Function} fn - the function to curry | |
| * @return {Function} the curried function | |
| * | |
| * @example | |
| * function add(x, y) { return x + y; }; | |
| * var a = flyd.curryN(2, add); | |
| * a(2)(4) // => 6 | |
| */ | |
| flyd.curryN = curryN | |
| /** | |
| * Returns a new stream identical to the original except every | |
| * value will be passed through `f`. | |
| * | |
| * _Note:_ This function is included in order to support the fantasy land | |
| * specification. | |
| * | |
| * __Signature__: Called bound to `Stream a`: `(a -> b) -> Stream b` | |
| * | |
| * @name stream.map | |
| * @param {Function} function - the function to apply | |
| * @return {stream} a new stream with the values mapped | |
| * | |
| * @example | |
| * var numbers = flyd.stream(0); | |
| * var squaredNumbers = numbers.map(function(n) { return n*n; }); | |
| */ | |
| function boundMap(f) { return flyd.map(f, this); } | |
| /** | |
| * Returns a new stream which is the result of applying the | |
| * functions from `this` stream to the values in `stream` parameter. | |
| * | |
| * `this` stream must be a stream of functions. | |
| * | |
| * _Note:_ This function is included in order to support the fantasy land | |
| * specification. | |
| * | |
| * __Signature__: Called bound to `Stream (a -> b)`: `a -> Stream b` | |
| * | |
| * @name stream.ap | |
| * @param {stream} stream - the values stream | |
| * @return {stream} a new stram with the functions applied to values | |
| * | |
| * @example | |
| * var add = flyd.curryN(2, function(x, y) { return x + y; }); | |
| * var numbers1 = flyd.stream(); | |
| * var numbers2 = flyd.stream(); | |
| * var addToNumbers1 = flyd.map(add, numbers1); | |
| * var added = addToNumbers1.ap(numbers2); | |
| */ | |
| function ap(s2) { | |
| var s1 = this; | |
| return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]); | |
| } | |
| /** | |
| * Get a human readable view of a stream | |
| * @name stream.toString | |
| * @return {String} the stream string representation | |
| */ | |
| function streamToString() { | |
| return 'stream(' + this.val + ')'; | |
| } | |
| /** | |
| * @name stream.end | |
| * @memberof stream | |
| * A stream that emits `true` when the stream ends. If `true` is pushed down the | |
| * stream the parent stream ends. | |
| */ | |
| /** | |
| * @name stream.of | |
| * @function | |
| * @memberof stream | |
| * Returns a new stream with `value` as its initial value. It is identical to | |
| * calling `flyd.stream` with one argument. | |
| * | |
| * __Signature__: Called bound to `Stream (a)`: `b -> Stream b` | |
| * | |
| * @param {*} value - the initial value | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); | |
| * var m = n.of(1); | |
| */ | |
| // /////////////////////////// PRIVATE ///////////////////////////////// // | |
| /** | |
| * @private | |
| * Create a stream with no dependencies and no value | |
| * @return {Function} a flyd stream | |
| */ | |
| function createStream() { | |
| function s(n) { | |
| if (arguments.length === 0) return s.val | |
| updateStreamValue(s, n) | |
| return s | |
| } | |
| s.hasVal = false; | |
| s.val = undefined; | |
| s.vals = []; | |
| s.listeners = []; | |
| s.queued = false; | |
| s.end = undefined; | |
| s.map = boundMap; | |
| s.ap = ap; | |
| s.of = flyd.stream; | |
| s.toString = streamToString; | |
| return s; | |
| } | |
| /** | |
| * @private | |
| * Create a dependent stream | |
| * @param {Array<stream>} dependencies - an array of the streams | |
| * @param {Function} fn - the function used to calculate the new stream value | |
| * from the dependencies | |
| * @return {stream} the created stream | |
| */ | |
| function createDependentStream(deps, fn) { | |
| var s = createStream(); | |
| s.fn = fn; | |
| s.deps = deps; | |
| s.depsMet = false; | |
| s.depsChanged = deps.length > 0 ? [] : undefined; | |
| s.shouldUpdate = false; | |
| addListeners(deps, s); | |
| return s; | |
| } | |
| /** | |
| * @private | |
| * Check if all the dependencies have values | |
| * @param {stream} stream - the stream to check depencencies from | |
| * @return {Boolean} `true` if all dependencies have vales, `false` otherwise | |
| */ | |
| function initialDepsNotMet(stream) { | |
| stream.depsMet = stream.deps.every(function(s) { | |
| return s.hasVal; | |
| }); | |
| return !stream.depsMet; | |
| } | |
| /** | |
| * @private | |
| * Update a dependent stream using its dependencies in an atomic way | |
| * @param {stream} stream - the stream to update | |
| */ | |
| function updateStream(s) { | |
| if ((s.depsMet !== true && initialDepsNotMet(s)) || | |
| (s.end !== undefined && s.end.val === true)) return; | |
| if (inStream !== undefined) { | |
| toUpdate.push(s); | |
| return; | |
| } | |
| inStream = s; | |
| if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged; | |
| var returnVal = s.fn.apply(s.fn, s.fnArgs); | |
| if (returnVal !== undefined) { | |
| s(returnVal); | |
| } | |
| inStream = undefined; | |
| if (s.depsChanged !== undefined) s.depsChanged = []; | |
| s.shouldUpdate = false; | |
| if (flushing === false) flushUpdate(); | |
| } | |
| /** | |
| * @private | |
| * Update the dependencies of a stream | |
| * @param {stream} stream | |
| */ | |
| function updateDeps(s) { | |
| var i, o, list | |
| var listeners = s.listeners; | |
| for (i = 0; i < listeners.length; ++i) { | |
| list = listeners[i]; | |
| if (list.end === s) { | |
| endStream(list); | |
| } else { | |
| if (list.depsChanged !== undefined) list.depsChanged.push(s); | |
| list.shouldUpdate = true; | |
| findDeps(list); | |
| } | |
| } | |
| for (; orderNextIdx >= 0; --orderNextIdx) { | |
| o = order[orderNextIdx]; | |
| if (o.shouldUpdate === true) updateStream(o); | |
| o.queued = false; | |
| } | |
| } | |
| /** | |
| * @private | |
| * Add stream dependencies to the global `order` queue. | |
| * @param {stream} stream | |
| * @see updateDeps | |
| */ | |
| function findDeps(s) { | |
| var i | |
| var listeners = s.listeners; | |
| if (s.queued === false) { | |
| s.queued = true; | |
| for (i = 0; i < listeners.length; ++i) { | |
| findDeps(listeners[i]); | |
| } | |
| order[++orderNextIdx] = s; | |
| } | |
| } | |
| /** | |
| * @private | |
| */ | |
| function flushUpdate() { | |
| flushing = true; | |
| while (toUpdate.length > 0) { | |
| var s = toUpdate.shift(); | |
| if (s.vals.length > 0) s.val = s.vals.shift(); | |
| updateDeps(s); | |
| } | |
| flushing = false; | |
| } | |
| /** | |
| * @private | |
| * Push down a value into a stream | |
| * @param {stream} stream | |
| * @param {*} value | |
| */ | |
| function updateStreamValue(s, n) { | |
| if (n !== undefined && n !== null && isFunction(n.then)) { | |
| n.then(s); | |
| return; | |
| } | |
| s.val = n; | |
| s.hasVal = true; | |
| if (inStream === undefined) { | |
| flushing = true; | |
| updateDeps(s); | |
| if (toUpdate.length > 0) flushUpdate(); else flushing = false; | |
| } else if (inStream === s) { | |
| markListeners(s, s.listeners); | |
| } else { | |
| s.vals.push(n); | |
| toUpdate.push(s); | |
| } | |
| } | |
| /** | |
| * @private | |
| */ | |
| function markListeners(s, lists) { | |
| var i, list; | |
| for (i = 0; i < lists.length; ++i) { | |
| list = lists[i]; | |
| if (list.end !== s) { | |
| if (list.depsChanged !== undefined) { | |
| list.depsChanged.push(s); | |
| } | |
| list.shouldUpdate = true; | |
| } else { | |
| endStream(list); | |
| } | |
| } | |
| } | |
| /** | |
| * @private | |
| * Add dependencies to a stream | |
| * @param {Array<stream>} dependencies | |
| * @param {stream} stream | |
| */ | |
| function addListeners(deps, s) { | |
| for (var i = 0; i < deps.length; ++i) { | |
| deps[i].listeners.push(s); | |
| } | |
| } | |
| /** | |
| * @private | |
| * Removes an stream from a dependency array | |
| * @param {stream} stream | |
| * @param {Array<stream>} dependencies | |
| */ | |
| function removeListener(s, listeners) { | |
| var idx = listeners.indexOf(s); | |
| listeners[idx] = listeners[listeners.length - 1]; | |
| listeners.length--; | |
| } | |
| /** | |
| * @private | |
| * Detach a stream from its dependencies | |
| * @param {stream} stream | |
| */ | |
| function detachDeps(s) { | |
| for (var i = 0; i < s.deps.length; ++i) { | |
| removeListener(s, s.deps[i].listeners); | |
| } | |
| s.deps.length = 0; | |
| } | |
| /** | |
| * @private | |
| * Ends a stream | |
| */ | |
| function endStream(s) { | |
| if (s.deps !== undefined) detachDeps(s); | |
| if (s.end !== undefined) detachDeps(s.end); | |
| } | |
| /** | |
| * @private | |
| * transducer stream transformer | |
| */ | |
| function StreamTransformer() { } | |
| StreamTransformer.prototype['@@transducer/init'] = function() { }; | |
| StreamTransformer.prototype['@@transducer/result'] = function() { }; | |
| StreamTransformer.prototype['@@transducer/step'] = function(s, v) { return v; }; | |
| module.exports = flyd; | |
| },{"ramda/src/curryN":2}],2:[function(require,module,exports){ | |
| var _arity = require('./internal/_arity'); | |
| var _curry1 = require('./internal/_curry1'); | |
| var _curry2 = require('./internal/_curry2'); | |
| var _curryN = require('./internal/_curryN'); | |
| /** | |
| * Returns a curried equivalent of the provided function, with the specified | |
| * arity. The curried function has two unusual capabilities. First, its | |
| * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the | |
| * following are equivalent: | |
| * | |
| * - `g(1)(2)(3)` | |
| * - `g(1)(2, 3)` | |
| * - `g(1, 2)(3)` | |
| * - `g(1, 2, 3)` | |
| * | |
| * Secondly, the special placeholder value `R.__` may be used to specify | |
| * "gaps", allowing partial application of any combination of arguments, | |
| * regardless of their positions. If `g` is as above and `_` is `R.__`, the | |
| * following are equivalent: | |
| * | |
| * - `g(1, 2, 3)` | |
| * - `g(_, 2, 3)(1)` | |
| * - `g(_, _, 3)(1)(2)` | |
| * - `g(_, _, 3)(1, 2)` | |
| * - `g(_, 2)(1)(3)` | |
| * - `g(_, 2)(1, 3)` | |
| * - `g(_, 2)(_, 3)(1)` | |
| * | |
| * @func | |
| * @memberOf R | |
| * @since v0.5.0 | |
| * @category Function | |
| * @sig Number -> (* -> a) -> (* -> a) | |
| * @param {Number} length The arity for the returned function. | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} A new, curried function. | |
| * @see R.curry | |
| * @example | |
| * | |
| * var sumArgs = (...args) => R.sum(args); | |
| * | |
| * var curriedAddFourNumbers = R.curryN(4, sumArgs); | |
| * var f = curriedAddFourNumbers(1, 2); | |
| * var g = f(3); | |
| * g(4); //=> 10 | |
| */ | |
| module.exports = _curry2(function curryN(length, fn) { | |
| if (length === 1) { | |
| return _curry1(fn); | |
| } | |
| return _arity(length, _curryN(length, [], fn)); | |
| }); | |
| },{"./internal/_arity":3,"./internal/_curry1":4,"./internal/_curry2":5,"./internal/_curryN":6}],3:[function(require,module,exports){ | |
| module.exports = function _arity(n, fn) { | |
| /* eslint-disable no-unused-vars */ | |
| switch (n) { | |
| case 0: return function() { return fn.apply(this, arguments); }; | |
| case 1: return function(a0) { return fn.apply(this, arguments); }; | |
| case 2: return function(a0, a1) { return fn.apply(this, arguments); }; | |
| case 3: return function(a0, a1, a2) { return fn.apply(this, arguments); }; | |
| case 4: return function(a0, a1, a2, a3) { return fn.apply(this, arguments); }; | |
| case 5: return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments); }; | |
| case 6: return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments); }; | |
| case 7: return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments); }; | |
| case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments); }; | |
| case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments); }; | |
| case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments); }; | |
| default: throw new Error('First argument to _arity must be a non-negative integer no greater than ten'); | |
| } | |
| }; | |
| },{}],4:[function(require,module,exports){ | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Optimized internal one-arity curry function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curry1(fn) { | |
| return function f1(a) { | |
| if (arguments.length === 0 || _isPlaceholder(a)) { | |
| return f1; | |
| } else { | |
| return fn.apply(this, arguments); | |
| } | |
| }; | |
| }; | |
| },{"./_isPlaceholder":7}],5:[function(require,module,exports){ | |
| var _curry1 = require('./_curry1'); | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Optimized internal two-arity curry function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curry2(fn) { | |
| return function f2(a, b) { | |
| switch (arguments.length) { | |
| case 0: | |
| return f2; | |
| case 1: | |
| return _isPlaceholder(a) ? f2 | |
| : _curry1(function(_b) { return fn(a, _b); }); | |
| default: | |
| return _isPlaceholder(a) && _isPlaceholder(b) ? f2 | |
| : _isPlaceholder(a) ? _curry1(function(_a) { return fn(_a, b); }) | |
| : _isPlaceholder(b) ? _curry1(function(_b) { return fn(a, _b); }) | |
| : fn(a, b); | |
| } | |
| }; | |
| }; | |
| },{"./_curry1":4,"./_isPlaceholder":7}],6:[function(require,module,exports){ | |
| var _arity = require('./_arity'); | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Internal curryN function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Number} length The arity of the curried function. | |
| * @param {Array} received An array of arguments received thus far. | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curryN(length, received, fn) { | |
| return function() { | |
| var combined = []; | |
| var argsIdx = 0; | |
| var left = length; | |
| var combinedIdx = 0; | |
| while (combinedIdx < received.length || argsIdx < arguments.length) { | |
| var result; | |
| if (combinedIdx < received.length && | |
| (!_isPlaceholder(received[combinedIdx]) || | |
| argsIdx >= arguments.length)) { | |
| result = received[combinedIdx]; | |
| } else { | |
| result = arguments[argsIdx]; | |
| argsIdx += 1; | |
| } | |
| combined[combinedIdx] = result; | |
| if (!_isPlaceholder(result)) { | |
| left -= 1; | |
| } | |
| combinedIdx += 1; | |
| } | |
| return left <= 0 ? fn.apply(this, combined) | |
| : _arity(left, _curryN(length, combined, fn)); | |
| }; | |
| }; | |
| },{"./_arity":3,"./_isPlaceholder":7}],7:[function(require,module,exports){ | |
| module.exports = function _isPlaceholder(a) { | |
| return a != null && | |
| typeof a === 'object' && | |
| a['@@functional/placeholder'] === true; | |
| }; | |
| },{}],"flyd/module/mergeall":[function(require,module,exports){ | |
| var flyd = require('../../lib'); | |
| module.exports = function mergeAll(streams) { | |
| var s = flyd.immediate(flyd.combine(function() { | |
| var self = arguments[arguments.length - 2]; | |
| if (arguments[arguments.length - 1][0]) { | |
| self(arguments[arguments.length - 1][0]()); | |
| return; | |
| } | |
| [].slice.call(arguments, 0, arguments.length - 2) | |
| .some(function(s1) { | |
| if (s1.hasVal) { | |
| self(s1.val); | |
| return true; | |
| } | |
| }); | |
| }, streams)); | |
| flyd.endsOn(flyd.combine(function() { | |
| return true; | |
| }, streams.map(function(sm) { return sm.end; })), s); | |
| return s; | |
| }; | |
| },{"../../lib":1}]},{},[]) | |
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImxpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9yYW1kYS9zcmMvY3VycnlOLmpzIiwibm9kZV9tb2R1bGVzL3JhbWRhL3NyYy9pbnRlcm5hbC9fYXJpdHkuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTEuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTIuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeU4uanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19pc1BsYWNlaG9sZGVyLmpzIiwibW9kdWxlL21lcmdlYWxsL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnJ5TiA9IHJlcXVpcmUoJ3JhbWRhL3NyYy9jdXJyeU4nKTtcblxuLy8gVXRpbGl0eVxuZnVuY3Rpb24gaXNGdW5jdGlvbihvYmopIHtcbiAgcmV0dXJuICEhKG9iaiAmJiBvYmouY29uc3RydWN0b3IgJiYgb2JqLmNhbGwgJiYgb2JqLmFwcGx5KTtcbn1cbmZ1bmN0aW9uIHRydWVGbigpIHsgcmV0dXJuIHRydWU7IH1cblxuLy8gR2xvYmFsc1xudmFyIHRvVXBkYXRlID0gW107XG52YXIgaW5TdHJlYW07XG52YXIgb3JkZXIgPSBbXTtcbnZhciBvcmRlck5leHRJZHggPSAtMTtcbnZhciBmbHVzaGluZyA9IGZhbHNlO1xuXG4vKiogQG5hbWVzcGFjZSAqL1xudmFyIGZseWQgPSB7fVxuXG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gQVBJIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyAvL1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtXG4gKlxuICogX19TaWduYXR1cmVfXzogYGEgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5zdHJlYW1cbiAqIEBwYXJhbSB7Kn0gaW5pdGlhbFZhbHVlIC0gKE9wdGlvbmFsKSB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4gPSBmbHlkLnN0cmVhbSgxKTsgLy8gU3RyZWFtIHdpdGggaW5pdGlhbCB2YWx1ZSBgMWBcbiAqIHZhciBzID0gZmx5ZC5zdHJlYW0oKTsgLy8gU3RyZWFtIHdpdGggbm8gaW5pdGlhbCB2YWx1ZVxuICovXG5mbHlkLnN0cmVhbSA9IGZ1bmN0aW9uKGluaXRpYWxWYWx1ZSkge1xuICB2YXIgZW5kU3RyZWFtID0gY3JlYXRlRGVwZW5kZW50U3RyZWFtKFtdLCB0cnVlRm4pO1xuICB2YXIgcyA9IGNyZWF0ZVN0cmVhbSgpO1xuICBzLmVuZCA9IGVuZFN0cmVhbTtcbiAgcy5mbkFyZ3MgPSBbXTtcbiAgZW5kU3RyZWFtLmxpc3RlbmVycy5wdXNoKHMpO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDApIHMoaW5pdGlhbFZhbHVlKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGRlcGVuZGVudCBzdHJlYW1cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgKC4uLlN0cmVhbSAqIC0+IFN0cmVhbSBiIC0+IGIpIC0+IFtTdHJlYW0gKl0gLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgZmx5ZC5jb21iaW5lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNvbWJpbmUgdGhlIHN0cmVhbXNcbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzIC0gdGhlIHN0cmVhbXMgdGhhdCB0aGlzIG9uZSBkZXBlbmRzIG9uXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBkZXBlbmRlbnQgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBuMSA9IGZseWQuc3RyZWFtKDApO1xuICogdmFyIG4yID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgbWF4ID0gZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKG4xLCBuMiwgc2VsZiwgY2hhbmdlZCkge1xuICogICByZXR1cm4gbjEoKSA+IG4yKCkgPyBuMSgpIDogbjIoKTtcbiAqIH0sIFtuMSwgbjJdKTtcbiAqL1xuZmx5ZC5jb21iaW5lID0gY3VycnlOKDIsIGNvbWJpbmUpO1xuZnVuY3Rpb24gY29tYmluZShmbiwgc3RyZWFtcykge1xuICB2YXIgaSwgcywgZGVwcywgZGVwRW5kU3RyZWFtcztcbiAgdmFyIGVuZFN0cmVhbSA9IGNyZWF0ZURlcGVuZGVudFN0cmVhbShbXSwgdHJ1ZUZuKTtcbiAgZGVwcyA9IFtdOyBkZXBFbmRTdHJlYW1zID0gW107XG4gIGZvciAoaSA9IDA7IGkgPCBzdHJlYW1zLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKHN0cmVhbXNbaV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgZGVwcy5wdXNoKHN0cmVhbXNbaV0pO1xuICAgICAgaWYgKHN0cmVhbXNbaV0uZW5kICE9PSB1bmRlZmluZWQpIGRlcEVuZFN0cmVhbXMucHVzaChzdHJlYW1zW2ldLmVuZCk7XG4gICAgfVxuICB9XG4gIHMgPSBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oZGVwcywgZm4pO1xuICBzLmRlcHNDaGFuZ2VkID0gW107XG4gIHMuZm5BcmdzID0gcy5kZXBzLmNvbmNhdChbcywgcy5kZXBzQ2hhbmdlZF0pO1xuICBzLmVuZCA9IGVuZFN0cmVhbTtcbiAgZW5kU3RyZWFtLmxpc3RlbmVycy5wdXNoKHMpO1xuICBhZGRMaXN0ZW5lcnMoZGVwRW5kU3RyZWFtcywgZW5kU3RyZWFtKTtcbiAgZW5kU3RyZWFtLmRlcHMgPSBkZXBFbmRTdHJlYW1zO1xuICB1cGRhdGVTdHJlYW0ocyk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIFJldHVybnMgYHRydWVgIGlmIHRoZSBzdXBwbGllZCBhcmd1bWVudCBpcyBhIEZseWQgc3RyZWFtIGFuZCBgZmFsc2VgIG90aGVyd2lzZS5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgKiAtPiBCb29sZWFuYFxuICpcbiAqIEBuYW1lIGZseWQuaXNTdHJlYW1cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgLSB0aGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybiB7Qm9vbGVhbn0gYHRydWVgIGlmIGlzIGEgRmx5ZCBzdHJlYW1uLCBgZmFsc2VgIG90aGVyd2lzZVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgcyA9IGZseWQuc3RyZWFtKDEpO1xuICogdmFyIG4gPSAxO1xuICogZmx5ZC5pc1N0cmVhbShzKTsgLy89PiB0cnVlXG4gKiBmbHlkLmlzU3RyZWFtKG4pOyAvLz0+IGZhbHNlXG4gKi9cbmZseWQuaXNTdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgcmV0dXJuIGlzRnVuY3Rpb24oc3RyZWFtKSAmJiAnaGFzVmFsJyBpbiBzdHJlYW07XG59XG5cbi8qKlxuICogSW52b2tlcyB0aGUgYm9keSAodGhlIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSB0aGUgdmFsdWUpIG9mIGEgZGVwZW5kZW50IHN0cmVhbVxuICpcbiAqIEJ5IGRlZmF1bHQgdGhlIGJvZHkgb2YgYSBkZXBlbmRlbnQgc3RyZWFtIGlzIG9ubHkgY2FsbGVkIHdoZW4gYWxsIHRoZSBzdHJlYW1zXG4gKiB1cG9uIHdoaWNoIGl0IGRlcGVuZHMgaGFzIGEgdmFsdWUuIGBpbW1lZGlhdGVgIGNhbiBjaXJjdW12ZW50IHRoaXMgYmVoYXZpb3VyLlxuICogSXQgaW1tZWRpYXRlbHkgaW52b2tlcyB0aGUgYm9keSBvZiBhIGRlcGVuZGVudCBzdHJlYW0uXG4gKlxuICogX19TaWduYXR1cmVfXzogYFN0cmVhbSBhIC0+IFN0cmVhbSBhYFxuICpcbiAqIEBuYW1lIGZseWQuaW1tZWRpYXRlXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIGRlcGVuZGVudCBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIHNhbWUgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBzID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBoYXNJdGVtcyA9IGZseWQuaW1tZWRpYXRlKGZseWQuY29tYmluZShmdW5jdGlvbihzKSB7XG4gKiAgIHJldHVybiBzKCkgIT09IHVuZGVmaW5lZCAmJiBzKCkubGVuZ3RoID4gMDtcbiAqIH0sIFtzXSk7XG4gKiBjb25zb2xlLmxvZyhoYXNJdGVtcygpKTsgLy8gbG9ncyBgZmFsc2VgLiBIYWQgYGltbWVkaWF0ZWAgbm90IGJlZW5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2VkIGBoYXNJdGVtcygpYCB3b3VsZCd2ZSByZXR1cm5lZCBgdW5kZWZpbmVkYFxuICogcyhbMV0pO1xuICogY29uc29sZS5sb2coaGFzSXRlbXMoKSk7IC8vIGxvZ3MgYHRydWVgLlxuICogcyhbXSk7XG4gKiBjb25zb2xlLmxvZyhoYXNJdGVtcygpKTsgLy8gbG9ncyBgZmFsc2VgLlxuICovXG5mbHlkLmltbWVkaWF0ZSA9IGZ1bmN0aW9uKHMpIHtcbiAgaWYgKHMuZGVwc01ldCA9PT0gZmFsc2UpIHtcbiAgICBzLmRlcHNNZXQgPSB0cnVlO1xuICAgIHVwZGF0ZVN0cmVhbShzKTtcbiAgfVxuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBDaGFuZ2VzIHdoaWNoIGBlbmRzU3RyZWFtYCBzaG91bGQgdHJpZ2dlciB0aGUgZW5kaW5nIG9mIGBzYC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgU3RyZWFtIGEgLT4gU3RyZWFtIGIgLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgZmx5ZC5lbmRzT25cbiAqIEBwYXJhbSB7c3RyZWFtfSBlbmRTdHJlYW0gLSB0aGUgc3RyZWFtIHRvIHRyaWdnZXIgdGhlIGVuZGluZ1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gYmUgZW5kZWQgYnkgdGhlIGVuZFN0cmVhbVxuICogQHBhcmFtIHtzdHJlYW19IHRoZSBzdHJlYW0gbW9kaWZpZWQgdG8gYmUgZW5kZWQgYnkgZW5kU3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBuID0gZmx5ZC5zdHJlYW0oMSk7XG4gKiB2YXIga2lsbGVyID0gZmx5ZC5zdHJlYW0oKTtcbiAqIC8vIGBkb3VibGVgIGVuZHMgd2hlbiBgbmAgZW5kcyBvciB3aGVuIGBraWxsZXJgIGVtaXRzIGFueSB2YWx1ZVxuICogdmFyIGRvdWJsZSA9IGZseWQuZW5kc09uKGZseWQubWVyZ2Uobi5lbmQsIGtpbGxlciksIGZseWQuY29tYmluZShmdW5jdGlvbihuKSB7XG4gKiAgIHJldHVybiAyICogbigpO1xuICogfSwgW25dKTtcbiovXG5mbHlkLmVuZHNPbiA9IGZ1bmN0aW9uKGVuZFMsIHMpIHtcbiAgZGV0YWNoRGVwcyhzLmVuZCk7XG4gIGVuZFMubGlzdGVuZXJzLnB1c2gocy5lbmQpO1xuICBzLmVuZC5kZXBzLnB1c2goZW5kUyk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIE1hcCBhIHN0cmVhbVxuICpcbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIGNvbnNpc3Rpbmcgb2YgZXZlcnkgdmFsdWUgZnJvbSBgc2AgcGFzc2VkIHRocm91Z2hcbiAqIGBmbmAuIEkuZS4gYG1hcGAgY3JlYXRlcyBhIG5ldyBzdHJlYW0gdGhhdCBsaXN0ZW5zIHRvIGBzYCBhbmRcbiAqIGFwcGxpZXMgYGZuYCB0byBldmVyeSBuZXcgdmFsdWUuXG4gKiBfX1NpZ25hdHVyZV9fOiBgKGEgLT4gcmVzdWx0KSAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gcmVzdWx0YFxuICpcbiAqIEBuYW1lIGZseWQubWFwXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0aGF0IHByb2R1Y2VzIHRoZSBlbGVtZW50cyBvZiB0aGUgbmV3IHN0cmVhbVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gbWFwXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmVhbSB3aXRoIHRoZSBtYXBwZWQgdmFsdWVzXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBudW1iZXJzID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgc3F1YXJlZE51bWJlcnMgPSBmbHlkLm1hcChmdW5jdGlvbihuKSB7IHJldHVybiBuKm47IH0sIG51bWJlcnMpO1xuICovXG4vLyBMaWJyYXJ5IGZ1bmN0aW9ucyB1c2Ugc2VsZiBjYWxsYmFjayB0byBhY2NlcHQgKG51bGwsIHVuZGVmaW5lZCkgdXBkYXRlIHRyaWdnZXJzLlxuZmx5ZC5tYXAgPSBjdXJyeU4oMiwgZnVuY3Rpb24oZiwgcykge1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzLCBzZWxmKSB7IHNlbGYoZihzLnZhbCkpOyB9LCBbc10pO1xufSlcblxuLyoqXG4gKiBMaXN0ZW4gdG8gc3RyZWFtIGV2ZW50c1xuICpcbiAqIFNpbWlsYXIgdG8gYG1hcGAgZXhjZXB0IHRoYXQgdGhlIHJldHVybmVkIHN0cmVhbSBpcyBlbXB0eS4gVXNlIGBvbmAgZm9yIGRvaW5nXG4gKiBzaWRlIGVmZmVjdHMgaW4gcmVhY3Rpb24gdG8gc3RyZWFtIGNoYW5nZXMuIFVzZSB0aGUgcmV0dXJuZWQgc3RyZWFtIG9ubHkgaWYgeW91XG4gKiBuZWVkIHRvIG1hbnVhbGx5IGVuZCBpdC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgKGEgLT4gcmVzdWx0KSAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gdW5kZWZpbmVkYFxuICpcbiAqIEBuYW1lIGZseWQub25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNiIC0gdGhlIGNhbGxiYWNrXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSBhbiBlbXB0eSBzdHJlYW0gKGNhbiBiZSBlbmRlZClcbiAqL1xuZmx5ZC5vbiA9IGN1cnJ5TigyLCBmdW5jdGlvbihmLCBzKSB7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMpIHsgZihzLnZhbCk7IH0sIFtzXSk7XG59KVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtIHdpdGggdGhlIHJlc3VsdHMgb2YgY2FsbGluZyB0aGUgZnVuY3Rpb24gb24gZXZlcnkgaW5jb21pbmdcbiAqIHN0cmVhbSB3aXRoIGFuZCBhY2N1bXVsYXRvciBhbmQgdGhlIGluY29taW5nIHZhbHVlLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiBiIC0+IGEpIC0+IGEgLT4gU3RyZWFtIGIgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5zY2FuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBjYWxsXG4gKiBAcGFyYW0geyp9IHZhbCAtIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBhY2N1bXVsYXRvclxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gc291cmNlXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBuZXcgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBudW1iZXJzID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBzdW0gPSBmbHlkLnNjYW4oZnVuY3Rpb24oc3VtLCBuKSB7IHJldHVybiBzdW0rbjsgfSwgMCwgbnVtYmVycyk7XG4gKiBudW1iZXJzKDIpKDMpKDUpO1xuICogc3VtKCk7IC8vIDEwXG4gKi9cbmZseWQuc2NhbiA9IGN1cnJ5TigzLCBmdW5jdGlvbihmLCBhY2MsIHMpIHtcbiAgdmFyIG5zID0gY29tYmluZShmdW5jdGlvbihzLCBzZWxmKSB7XG4gICAgc2VsZihhY2MgPSBmKGFjYywgcy52YWwpKTtcbiAgfSwgW3NdKTtcbiAgaWYgKCFucy5oYXNWYWwpIG5zKGFjYyk7XG4gIHJldHVybiBucztcbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtIGRvd24gd2hpY2ggYWxsIHZhbHVlcyBmcm9tIGJvdGggYHN0cmVhbTFgIGFuZCBgc3RyZWFtMmBcbiAqIHdpbGwgYmUgc2VudC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgU3RyZWFtIGEgLT4gU3RyZWFtIGEgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5tZXJnZVxuICogQHBhcmFtIHtzdHJlYW19IHNvdXJjZTEgLSBvbmUgc3RyZWFtIHRvIGJlIG1lcmdlZFxuICogQHBhcmFtIHtzdHJlYW19IHNvdXJjZTIgLSB0aGUgb3RoZXIgc3RyZWFtIHRvIGJlIG1lcmdlZFxuICogQHJldHVybiB7c3RyZWFtfSBhIHN0cmVhbSB3aXRoIHRoZSB2YWx1ZXMgZnJvbSBib3RoIHNvdXJjZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIGJ0bjFDbGlja3MgPSBmbHlkLnN0cmVhbSgpO1xuICogYnV0dG9uMUVsbS5hZGRFdmVudExpc3RlbmVyKGJ0bjFDbGlja3MpO1xuICogdmFyIGJ0bjJDbGlja3MgPSBmbHlkLnN0cmVhbSgpO1xuICogYnV0dG9uMkVsbS5hZGRFdmVudExpc3RlbmVyKGJ0bjJDbGlja3MpO1xuICogdmFyIGFsbENsaWNrcyA9IGZseWQubWVyZ2UoYnRuMUNsaWNrcywgYnRuMkNsaWNrcyk7XG4gKi9cbmZseWQubWVyZ2UgPSBjdXJyeU4oMiwgZnVuY3Rpb24oczEsIHMyKSB7XG4gIHZhciBzID0gZmx5ZC5pbW1lZGlhdGUoY29tYmluZShmdW5jdGlvbihzMSwgczIsIHNlbGYsIGNoYW5nZWQpIHtcbiAgICBpZiAoY2hhbmdlZFswXSkge1xuICAgICAgc2VsZihjaGFuZ2VkWzBdKCkpO1xuICAgIH0gZWxzZSBpZiAoczEuaGFzVmFsKSB7XG4gICAgICBzZWxmKHMxLnZhbCk7XG4gICAgfSBlbHNlIGlmIChzMi5oYXNWYWwpIHtcbiAgICAgIHNlbGYoczIudmFsKTtcbiAgICB9XG4gIH0sIFtzMSwgczJdKSk7XG4gIGZseWQuZW5kc09uKGNvbWJpbmUoZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sIFtzMS5lbmQsIHMyLmVuZF0pLCBzKTtcbiAgcmV0dXJuIHM7XG59KTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHN0cmVhbSByZXN1bHRpbmcgZnJvbSBhcHBseWluZyBgdHJhbnNkdWNlcmAgdG8gYHN0cmVhbWAuXG4gKlxuICogX19TaWduYXR1cmVfXzogYFRyYW5zZHVjZXIgLT4gU3RyZWFtIGEgLT4gU3RyZWFtIGJgXG4gKlxuICogQG5hbWUgZmx5ZC50cmFuc2R1Y2VcbiAqIEBwYXJhbSB7VHJhbnNkdWNlcn0geGZvcm0gLSB0aGUgdHJhbnNkdWNlciB0cmFuc2Zvcm1hdGlvblxuICogQHBhcmFtIHtzdHJlYW19IHNvdXJjZSAtIHRoZSBzdHJlYW0gc291cmNlXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBuZXcgc3RyZWFtXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciB0ID0gcmVxdWlyZSgndHJhbnNkdWNlcnMuanMnKTtcbiAqXG4gKiB2YXIgcmVzdWx0cyA9IFtdO1xuICogdmFyIHMxID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciB0eCA9IHQuY29tcG9zZSh0Lm1hcChmdW5jdGlvbih4KSB7IHJldHVybiB4ICogMjsgfSksIHQuZGVkdXBlKCkpO1xuICogdmFyIHMyID0gZmx5ZC50cmFuc2R1Y2UodHgsIHMxKTtcbiAqIGZseWQuY29tYmluZShmdW5jdGlvbihzMikgeyByZXN1bHRzLnB1c2goczIoKSk7IH0sIFtzMl0pO1xuICogczEoMSkoMSkoMikoMykoMykoMykoNCk7XG4gKiByZXN1bHRzOyAvLyA9PiBbMiwgNCwgNiwgOF1cbiAqL1xuZmx5ZC50cmFuc2R1Y2UgPSBjdXJyeU4oMiwgZnVuY3Rpb24oeGZvcm0sIHNvdXJjZSkge1xuICB4Zm9ybSA9IHhmb3JtKG5ldyBTdHJlYW1UcmFuc2Zvcm1lcigpKTtcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24oc291cmNlLCBzZWxmKSB7XG4gICAgdmFyIHJlcyA9IHhmb3JtWydAQHRyYW5zZHVjZXIvc3RlcCddKHVuZGVmaW5lZCwgc291cmNlLnZhbCk7XG4gICAgaWYgKHJlcyAmJiByZXNbJ0BAdHJhbnNkdWNlci9yZWR1Y2VkJ10gPT09IHRydWUpIHtcbiAgICAgIHNlbGYuZW5kKHRydWUpO1xuICAgICAgcmV0dXJuIHJlc1snQEB0cmFuc2R1Y2VyL3ZhbHVlJ107XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICB9LCBbc291cmNlXSk7XG59KTtcblxuLyoqXG4gKiBSZXR1cm5zIGBmbmAgY3VycmllZCB0byBgbmAuIFVzZSB0aGlzIGZ1bmN0aW9uIHRvIGN1cnJ5IGZ1bmN0aW9ucyBleHBvc2VkIGJ5XG4gKiBtb2R1bGVzIGZvciBGbHlkLlxuICpcbiAqIEBuYW1lIGZseWQuY3VycnlOXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7SW50ZWdlcn0gYXJpdHkgLSB0aGUgZnVuY3Rpb24gYXJpdHlcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGN1cnJ5XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gdGhlIGN1cnJpZWQgZnVuY3Rpb25cbiAqXG4gKiBAZXhhbXBsZVxuICogZnVuY3Rpb24gYWRkKHgsIHkpIHsgcmV0dXJuIHggKyB5OyB9O1xuICogdmFyIGEgPSBmbHlkLmN1cnJ5TigyLCBhZGQpO1xuICogYSgyKSg0KSAvLyA9PiA2XG4gKi9cbmZseWQuY3VycnlOID0gY3VycnlOXG5cbi8qKlxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gaWRlbnRpY2FsIHRvIHRoZSBvcmlnaW5hbCBleGNlcHQgZXZlcnlcbiAqIHZhbHVlIHdpbGwgYmUgcGFzc2VkIHRocm91Z2ggYGZgLlxuICpcbiAqIF9Ob3RlOl8gVGhpcyBmdW5jdGlvbiBpcyBpbmNsdWRlZCBpbiBvcmRlciB0byBzdXBwb3J0IHRoZSBmYW50YXN5IGxhbmRcbiAqIHNwZWNpZmljYXRpb24uXG4gKlxuICogX19TaWduYXR1cmVfXzogQ2FsbGVkIGJvdW5kIHRvIGBTdHJlYW0gYWA6IGAoYSAtPiBiKSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBzdHJlYW0ubWFwXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jdGlvbiAtIHRoZSBmdW5jdGlvbiB0byBhcHBseVxuICogQHJldHVybiB7c3RyZWFtfSBhIG5ldyBzdHJlYW0gd2l0aCB0aGUgdmFsdWVzIG1hcHBlZFxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbnVtYmVycyA9IGZseWQuc3RyZWFtKDApO1xuICogdmFyIHNxdWFyZWROdW1iZXJzID0gbnVtYmVycy5tYXAoZnVuY3Rpb24obikgeyByZXR1cm4gbipuOyB9KTtcbiAqL1xuZnVuY3Rpb24gYm91bmRNYXAoZikgeyByZXR1cm4gZmx5ZC5tYXAoZiwgdGhpcyk7IH1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSB3aGljaCBpcyB0aGUgcmVzdWx0IG9mIGFwcGx5aW5nIHRoZVxuICogZnVuY3Rpb25zIGZyb20gYHRoaXNgIHN0cmVhbSB0byB0aGUgdmFsdWVzIGluIGBzdHJlYW1gIHBhcmFtZXRlci5cbiAqXG4gKiBgdGhpc2Agc3RyZWFtIG11c3QgYmUgYSBzdHJlYW0gb2YgZnVuY3Rpb25zLlxuICpcbiAqIF9Ob3RlOl8gVGhpcyBmdW5jdGlvbiBpcyBpbmNsdWRlZCBpbiBvcmRlciB0byBzdXBwb3J0IHRoZSBmYW50YXN5IGxhbmRcbiAqIHNwZWNpZmljYXRpb24uXG4gKlxuICogX19TaWduYXR1cmVfXzogQ2FsbGVkIGJvdW5kIHRvIGBTdHJlYW0gKGEgLT4gYilgOiBgYSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBzdHJlYW0uYXBcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgdmFsdWVzIHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSBhIG5ldyBzdHJhbSB3aXRoIHRoZSBmdW5jdGlvbnMgYXBwbGllZCB0byB2YWx1ZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIGFkZCA9IGZseWQuY3VycnlOKDIsIGZ1bmN0aW9uKHgsIHkpIHsgcmV0dXJuIHggKyB5OyB9KTtcbiAqIHZhciBudW1iZXJzMSA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgbnVtYmVyczIgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIGFkZFRvTnVtYmVyczEgPSBmbHlkLm1hcChhZGQsIG51bWJlcnMxKTtcbiAqIHZhciBhZGRlZCA9IGFkZFRvTnVtYmVyczEuYXAobnVtYmVyczIpO1xuICovXG5mdW5jdGlvbiBhcChzMikge1xuICB2YXIgczEgPSB0aGlzO1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzMSwgczIsIHNlbGYpIHsgc2VsZihzMS52YWwoczIudmFsKSk7IH0sIFtzMSwgczJdKTtcbn1cblxuLyoqXG4gKiBHZXQgYSBodW1hbiByZWFkYWJsZSB2aWV3IG9mIGEgc3RyZWFtXG4gKiBAbmFtZSBzdHJlYW0udG9TdHJpbmdcbiAqIEByZXR1cm4ge1N0cmluZ30gdGhlIHN0cmVhbSBzdHJpbmcgcmVwcmVzZW50YXRpb25cbiAqL1xuZnVuY3Rpb24gc3RyZWFtVG9TdHJpbmcoKSB7XG4gIHJldHVybiAnc3RyZWFtKCcgKyB0aGlzLnZhbCArICcpJztcbn1cblxuLyoqXG4gKiBAbmFtZSBzdHJlYW0uZW5kXG4gKiBAbWVtYmVyb2Ygc3RyZWFtXG4gKiBBIHN0cmVhbSB0aGF0IGVtaXRzIGB0cnVlYCB3aGVuIHRoZSBzdHJlYW0gZW5kcy4gSWYgYHRydWVgIGlzIHB1c2hlZCBkb3duIHRoZVxuICogc3RyZWFtIHRoZSBwYXJlbnQgc3RyZWFtIGVuZHMuXG4gKi9cblxuLyoqXG4gKiBAbmFtZSBzdHJlYW0ub2ZcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mIHN0cmVhbVxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gd2l0aCBgdmFsdWVgIGFzIGl0cyBpbml0aWFsIHZhbHVlLiBJdCBpcyBpZGVudGljYWwgdG9cbiAqIGNhbGxpbmcgYGZseWQuc3RyZWFtYCB3aXRoIG9uZSBhcmd1bWVudC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSAoYSlgOiBgYiAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gdGhlIGluaXRpYWwgdmFsdWVcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4gPSBmbHlkLnN0cmVhbSgxKTtcbiAqIHZhciBtID0gbi5vZigxKTtcbiAqL1xuXG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gUFJJVkFURSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gLy9cbi8qKlxuICogQHByaXZhdGVcbiAqIENyZWF0ZSBhIHN0cmVhbSB3aXRoIG5vIGRlcGVuZGVuY2llcyBhbmQgbm8gdmFsdWVcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBhIGZseWQgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVN0cmVhbSgpIHtcbiAgZnVuY3Rpb24gcyhuKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiBzLnZhbFxuICAgIHVwZGF0ZVN0cmVhbVZhbHVlKHMsIG4pXG4gICAgcmV0dXJuIHNcbiAgfVxuICBzLmhhc1ZhbCA9IGZhbHNlO1xuICBzLnZhbCA9IHVuZGVmaW5lZDtcbiAgcy52YWxzID0gW107XG4gIHMubGlzdGVuZXJzID0gW107XG4gIHMucXVldWVkID0gZmFsc2U7XG4gIHMuZW5kID0gdW5kZWZpbmVkO1xuICBzLm1hcCA9IGJvdW5kTWFwO1xuICBzLmFwID0gYXA7XG4gIHMub2YgPSBmbHlkLnN0cmVhbTtcbiAgcy50b1N0cmluZyA9IHN0cmVhbVRvU3RyaW5nO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQ3JlYXRlIGEgZGVwZW5kZW50IHN0cmVhbVxuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXMgLSBhbiBhcnJheSBvZiB0aGUgc3RyZWFtc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdXNlZCB0byBjYWxjdWxhdGUgdGhlIG5ldyBzdHJlYW0gdmFsdWVcbiAqIGZyb20gdGhlIGRlcGVuZGVuY2llc1xuICogQHJldHVybiB7c3RyZWFtfSB0aGUgY3JlYXRlZCBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRGVwZW5kZW50U3RyZWFtKGRlcHMsIGZuKSB7XG4gIHZhciBzID0gY3JlYXRlU3RyZWFtKCk7XG4gIHMuZm4gPSBmbjtcbiAgcy5kZXBzID0gZGVwcztcbiAgcy5kZXBzTWV0ID0gZmFsc2U7XG4gIHMuZGVwc0NoYW5nZWQgPSBkZXBzLmxlbmd0aCA+IDAgPyBbXSA6IHVuZGVmaW5lZDtcbiAgcy5zaG91bGRVcGRhdGUgPSBmYWxzZTtcbiAgYWRkTGlzdGVuZXJzKGRlcHMsIHMpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQ2hlY2sgaWYgYWxsIHRoZSBkZXBlbmRlbmNpZXMgaGF2ZSB2YWx1ZXNcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHRvIGNoZWNrIGRlcGVuY2VuY2llcyBmcm9tXG4gKiBAcmV0dXJuIHtCb29sZWFufSBgdHJ1ZWAgaWYgYWxsIGRlcGVuZGVuY2llcyBoYXZlIHZhbGVzLCBgZmFsc2VgIG90aGVyd2lzZVxuICovXG5mdW5jdGlvbiBpbml0aWFsRGVwc05vdE1ldChzdHJlYW0pIHtcbiAgc3RyZWFtLmRlcHNNZXQgPSBzdHJlYW0uZGVwcy5ldmVyeShmdW5jdGlvbihzKSB7XG4gICAgcmV0dXJuIHMuaGFzVmFsO1xuICB9KTtcbiAgcmV0dXJuICFzdHJlYW0uZGVwc01ldDtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogVXBkYXRlIGEgZGVwZW5kZW50IHN0cmVhbSB1c2luZyBpdHMgZGVwZW5kZW5jaWVzIGluIGFuIGF0b21pYyB3YXlcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtIHRvIHVwZGF0ZVxuICovXG5mdW5jdGlvbiB1cGRhdGVTdHJlYW0ocykge1xuICBpZiAoKHMuZGVwc01ldCAhPT0gdHJ1ZSAmJiBpbml0aWFsRGVwc05vdE1ldChzKSkgfHxcbiAgICAgIChzLmVuZCAhPT0gdW5kZWZpbmVkICYmIHMuZW5kLnZhbCA9PT0gdHJ1ZSkpIHJldHVybjtcbiAgaWYgKGluU3RyZWFtICE9PSB1bmRlZmluZWQpIHtcbiAgICB0b1VwZGF0ZS5wdXNoKHMpO1xuICAgIHJldHVybjtcbiAgfVxuICBpblN0cmVhbSA9IHM7XG4gIGlmIChzLmRlcHNDaGFuZ2VkKSBzLmZuQXJnc1tzLmZuQXJncy5sZW5ndGggLSAxXSA9IHMuZGVwc0NoYW5nZWQ7XG4gIHZhciByZXR1cm5WYWwgPSBzLmZuLmFwcGx5KHMuZm4sIHMuZm5BcmdzKTtcbiAgaWYgKHJldHVyblZhbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcyhyZXR1cm5WYWwpO1xuICB9XG4gIGluU3RyZWFtID0gdW5kZWZpbmVkO1xuICBpZiAocy5kZXBzQ2hhbmdlZCAhPT0gdW5kZWZpbmVkKSBzLmRlcHNDaGFuZ2VkID0gW107XG4gIHMuc2hvdWxkVXBkYXRlID0gZmFsc2U7XG4gIGlmIChmbHVzaGluZyA9PT0gZmFsc2UpIGZsdXNoVXBkYXRlKCk7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFVwZGF0ZSB0aGUgZGVwZW5kZW5jaWVzIG9mIGEgc3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZURlcHMocykge1xuICB2YXIgaSwgbywgbGlzdFxuICB2YXIgbGlzdGVuZXJzID0gcy5saXN0ZW5lcnM7XG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyArK2kpIHtcbiAgICBsaXN0ID0gbGlzdGVuZXJzW2ldO1xuICAgIGlmIChsaXN0LmVuZCA9PT0gcykge1xuICAgICAgZW5kU3RyZWFtKGxpc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobGlzdC5kZXBzQ2hhbmdlZCAhPT0gdW5kZWZpbmVkKSBsaXN0LmRlcHNDaGFuZ2VkLnB1c2gocyk7XG4gICAgICBsaXN0LnNob3VsZFVwZGF0ZSA9IHRydWU7XG4gICAgICBmaW5kRGVwcyhsaXN0KTtcbiAgICB9XG4gIH1cbiAgZm9yICg7IG9yZGVyTmV4dElkeCA+PSAwOyAtLW9yZGVyTmV4dElkeCkge1xuICAgIG8gPSBvcmRlcltvcmRlck5leHRJZHhdO1xuICAgIGlmIChvLnNob3VsZFVwZGF0ZSA9PT0gdHJ1ZSkgdXBkYXRlU3RyZWFtKG8pO1xuICAgIG8ucXVldWVkID0gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQWRkIHN0cmVhbSBkZXBlbmRlbmNpZXMgdG8gdGhlIGdsb2JhbCBgb3JkZXJgIHF1ZXVlLlxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICogQHNlZSB1cGRhdGVEZXBzXG4gKi9cbmZ1bmN0aW9uIGZpbmREZXBzKHMpIHtcbiAgdmFyIGlcbiAgdmFyIGxpc3RlbmVycyA9IHMubGlzdGVuZXJzO1xuICBpZiAocy5xdWV1ZWQgPT09IGZhbHNlKSB7XG4gICAgcy5xdWV1ZWQgPSB0cnVlO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGZpbmREZXBzKGxpc3RlbmVyc1tpXSk7XG4gICAgfVxuICAgIG9yZGVyWysrb3JkZXJOZXh0SWR4XSA9IHM7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBmbHVzaFVwZGF0ZSgpIHtcbiAgZmx1c2hpbmcgPSB0cnVlO1xuICB3aGlsZSAodG9VcGRhdGUubGVuZ3RoID4gMCkge1xuICAgIHZhciBzID0gdG9VcGRhdGUuc2hpZnQoKTtcbiAgICBpZiAocy52YWxzLmxlbmd0aCA+IDApIHMudmFsID0gcy52YWxzLnNoaWZ0KCk7XG4gICAgdXBkYXRlRGVwcyhzKTtcbiAgfVxuICBmbHVzaGluZyA9IGZhbHNlO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBQdXNoIGRvd24gYSB2YWx1ZSBpbnRvIGEgc3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZVN0cmVhbVZhbHVlKHMsIG4pIHtcbiAgaWYgKG4gIT09IHVuZGVmaW5lZCAmJiBuICE9PSBudWxsICYmIGlzRnVuY3Rpb24obi50aGVuKSkge1xuICAgIG4udGhlbihzKTtcbiAgICByZXR1cm47XG4gIH1cbiAgcy52YWwgPSBuO1xuICBzLmhhc1ZhbCA9IHRydWU7XG4gIGlmIChpblN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgIHVwZGF0ZURlcHMocyk7XG4gICAgaWYgKHRvVXBkYXRlLmxlbmd0aCA+IDApIGZsdXNoVXBkYXRlKCk7IGVsc2UgZmx1c2hpbmcgPSBmYWxzZTtcbiAgfSBlbHNlIGlmIChpblN0cmVhbSA9PT0gcykge1xuICAgIG1hcmtMaXN0ZW5lcnMocywgcy5saXN0ZW5lcnMpO1xuICB9IGVsc2Uge1xuICAgIHMudmFscy5wdXNoKG4pO1xuICAgIHRvVXBkYXRlLnB1c2gocyk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBtYXJrTGlzdGVuZXJzKHMsIGxpc3RzKSB7XG4gIHZhciBpLCBsaXN0O1xuICBmb3IgKGkgPSAwOyBpIDwgbGlzdHMubGVuZ3RoOyArK2kpIHtcbiAgICBsaXN0ID0gbGlzdHNbaV07XG4gICAgaWYgKGxpc3QuZW5kICE9PSBzKSB7XG4gICAgICBpZiAobGlzdC5kZXBzQ2hhbmdlZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxpc3QuZGVwc0NoYW5nZWQucHVzaChzKTtcbiAgICAgIH1cbiAgICAgIGxpc3Quc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5kU3RyZWFtKGxpc3QpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBBZGQgZGVwZW5kZW5jaWVzIHRvIGEgc3RyZWFtXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llc1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICovXG5mdW5jdGlvbiBhZGRMaXN0ZW5lcnMoZGVwcywgcykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGRlcHMubGVuZ3RoOyArK2kpIHtcbiAgICBkZXBzW2ldLmxpc3RlbmVycy5wdXNoKHMpO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFJlbW92ZXMgYW4gc3RyZWFtIGZyb20gYSBkZXBlbmRlbmN5IGFycmF5XG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llc1xuICovXG5mdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihzLCBsaXN0ZW5lcnMpIHtcbiAgdmFyIGlkeCA9IGxpc3RlbmVycy5pbmRleE9mKHMpO1xuICBsaXN0ZW5lcnNbaWR4XSA9IGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV07XG4gIGxpc3RlbmVycy5sZW5ndGgtLTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogRGV0YWNoIGEgc3RyZWFtIGZyb20gaXRzIGRlcGVuZGVuY2llc1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbVxuICovXG5mdW5jdGlvbiBkZXRhY2hEZXBzKHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzLmRlcHMubGVuZ3RoOyArK2kpIHtcbiAgICByZW1vdmVMaXN0ZW5lcihzLCBzLmRlcHNbaV0ubGlzdGVuZXJzKTtcbiAgfVxuICBzLmRlcHMubGVuZ3RoID0gMDtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogRW5kcyBhIHN0cmVhbVxuICovXG5mdW5jdGlvbiBlbmRTdHJlYW0ocykge1xuICBpZiAocy5kZXBzICE9PSB1bmRlZmluZWQpIGRldGFjaERlcHMocyk7XG4gIGlmIChzLmVuZCAhPT0gdW5kZWZpbmVkKSBkZXRhY2hEZXBzKHMuZW5kKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogdHJhbnNkdWNlciBzdHJlYW0gdHJhbnNmb3JtZXJcbiAqL1xuZnVuY3Rpb24gU3RyZWFtVHJhbnNmb3JtZXIoKSB7IH1cblN0cmVhbVRyYW5zZm9ybWVyLnByb3RvdHlwZVsnQEB0cmFuc2R1Y2VyL2luaXQnXSA9IGZ1bmN0aW9uKCkgeyB9O1xuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvcmVzdWx0J10gPSBmdW5jdGlvbigpIHsgfTtcblN0cmVhbVRyYW5zZm9ybWVyLnByb3RvdHlwZVsnQEB0cmFuc2R1Y2VyL3N0ZXAnXSA9IGZ1bmN0aW9uKHMsIHYpIHsgcmV0dXJuIHY7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZmx5ZDtcbiIsInZhciBfYXJpdHkgPSByZXF1aXJlKCcuL2ludGVybmFsL19hcml0eScpO1xudmFyIF9jdXJyeTEgPSByZXF1aXJlKCcuL2ludGVybmFsL19jdXJyeTEnKTtcbnZhciBfY3VycnkyID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9fY3VycnkyJyk7XG52YXIgX2N1cnJ5TiA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2N1cnJ5TicpO1xuXG5cbi8qKlxuICogUmV0dXJucyBhIGN1cnJpZWQgZXF1aXZhbGVudCBvZiB0aGUgcHJvdmlkZWQgZnVuY3Rpb24sIHdpdGggdGhlIHNwZWNpZmllZFxuICogYXJpdHkuIFRoZSBjdXJyaWVkIGZ1bmN0aW9uIGhhcyB0d28gdW51c3VhbCBjYXBhYmlsaXRpZXMuIEZpcnN0LCBpdHNcbiAqIGFyZ3VtZW50cyBuZWVkbid0IGJlIHByb3ZpZGVkIG9uZSBhdCBhIHRpbWUuIElmIGBnYCBpcyBgUi5jdXJyeU4oMywgZilgLCB0aGVcbiAqIGZvbGxvd2luZyBhcmUgZXF1aXZhbGVudDpcbiAqXG4gKiAgIC0gYGcoMSkoMikoMylgXG4gKiAgIC0gYGcoMSkoMiwgMylgXG4gKiAgIC0gYGcoMSwgMikoMylgXG4gKiAgIC0gYGcoMSwgMiwgMylgXG4gKlxuICogU2Vjb25kbHksIHRoZSBzcGVjaWFsIHBsYWNlaG9sZGVyIHZhbHVlIGBSLl9fYCBtYXkgYmUgdXNlZCB0byBzcGVjaWZ5XG4gKiBcImdhcHNcIiwgYWxsb3dpbmcgcGFydGlhbCBhcHBsaWNhdGlvbiBvZiBhbnkgY29tYmluYXRpb24gb2YgYXJndW1lbnRzLFxuICogcmVnYXJkbGVzcyBvZiB0aGVpciBwb3NpdGlvbnMuIElmIGBnYCBpcyBhcyBhYm92ZSBhbmQgYF9gIGlzIGBSLl9fYCwgdGhlXG4gKiBmb2xsb3dpbmcgYXJlIGVxdWl2YWxlbnQ6XG4gKlxuICogICAtIGBnKDEsIDIsIDMpYFxuICogICAtIGBnKF8sIDIsIDMpKDEpYFxuICogICAtIGBnKF8sIF8sIDMpKDEpKDIpYFxuICogICAtIGBnKF8sIF8sIDMpKDEsIDIpYFxuICogICAtIGBnKF8sIDIpKDEpKDMpYFxuICogICAtIGBnKF8sIDIpKDEsIDMpYFxuICogICAtIGBnKF8sIDIpKF8sIDMpKDEpYFxuICpcbiAqIEBmdW5jXG4gKiBAbWVtYmVyT2YgUlxuICogQHNpbmNlIHYwLjUuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAc2lnIE51bWJlciAtPiAoKiAtPiBhKSAtPiAoKiAtPiBhKVxuICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgYXJpdHkgZm9yIHRoZSByZXR1cm5lZCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjdXJyeS5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG5ldywgY3VycmllZCBmdW5jdGlvbi5cbiAqIEBzZWUgUi5jdXJyeVxuICogQGV4YW1wbGVcbiAqXG4gKiAgICAgIHZhciBzdW1BcmdzID0gKC4uLmFyZ3MpID0+IFIuc3VtKGFyZ3MpO1xuICpcbiAqICAgICAgdmFyIGN1cnJpZWRBZGRGb3VyTnVtYmVycyA9IFIuY3VycnlOKDQsIHN1bUFyZ3MpO1xuICogICAgICB2YXIgZiA9IGN1cnJpZWRBZGRGb3VyTnVtYmVycygxLCAyKTtcbiAqICAgICAgdmFyIGcgPSBmKDMpO1xuICogICAgICBnKDQpOyAvLz0+IDEwXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gX2N1cnJ5MihmdW5jdGlvbiBjdXJyeU4obGVuZ3RoLCBmbikge1xuICBpZiAobGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIF9jdXJyeTEoZm4pO1xuICB9XG4gIHJldHVybiBfYXJpdHkobGVuZ3RoLCBfY3VycnlOKGxlbmd0aCwgW10sIGZuKSk7XG59KTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2FyaXR5KG4sIGZuKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4gIHN3aXRjaCAobikge1xuICAgIGNhc2UgMDogcmV0dXJuIGZ1bmN0aW9uKCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbihhMCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbihhMCwgYTEpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMikgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDQ6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMykgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDU6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSA2OiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDc6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNikgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDg6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgY2FzZSA5OiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDEwOiByZXR1cm4gZnVuY3Rpb24oYTAsIGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCwgYTkpIHsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCB0byBfYXJpdHkgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyIG5vIGdyZWF0ZXIgdGhhbiB0ZW4nKTtcbiAgfVxufTtcbiIsInZhciBfaXNQbGFjZWhvbGRlciA9IHJlcXVpcmUoJy4vX2lzUGxhY2Vob2xkZXInKTtcblxuXG4vKipcbiAqIE9wdGltaXplZCBpbnRlcm5hbCBvbmUtYXJpdHkgY3VycnkgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeTEoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGYxKGEpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCBfaXNQbGFjZWhvbGRlcihhKSkge1xuICAgICAgcmV0dXJuIGYxO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH07XG59O1xuIiwidmFyIF9jdXJyeTEgPSByZXF1aXJlKCcuL19jdXJyeTEnKTtcbnZhciBfaXNQbGFjZWhvbGRlciA9IHJlcXVpcmUoJy4vX2lzUGxhY2Vob2xkZXInKTtcblxuXG4vKipcbiAqIE9wdGltaXplZCBpbnRlcm5hbCB0d28tYXJpdHkgY3VycnkgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeTIoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGYyKGEsIGIpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIGYyO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gX2lzUGxhY2Vob2xkZXIoYSkgPyBmMlxuICAgICAgICAgICAgIDogX2N1cnJ5MShmdW5jdGlvbihfYikgeyByZXR1cm4gZm4oYSwgX2IpOyB9KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBfaXNQbGFjZWhvbGRlcihhKSAmJiBfaXNQbGFjZWhvbGRlcihiKSA/IGYyXG4gICAgICAgICAgICAgOiBfaXNQbGFjZWhvbGRlcihhKSA/IF9jdXJyeTEoZnVuY3Rpb24oX2EpIHsgcmV0dXJuIGZuKF9hLCBiKTsgfSlcbiAgICAgICAgICAgICA6IF9pc1BsYWNlaG9sZGVyKGIpID8gX2N1cnJ5MShmdW5jdGlvbihfYikgeyByZXR1cm4gZm4oYSwgX2IpOyB9KVxuICAgICAgICAgICAgIDogZm4oYSwgYik7XG4gICAgfVxuICB9O1xufTtcbiIsInZhciBfYXJpdHkgPSByZXF1aXJlKCcuL19hcml0eScpO1xudmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogSW50ZXJuYWwgY3VycnlOIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGggVGhlIGFyaXR5IG9mIHRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gcmVjZWl2ZWQgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlY2VpdmVkIHRodXMgZmFyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjdXJyaWVkIGZ1bmN0aW9uLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9jdXJyeU4obGVuZ3RoLCByZWNlaXZlZCwgZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBjb21iaW5lZCA9IFtdO1xuICAgIHZhciBhcmdzSWR4ID0gMDtcbiAgICB2YXIgbGVmdCA9IGxlbmd0aDtcbiAgICB2YXIgY29tYmluZWRJZHggPSAwO1xuICAgIHdoaWxlIChjb21iaW5lZElkeCA8IHJlY2VpdmVkLmxlbmd0aCB8fCBhcmdzSWR4IDwgYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIGlmIChjb21iaW5lZElkeCA8IHJlY2VpdmVkLmxlbmd0aCAmJlxuICAgICAgICAgICghX2lzUGxhY2Vob2xkZXIocmVjZWl2ZWRbY29tYmluZWRJZHhdKSB8fFxuICAgICAgICAgICBhcmdzSWR4ID49IGFyZ3VtZW50cy5sZW5ndGgpKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlY2VpdmVkW2NvbWJpbmVkSWR4XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IGFyZ3VtZW50c1thcmdzSWR4XTtcbiAgICAgICAgYXJnc0lkeCArPSAxO1xuICAgICAgfVxuICAgICAgY29tYmluZWRbY29tYmluZWRJZHhdID0gcmVzdWx0O1xuICAgICAgaWYgKCFfaXNQbGFjZWhvbGRlcihyZXN1bHQpKSB7XG4gICAgICAgIGxlZnQgLT0gMTtcbiAgICAgIH1cbiAgICAgIGNvbWJpbmVkSWR4ICs9IDE7XG4gICAgfVxuICAgIHJldHVybiBsZWZ0IDw9IDAgPyBmbi5hcHBseSh0aGlzLCBjb21iaW5lZClcbiAgICAgICAgICAgICAgICAgICAgIDogX2FyaXR5KGxlZnQsIF9jdXJyeU4obGVuZ3RoLCBjb21iaW5lZCwgZm4pKTtcbiAgfTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIF9pc1BsYWNlaG9sZGVyKGEpIHtcbiAgcmV0dXJuIGEgIT0gbnVsbCAmJlxuICAgICAgICAgdHlwZW9mIGEgPT09ICdvYmplY3QnICYmXG4gICAgICAgICBhWydAQGZ1bmN0aW9uYWwvcGxhY2Vob2xkZXInXSA9PT0gdHJ1ZTtcbn07XG4iLCJ2YXIgZmx5ZCA9IHJlcXVpcmUoJy4uLy4uL2xpYicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG1lcmdlQWxsKHN0cmVhbXMpIHtcbiAgdmFyIHMgPSBmbHlkLmltbWVkaWF0ZShmbHlkLmNvbWJpbmUoZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNlbGYgPSBhcmd1bWVudHNbYXJndW1lbnRzLmxlbmd0aCAtIDJdO1xuICAgIGlmIChhcmd1bWVudHNbYXJndW1lbnRzLmxlbmd0aCAtIDFdWzBdKSB7XG4gICAgICBzZWxmKGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMV1bMF0oKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwLCBhcmd1bWVudHMubGVuZ3RoIC0gMilcbiAgICAuc29tZShmdW5jdGlvbihzMSkge1xuICAgICAgaWYgKHMxLmhhc1ZhbCkge1xuICAgICAgICBzZWxmKHMxLnZhbCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICB9LCBzdHJlYW1zKSk7XG4gIGZseWQuZW5kc09uKGZseWQuY29tYmluZShmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgc3RyZWFtcy5tYXAoZnVuY3Rpb24oc20pIHsgcmV0dXJuIHNtLmVuZDsgfSkpLCBzKTtcbiAgcmV0dXJuIHM7XG59O1xuXG4iXX0= | |
| require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
| 'use strict'; | |
| var curryN = require('ramda/src/curryN'); | |
| // Utility | |
| function isFunction(obj) { | |
| return !!(obj && obj.constructor && obj.call && obj.apply); | |
| } | |
| function trueFn() { return true; } | |
| // Globals | |
| var toUpdate = []; | |
| var inStream; | |
| var order = []; | |
| var orderNextIdx = -1; | |
| var flushing = false; | |
| /** @namespace */ | |
| var flyd = {} | |
| // /////////////////////////// API ///////////////////////////////// // | |
| /** | |
| * Creates a new stream | |
| * | |
| * __Signature__: `a -> Stream a` | |
| * | |
| * @name flyd.stream | |
| * @param {*} initialValue - (Optional) the initial value of the stream | |
| * @return {stream} the stream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); // Stream with initial value `1` | |
| * var s = flyd.stream(); // Stream with no initial value | |
| */ | |
| flyd.stream = function(initialValue) { | |
| var endStream = createDependentStream([], trueFn); | |
| var s = createStream(); | |
| s.end = endStream; | |
| s.fnArgs = []; | |
| endStream.listeners.push(s); | |
| if (arguments.length > 0) s(initialValue); | |
| return s; | |
| } | |
| /** | |
| * Create a new dependent stream | |
| * | |
| * __Signature__: `(...Stream * -> Stream b -> b) -> [Stream *] -> Stream b` | |
| * | |
| * @name flyd.combine | |
| * @param {Function} fn - the function used to combine the streams | |
| * @param {Array<stream>} dependencies - the streams that this one depends on | |
| * @return {stream} the dependent stream | |
| * | |
| * @example | |
| * var n1 = flyd.stream(0); | |
| * var n2 = flyd.stream(0); | |
| * var max = flyd.combine(function(n1, n2, self, changed) { | |
| * return n1() > n2() ? n1() : n2(); | |
| * }, [n1, n2]); | |
| */ | |
| flyd.combine = curryN(2, combine); | |
| function combine(fn, streams) { | |
| var i, s, deps, depEndStreams; | |
| var endStream = createDependentStream([], trueFn); | |
| deps = []; depEndStreams = []; | |
| for (i = 0; i < streams.length; ++i) { | |
| if (streams[i] !== undefined) { | |
| deps.push(streams[i]); | |
| if (streams[i].end !== undefined) depEndStreams.push(streams[i].end); | |
| } | |
| } | |
| s = createDependentStream(deps, fn); | |
| s.depsChanged = []; | |
| s.fnArgs = s.deps.concat([s, s.depsChanged]); | |
| s.end = endStream; | |
| endStream.listeners.push(s); | |
| addListeners(depEndStreams, endStream); | |
| endStream.deps = depEndStreams; | |
| updateStream(s); | |
| return s; | |
| } | |
| /** | |
| * Returns `true` if the supplied argument is a Flyd stream and `false` otherwise. | |
| * | |
| * __Signature__: `* -> Boolean` | |
| * | |
| * @name flyd.isStream | |
| * @param {*} value - the value to test | |
| * @return {Boolean} `true` if is a Flyd streamn, `false` otherwise | |
| * | |
| * @example | |
| * var s = flyd.stream(1); | |
| * var n = 1; | |
| * flyd.isStream(s); //=> true | |
| * flyd.isStream(n); //=> false | |
| */ | |
| flyd.isStream = function(stream) { | |
| return isFunction(stream) && 'hasVal' in stream; | |
| } | |
| /** | |
| * Invokes the body (the function to calculate the value) of a dependent stream | |
| * | |
| * By default the body of a dependent stream is only called when all the streams | |
| * upon which it depends has a value. `immediate` can circumvent this behaviour. | |
| * It immediately invokes the body of a dependent stream. | |
| * | |
| * __Signature__: `Stream a -> Stream a` | |
| * | |
| * @name flyd.immediate | |
| * @param {stream} stream - the dependent stream | |
| * @return {stream} the same stream | |
| * | |
| * @example | |
| * var s = flyd.stream(); | |
| * var hasItems = flyd.immediate(flyd.combine(function(s) { | |
| * return s() !== undefined && s().length > 0; | |
| * }, [s]); | |
| * console.log(hasItems()); // logs `false`. Had `immediate` not been | |
| * // used `hasItems()` would've returned `undefined` | |
| * s([1]); | |
| * console.log(hasItems()); // logs `true`. | |
| * s([]); | |
| * console.log(hasItems()); // logs `false`. | |
| */ | |
| flyd.immediate = function(s) { | |
| if (s.depsMet === false) { | |
| s.depsMet = true; | |
| updateStream(s); | |
| } | |
| return s; | |
| } | |
| /** | |
| * Changes which `endsStream` should trigger the ending of `s`. | |
| * | |
| * __Signature__: `Stream a -> Stream b -> Stream b` | |
| * | |
| * @name flyd.endsOn | |
| * @param {stream} endStream - the stream to trigger the ending | |
| * @param {stream} stream - the stream to be ended by the endStream | |
| * @param {stream} the stream modified to be ended by endStream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); | |
| * var killer = flyd.stream(); | |
| * // `double` ends when `n` ends or when `killer` emits any value | |
| * var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.combine(function(n) { | |
| * return 2 * n(); | |
| * }, [n]); | |
| */ | |
| flyd.endsOn = function(endS, s) { | |
| detachDeps(s.end); | |
| endS.listeners.push(s.end); | |
| s.end.deps.push(endS); | |
| return s; | |
| } | |
| /** | |
| * Map a stream | |
| * | |
| * Returns a new stream consisting of every value from `s` passed through | |
| * `fn`. I.e. `map` creates a new stream that listens to `s` and | |
| * applies `fn` to every new value. | |
| * __Signature__: `(a -> result) -> Stream a -> Stream result` | |
| * | |
| * @name flyd.map | |
| * @param {Function} fn - the function that produces the elements of the new stream | |
| * @param {stream} stream - the stream to map | |
| * @return {stream} a new stream with the mapped values | |
| * | |
| * @example | |
| * var numbers = flyd.stream(0); | |
| * var squaredNumbers = flyd.map(function(n) { return n*n; }, numbers); | |
| */ | |
| // Library functions use self callback to accept (null, undefined) update triggers. | |
| flyd.map = curryN(2, function(f, s) { | |
| return combine(function(s, self) { self(f(s.val)); }, [s]); | |
| }) | |
| /** | |
| * Listen to stream events | |
| * | |
| * Similar to `map` except that the returned stream is empty. Use `on` for doing | |
| * side effects in reaction to stream changes. Use the returned stream only if you | |
| * need to manually end it. | |
| * | |
| * __Signature__: `(a -> result) -> Stream a -> Stream undefined` | |
| * | |
| * @name flyd.on | |
| * @param {Function} cb - the callback | |
| * @param {stream} stream - the stream | |
| * @return {stream} an empty stream (can be ended) | |
| */ | |
| flyd.on = curryN(2, function(f, s) { | |
| return combine(function(s) { f(s.val); }, [s]); | |
| }) | |
| /** | |
| * Creates a new stream with the results of calling the function on every incoming | |
| * stream with and accumulator and the incoming value. | |
| * | |
| * __Signature__: `(a -> b -> a) -> a -> Stream b -> Stream a` | |
| * | |
| * @name flyd.scan | |
| * @param {Function} fn - the function to call | |
| * @param {*} val - the initial value of the accumulator | |
| * @param {stream} stream - the stream source | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var numbers = flyd.stream(); | |
| * var sum = flyd.scan(function(sum, n) { return sum+n; }, 0, numbers); | |
| * numbers(2)(3)(5); | |
| * sum(); // 10 | |
| */ | |
| flyd.scan = curryN(3, function(f, acc, s) { | |
| var ns = combine(function(s, self) { | |
| self(acc = f(acc, s.val)); | |
| }, [s]); | |
| if (!ns.hasVal) ns(acc); | |
| return ns; | |
| }); | |
| /** | |
| * Creates a new stream down which all values from both `stream1` and `stream2` | |
| * will be sent. | |
| * | |
| * __Signature__: `Stream a -> Stream a -> Stream a` | |
| * | |
| * @name flyd.merge | |
| * @param {stream} source1 - one stream to be merged | |
| * @param {stream} source2 - the other stream to be merged | |
| * @return {stream} a stream with the values from both sources | |
| * | |
| * @example | |
| * var btn1Clicks = flyd.stream(); | |
| * button1Elm.addEventListener(btn1Clicks); | |
| * var btn2Clicks = flyd.stream(); | |
| * button2Elm.addEventListener(btn2Clicks); | |
| * var allClicks = flyd.merge(btn1Clicks, btn2Clicks); | |
| */ | |
| flyd.merge = curryN(2, function(s1, s2) { | |
| var s = flyd.immediate(combine(function(s1, s2, self, changed) { | |
| if (changed[0]) { | |
| self(changed[0]()); | |
| } else if (s1.hasVal) { | |
| self(s1.val); | |
| } else if (s2.hasVal) { | |
| self(s2.val); | |
| } | |
| }, [s1, s2])); | |
| flyd.endsOn(combine(function() { | |
| return true; | |
| }, [s1.end, s2.end]), s); | |
| return s; | |
| }); | |
| /** | |
| * Creates a new stream resulting from applying `transducer` to `stream`. | |
| * | |
| * __Signature__: `Transducer -> Stream a -> Stream b` | |
| * | |
| * @name flyd.transduce | |
| * @param {Transducer} xform - the transducer transformation | |
| * @param {stream} source - the stream source | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var t = require('transducers.js'); | |
| * | |
| * var results = []; | |
| * var s1 = flyd.stream(); | |
| * var tx = t.compose(t.map(function(x) { return x * 2; }), t.dedupe()); | |
| * var s2 = flyd.transduce(tx, s1); | |
| * flyd.combine(function(s2) { results.push(s2()); }, [s2]); | |
| * s1(1)(1)(2)(3)(3)(3)(4); | |
| * results; // => [2, 4, 6, 8] | |
| */ | |
| flyd.transduce = curryN(2, function(xform, source) { | |
| xform = xform(new StreamTransformer()); | |
| return combine(function(source, self) { | |
| var res = xform['@@transducer/step'](undefined, source.val); | |
| if (res && res['@@transducer/reduced'] === true) { | |
| self.end(true); | |
| return res['@@transducer/value']; | |
| } else { | |
| return res; | |
| } | |
| }, [source]); | |
| }); | |
| /** | |
| * Returns `fn` curried to `n`. Use this function to curry functions exposed by | |
| * modules for Flyd. | |
| * | |
| * @name flyd.curryN | |
| * @function | |
| * @param {Integer} arity - the function arity | |
| * @param {Function} fn - the function to curry | |
| * @return {Function} the curried function | |
| * | |
| * @example | |
| * function add(x, y) { return x + y; }; | |
| * var a = flyd.curryN(2, add); | |
| * a(2)(4) // => 6 | |
| */ | |
| flyd.curryN = curryN | |
| /** | |
| * Returns a new stream identical to the original except every | |
| * value will be passed through `f`. | |
| * | |
| * _Note:_ This function is included in order to support the fantasy land | |
| * specification. | |
| * | |
| * __Signature__: Called bound to `Stream a`: `(a -> b) -> Stream b` | |
| * | |
| * @name stream.map | |
| * @param {Function} function - the function to apply | |
| * @return {stream} a new stream with the values mapped | |
| * | |
| * @example | |
| * var numbers = flyd.stream(0); | |
| * var squaredNumbers = numbers.map(function(n) { return n*n; }); | |
| */ | |
| function boundMap(f) { return flyd.map(f, this); } | |
| /** | |
| * Returns a new stream which is the result of applying the | |
| * functions from `this` stream to the values in `stream` parameter. | |
| * | |
| * `this` stream must be a stream of functions. | |
| * | |
| * _Note:_ This function is included in order to support the fantasy land | |
| * specification. | |
| * | |
| * __Signature__: Called bound to `Stream (a -> b)`: `a -> Stream b` | |
| * | |
| * @name stream.ap | |
| * @param {stream} stream - the values stream | |
| * @return {stream} a new stram with the functions applied to values | |
| * | |
| * @example | |
| * var add = flyd.curryN(2, function(x, y) { return x + y; }); | |
| * var numbers1 = flyd.stream(); | |
| * var numbers2 = flyd.stream(); | |
| * var addToNumbers1 = flyd.map(add, numbers1); | |
| * var added = addToNumbers1.ap(numbers2); | |
| */ | |
| function ap(s2) { | |
| var s1 = this; | |
| return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]); | |
| } | |
| /** | |
| * Get a human readable view of a stream | |
| * @name stream.toString | |
| * @return {String} the stream string representation | |
| */ | |
| function streamToString() { | |
| return 'stream(' + this.val + ')'; | |
| } | |
| /** | |
| * @name stream.end | |
| * @memberof stream | |
| * A stream that emits `true` when the stream ends. If `true` is pushed down the | |
| * stream the parent stream ends. | |
| */ | |
| /** | |
| * @name stream.of | |
| * @function | |
| * @memberof stream | |
| * Returns a new stream with `value` as its initial value. It is identical to | |
| * calling `flyd.stream` with one argument. | |
| * | |
| * __Signature__: Called bound to `Stream (a)`: `b -> Stream b` | |
| * | |
| * @param {*} value - the initial value | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); | |
| * var m = n.of(1); | |
| */ | |
| // /////////////////////////// PRIVATE ///////////////////////////////// // | |
| /** | |
| * @private | |
| * Create a stream with no dependencies and no value | |
| * @return {Function} a flyd stream | |
| */ | |
| function createStream() { | |
| function s(n) { | |
| if (arguments.length === 0) return s.val | |
| updateStreamValue(s, n) | |
| return s | |
| } | |
| s.hasVal = false; | |
| s.val = undefined; | |
| s.vals = []; | |
| s.listeners = []; | |
| s.queued = false; | |
| s.end = undefined; | |
| s.map = boundMap; | |
| s.ap = ap; | |
| s.of = flyd.stream; | |
| s.toString = streamToString; | |
| return s; | |
| } | |
| /** | |
| * @private | |
| * Create a dependent stream | |
| * @param {Array<stream>} dependencies - an array of the streams | |
| * @param {Function} fn - the function used to calculate the new stream value | |
| * from the dependencies | |
| * @return {stream} the created stream | |
| */ | |
| function createDependentStream(deps, fn) { | |
| var s = createStream(); | |
| s.fn = fn; | |
| s.deps = deps; | |
| s.depsMet = false; | |
| s.depsChanged = deps.length > 0 ? [] : undefined; | |
| s.shouldUpdate = false; | |
| addListeners(deps, s); | |
| return s; | |
| } | |
| /** | |
| * @private | |
| * Check if all the dependencies have values | |
| * @param {stream} stream - the stream to check depencencies from | |
| * @return {Boolean} `true` if all dependencies have vales, `false` otherwise | |
| */ | |
| function initialDepsNotMet(stream) { | |
| stream.depsMet = stream.deps.every(function(s) { | |
| return s.hasVal; | |
| }); | |
| return !stream.depsMet; | |
| } | |
| /** | |
| * @private | |
| * Update a dependent stream using its dependencies in an atomic way | |
| * @param {stream} stream - the stream to update | |
| */ | |
| function updateStream(s) { | |
| if ((s.depsMet !== true && initialDepsNotMet(s)) || | |
| (s.end !== undefined && s.end.val === true)) return; | |
| if (inStream !== undefined) { | |
| toUpdate.push(s); | |
| return; | |
| } | |
| inStream = s; | |
| if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged; | |
| var returnVal = s.fn.apply(s.fn, s.fnArgs); | |
| if (returnVal !== undefined) { | |
| s(returnVal); | |
| } | |
| inStream = undefined; | |
| if (s.depsChanged !== undefined) s.depsChanged = []; | |
| s.shouldUpdate = false; | |
| if (flushing === false) flushUpdate(); | |
| } | |
| /** | |
| * @private | |
| * Update the dependencies of a stream | |
| * @param {stream} stream | |
| */ | |
| function updateDeps(s) { | |
| var i, o, list | |
| var listeners = s.listeners; | |
| for (i = 0; i < listeners.length; ++i) { | |
| list = listeners[i]; | |
| if (list.end === s) { | |
| endStream(list); | |
| } else { | |
| if (list.depsChanged !== undefined) list.depsChanged.push(s); | |
| list.shouldUpdate = true; | |
| findDeps(list); | |
| } | |
| } | |
| for (; orderNextIdx >= 0; --orderNextIdx) { | |
| o = order[orderNextIdx]; | |
| if (o.shouldUpdate === true) updateStream(o); | |
| o.queued = false; | |
| } | |
| } | |
| /** | |
| * @private | |
| * Add stream dependencies to the global `order` queue. | |
| * @param {stream} stream | |
| * @see updateDeps | |
| */ | |
| function findDeps(s) { | |
| var i | |
| var listeners = s.listeners; | |
| if (s.queued === false) { | |
| s.queued = true; | |
| for (i = 0; i < listeners.length; ++i) { | |
| findDeps(listeners[i]); | |
| } | |
| order[++orderNextIdx] = s; | |
| } | |
| } | |
| /** | |
| * @private | |
| */ | |
| function flushUpdate() { | |
| flushing = true; | |
| while (toUpdate.length > 0) { | |
| var s = toUpdate.shift(); | |
| if (s.vals.length > 0) s.val = s.vals.shift(); | |
| updateDeps(s); | |
| } | |
| flushing = false; | |
| } | |
| /** | |
| * @private | |
| * Push down a value into a stream | |
| * @param {stream} stream | |
| * @param {*} value | |
| */ | |
| function updateStreamValue(s, n) { | |
| if (n !== undefined && n !== null && isFunction(n.then)) { | |
| n.then(s); | |
| return; | |
| } | |
| s.val = n; | |
| s.hasVal = true; | |
| if (inStream === undefined) { | |
| flushing = true; | |
| updateDeps(s); | |
| if (toUpdate.length > 0) flushUpdate(); else flushing = false; | |
| } else if (inStream === s) { | |
| markListeners(s, s.listeners); | |
| } else { | |
| s.vals.push(n); | |
| toUpdate.push(s); | |
| } | |
| } | |
| /** | |
| * @private | |
| */ | |
| function markListeners(s, lists) { | |
| var i, list; | |
| for (i = 0; i < lists.length; ++i) { | |
| list = lists[i]; | |
| if (list.end !== s) { | |
| if (list.depsChanged !== undefined) { | |
| list.depsChanged.push(s); | |
| } | |
| list.shouldUpdate = true; | |
| } else { | |
| endStream(list); | |
| } | |
| } | |
| } | |
| /** | |
| * @private | |
| * Add dependencies to a stream | |
| * @param {Array<stream>} dependencies | |
| * @param {stream} stream | |
| */ | |
| function addListeners(deps, s) { | |
| for (var i = 0; i < deps.length; ++i) { | |
| deps[i].listeners.push(s); | |
| } | |
| } | |
| /** | |
| * @private | |
| * Removes an stream from a dependency array | |
| * @param {stream} stream | |
| * @param {Array<stream>} dependencies | |
| */ | |
| function removeListener(s, listeners) { | |
| var idx = listeners.indexOf(s); | |
| listeners[idx] = listeners[listeners.length - 1]; | |
| listeners.length--; | |
| } | |
| /** | |
| * @private | |
| * Detach a stream from its dependencies | |
| * @param {stream} stream | |
| */ | |
| function detachDeps(s) { | |
| for (var i = 0; i < s.deps.length; ++i) { | |
| removeListener(s, s.deps[i].listeners); | |
| } | |
| s.deps.length = 0; | |
| } | |
| /** | |
| * @private | |
| * Ends a stream | |
| */ | |
| function endStream(s) { | |
| if (s.deps !== undefined) detachDeps(s); | |
| if (s.end !== undefined) detachDeps(s.end); | |
| } | |
| /** | |
| * @private | |
| * transducer stream transformer | |
| */ | |
| function StreamTransformer() { } | |
| StreamTransformer.prototype['@@transducer/init'] = function() { }; | |
| StreamTransformer.prototype['@@transducer/result'] = function() { }; | |
| StreamTransformer.prototype['@@transducer/step'] = function(s, v) { return v; }; | |
| module.exports = flyd; | |
| },{"ramda/src/curryN":2}],2:[function(require,module,exports){ | |
| var _arity = require('./internal/_arity'); | |
| var _curry1 = require('./internal/_curry1'); | |
| var _curry2 = require('./internal/_curry2'); | |
| var _curryN = require('./internal/_curryN'); | |
| /** | |
| * Returns a curried equivalent of the provided function, with the specified | |
| * arity. The curried function has two unusual capabilities. First, its | |
| * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the | |
| * following are equivalent: | |
| * | |
| * - `g(1)(2)(3)` | |
| * - `g(1)(2, 3)` | |
| * - `g(1, 2)(3)` | |
| * - `g(1, 2, 3)` | |
| * | |
| * Secondly, the special placeholder value `R.__` may be used to specify | |
| * "gaps", allowing partial application of any combination of arguments, | |
| * regardless of their positions. If `g` is as above and `_` is `R.__`, the | |
| * following are equivalent: | |
| * | |
| * - `g(1, 2, 3)` | |
| * - `g(_, 2, 3)(1)` | |
| * - `g(_, _, 3)(1)(2)` | |
| * - `g(_, _, 3)(1, 2)` | |
| * - `g(_, 2)(1)(3)` | |
| * - `g(_, 2)(1, 3)` | |
| * - `g(_, 2)(_, 3)(1)` | |
| * | |
| * @func | |
| * @memberOf R | |
| * @since v0.5.0 | |
| * @category Function | |
| * @sig Number -> (* -> a) -> (* -> a) | |
| * @param {Number} length The arity for the returned function. | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} A new, curried function. | |
| * @see R.curry | |
| * @example | |
| * | |
| * var sumArgs = (...args) => R.sum(args); | |
| * | |
| * var curriedAddFourNumbers = R.curryN(4, sumArgs); | |
| * var f = curriedAddFourNumbers(1, 2); | |
| * var g = f(3); | |
| * g(4); //=> 10 | |
| */ | |
| module.exports = _curry2(function curryN(length, fn) { | |
| if (length === 1) { | |
| return _curry1(fn); | |
| } | |
| return _arity(length, _curryN(length, [], fn)); | |
| }); | |
| },{"./internal/_arity":3,"./internal/_curry1":4,"./internal/_curry2":5,"./internal/_curryN":6}],3:[function(require,module,exports){ | |
| module.exports = function _arity(n, fn) { | |
| /* eslint-disable no-unused-vars */ | |
| switch (n) { | |
| case 0: return function() { return fn.apply(this, arguments); }; | |
| case 1: return function(a0) { return fn.apply(this, arguments); }; | |
| case 2: return function(a0, a1) { return fn.apply(this, arguments); }; | |
| case 3: return function(a0, a1, a2) { return fn.apply(this, arguments); }; | |
| case 4: return function(a0, a1, a2, a3) { return fn.apply(this, arguments); }; | |
| case 5: return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments); }; | |
| case 6: return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments); }; | |
| case 7: return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments); }; | |
| case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments); }; | |
| case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments); }; | |
| case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments); }; | |
| default: throw new Error('First argument to _arity must be a non-negative integer no greater than ten'); | |
| } | |
| }; | |
| },{}],4:[function(require,module,exports){ | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Optimized internal one-arity curry function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curry1(fn) { | |
| return function f1(a) { | |
| if (arguments.length === 0 || _isPlaceholder(a)) { | |
| return f1; | |
| } else { | |
| return fn.apply(this, arguments); | |
| } | |
| }; | |
| }; | |
| },{"./_isPlaceholder":7}],5:[function(require,module,exports){ | |
| var _curry1 = require('./_curry1'); | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Optimized internal two-arity curry function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curry2(fn) { | |
| return function f2(a, b) { | |
| switch (arguments.length) { | |
| case 0: | |
| return f2; | |
| case 1: | |
| return _isPlaceholder(a) ? f2 | |
| : _curry1(function(_b) { return fn(a, _b); }); | |
| default: | |
| return _isPlaceholder(a) && _isPlaceholder(b) ? f2 | |
| : _isPlaceholder(a) ? _curry1(function(_a) { return fn(_a, b); }) | |
| : _isPlaceholder(b) ? _curry1(function(_b) { return fn(a, _b); }) | |
| : fn(a, b); | |
| } | |
| }; | |
| }; | |
| },{"./_curry1":4,"./_isPlaceholder":7}],6:[function(require,module,exports){ | |
| var _arity = require('./_arity'); | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Internal curryN function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Number} length The arity of the curried function. | |
| * @param {Array} received An array of arguments received thus far. | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curryN(length, received, fn) { | |
| return function() { | |
| var combined = []; | |
| var argsIdx = 0; | |
| var left = length; | |
| var combinedIdx = 0; | |
| while (combinedIdx < received.length || argsIdx < arguments.length) { | |
| var result; | |
| if (combinedIdx < received.length && | |
| (!_isPlaceholder(received[combinedIdx]) || | |
| argsIdx >= arguments.length)) { | |
| result = received[combinedIdx]; | |
| } else { | |
| result = arguments[argsIdx]; | |
| argsIdx += 1; | |
| } | |
| combined[combinedIdx] = result; | |
| if (!_isPlaceholder(result)) { | |
| left -= 1; | |
| } | |
| combinedIdx += 1; | |
| } | |
| return left <= 0 ? fn.apply(this, combined) | |
| : _arity(left, _curryN(length, combined, fn)); | |
| }; | |
| }; | |
| },{"./_arity":3,"./_isPlaceholder":7}],7:[function(require,module,exports){ | |
| module.exports = function _isPlaceholder(a) { | |
| return a != null && | |
| typeof a === 'object' && | |
| a['@@functional/placeholder'] === true; | |
| }; | |
| },{}],"flyd/module/takeuntil":[function(require,module,exports){ | |
| var flyd = require('../../lib'); | |
| module.exports = function(src, term) { | |
| return flyd.endsOn(flyd.merge(term, src.end), flyd.combine(function(src, self) { | |
| self(src()); | |
| }, [src])); | |
| }; | |
| },{"../../lib":1}]},{},[]) | |
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImxpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9yYW1kYS9zcmMvY3VycnlOLmpzIiwibm9kZV9tb2R1bGVzL3JhbWRhL3NyYy9pbnRlcm5hbC9fYXJpdHkuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTEuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTIuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeU4uanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19pc1BsYWNlaG9sZGVyLmpzIiwibW9kdWxlL3Rha2V1bnRpbC9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VycnlOID0gcmVxdWlyZSgncmFtZGEvc3JjL2N1cnJ5TicpO1xuXG4vLyBVdGlsaXR5XG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iaikge1xuICByZXR1cm4gISEob2JqICYmIG9iai5jb25zdHJ1Y3RvciAmJiBvYmouY2FsbCAmJiBvYmouYXBwbHkpO1xufVxuZnVuY3Rpb24gdHJ1ZUZuKCkgeyByZXR1cm4gdHJ1ZTsgfVxuXG4vLyBHbG9iYWxzXG52YXIgdG9VcGRhdGUgPSBbXTtcbnZhciBpblN0cmVhbTtcbnZhciBvcmRlciA9IFtdO1xudmFyIG9yZGVyTmV4dElkeCA9IC0xO1xudmFyIGZsdXNoaW5nID0gZmFsc2U7XG5cbi8qKiBAbmFtZXNwYWNlICovXG52YXIgZmx5ZCA9IHt9XG5cbi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBBUEkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIC8vXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW1cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLnN0cmVhbVxuICogQHBhcmFtIHsqfSBpbml0aWFsVmFsdWUgLSAoT3B0aW9uYWwpIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpOyAvLyBTdHJlYW0gd2l0aCBpbml0aWFsIHZhbHVlIGAxYFxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgpOyAvLyBTdHJlYW0gd2l0aCBubyBpbml0aWFsIHZhbHVlXG4gKi9cbmZseWQuc3RyZWFtID0gZnVuY3Rpb24oaW5pdGlhbFZhbHVlKSB7XG4gIHZhciBlbmRTdHJlYW0gPSBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oW10sIHRydWVGbik7XG4gIHZhciBzID0gY3JlYXRlU3RyZWFtKCk7XG4gIHMuZW5kID0gZW5kU3RyZWFtO1xuICBzLmZuQXJncyA9IFtdO1xuICBlbmRTdHJlYW0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMCkgcyhpbml0aWFsVmFsdWUpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgZGVwZW5kZW50IHN0cmVhbVxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoLi4uU3RyZWFtICogLT4gU3RyZWFtIGIgLT4gYikgLT4gW1N0cmVhbSAqXSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLmNvbWJpbmVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY29tYmluZSB0aGUgc3RyZWFtc1xuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXMgLSB0aGUgc3RyZWFtcyB0aGF0IHRoaXMgb25lIGRlcGVuZHMgb25cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIGRlcGVuZGVudCBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4xID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgbjIgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBtYXggPSBmbHlkLmNvbWJpbmUoZnVuY3Rpb24objEsIG4yLCBzZWxmLCBjaGFuZ2VkKSB7XG4gKiAgIHJldHVybiBuMSgpID4gbjIoKSA/IG4xKCkgOiBuMigpO1xuICogfSwgW24xLCBuMl0pO1xuICovXG5mbHlkLmNvbWJpbmUgPSBjdXJyeU4oMiwgY29tYmluZSk7XG5mdW5jdGlvbiBjb21iaW5lKGZuLCBzdHJlYW1zKSB7XG4gIHZhciBpLCBzLCBkZXBzLCBkZXBFbmRTdHJlYW1zO1xuICB2YXIgZW5kU3RyZWFtID0gY3JlYXRlRGVwZW5kZW50U3RyZWFtKFtdLCB0cnVlRm4pO1xuICBkZXBzID0gW107IGRlcEVuZFN0cmVhbXMgPSBbXTtcbiAgZm9yIChpID0gMDsgaSA8IHN0cmVhbXMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoc3RyZWFtc1tpXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBkZXBzLnB1c2goc3RyZWFtc1tpXSk7XG4gICAgICBpZiAoc3RyZWFtc1tpXS5lbmQgIT09IHVuZGVmaW5lZCkgZGVwRW5kU3RyZWFtcy5wdXNoKHN0cmVhbXNbaV0uZW5kKTtcbiAgICB9XG4gIH1cbiAgcyA9IGNyZWF0ZURlcGVuZGVudFN0cmVhbShkZXBzLCBmbik7XG4gIHMuZGVwc0NoYW5nZWQgPSBbXTtcbiAgcy5mbkFyZ3MgPSBzLmRlcHMuY29uY2F0KFtzLCBzLmRlcHNDaGFuZ2VkXSk7XG4gIHMuZW5kID0gZW5kU3RyZWFtO1xuICBlbmRTdHJlYW0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIGFkZExpc3RlbmVycyhkZXBFbmRTdHJlYW1zLCBlbmRTdHJlYW0pO1xuICBlbmRTdHJlYW0uZGVwcyA9IGRlcEVuZFN0cmVhbXM7XG4gIHVwZGF0ZVN0cmVhbShzKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHN1cHBsaWVkIGFyZ3VtZW50IGlzIGEgRmx5ZCBzdHJlYW0gYW5kIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAqIC0+IEJvb2xlYW5gXG4gKlxuICogQG5hbWUgZmx5ZC5pc1N0cmVhbVxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIHRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJuIHtCb29sZWFufSBgdHJ1ZWAgaWYgaXMgYSBGbHlkIHN0cmVhbW4sIGBmYWxzZWAgb3RoZXJ3aXNlXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBzID0gZmx5ZC5zdHJlYW0oMSk7XG4gKiB2YXIgbiA9IDE7XG4gKiBmbHlkLmlzU3RyZWFtKHMpOyAvLz0+IHRydWVcbiAqIGZseWQuaXNTdHJlYW0obik7IC8vPT4gZmFsc2VcbiAqL1xuZmx5ZC5pc1N0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICByZXR1cm4gaXNGdW5jdGlvbihzdHJlYW0pICYmICdoYXNWYWwnIGluIHN0cmVhbTtcbn1cblxuLyoqXG4gKiBJbnZva2VzIHRoZSBib2R5ICh0aGUgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSB2YWx1ZSkgb2YgYSBkZXBlbmRlbnQgc3RyZWFtXG4gKlxuICogQnkgZGVmYXVsdCB0aGUgYm9keSBvZiBhIGRlcGVuZGVudCBzdHJlYW0gaXMgb25seSBjYWxsZWQgd2hlbiBhbGwgdGhlIHN0cmVhbXNcbiAqIHVwb24gd2hpY2ggaXQgZGVwZW5kcyBoYXMgYSB2YWx1ZS4gYGltbWVkaWF0ZWAgY2FuIGNpcmN1bXZlbnQgdGhpcyBiZWhhdmlvdXIuXG4gKiBJdCBpbW1lZGlhdGVseSBpbnZva2VzIHRoZSBib2R5IG9mIGEgZGVwZW5kZW50IHN0cmVhbS5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgU3RyZWFtIGEgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5pbW1lZGlhdGVcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgZGVwZW5kZW50IHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgc2FtZSBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIGhhc0l0ZW1zID0gZmx5ZC5pbW1lZGlhdGUoZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKHMpIHtcbiAqICAgcmV0dXJuIHMoKSAhPT0gdW5kZWZpbmVkICYmIHMoKS5sZW5ndGggPiAwO1xuICogfSwgW3NdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGBmYWxzZWAuIEhhZCBgaW1tZWRpYXRlYCBub3QgYmVlblxuICogICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZWQgYGhhc0l0ZW1zKClgIHdvdWxkJ3ZlIHJldHVybmVkIGB1bmRlZmluZWRgXG4gKiBzKFsxXSk7XG4gKiBjb25zb2xlLmxvZyhoYXNJdGVtcygpKTsgLy8gbG9ncyBgdHJ1ZWAuXG4gKiBzKFtdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGBmYWxzZWAuXG4gKi9cbmZseWQuaW1tZWRpYXRlID0gZnVuY3Rpb24ocykge1xuICBpZiAocy5kZXBzTWV0ID09PSBmYWxzZSkge1xuICAgIHMuZGVwc01ldCA9IHRydWU7XG4gICAgdXBkYXRlU3RyZWFtKHMpO1xuICB9XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIENoYW5nZXMgd2hpY2ggYGVuZHNTdHJlYW1gIHNob3VsZCB0cmlnZ2VyIHRoZSBlbmRpbmcgb2YgYHNgLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYiAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLmVuZHNPblxuICogQHBhcmFtIHtzdHJlYW19IGVuZFN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gdHJpZ2dlciB0aGUgZW5kaW5nXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBiZSBlbmRlZCBieSB0aGUgZW5kU3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gdGhlIHN0cmVhbSBtb2RpZmllZCB0byBiZSBlbmRlZCBieSBlbmRTdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4gPSBmbHlkLnN0cmVhbSgxKTtcbiAqIHZhciBraWxsZXIgPSBmbHlkLnN0cmVhbSgpO1xuICogLy8gYGRvdWJsZWAgZW5kcyB3aGVuIGBuYCBlbmRzIG9yIHdoZW4gYGtpbGxlcmAgZW1pdHMgYW55IHZhbHVlXG4gKiB2YXIgZG91YmxlID0gZmx5ZC5lbmRzT24oZmx5ZC5tZXJnZShuLmVuZCwga2lsbGVyKSwgZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKG4pIHtcbiAqICAgcmV0dXJuIDIgKiBuKCk7XG4gKiB9LCBbbl0pO1xuKi9cbmZseWQuZW5kc09uID0gZnVuY3Rpb24oZW5kUywgcykge1xuICBkZXRhY2hEZXBzKHMuZW5kKTtcbiAgZW5kUy5saXN0ZW5lcnMucHVzaChzLmVuZCk7XG4gIHMuZW5kLmRlcHMucHVzaChlbmRTKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogTWFwIGEgc3RyZWFtXG4gKlxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gY29uc2lzdGluZyBvZiBldmVyeSB2YWx1ZSBmcm9tIGBzYCBwYXNzZWQgdGhyb3VnaFxuICogYGZuYC4gSS5lLiBgbWFwYCBjcmVhdGVzIGEgbmV3IHN0cmVhbSB0aGF0IGxpc3RlbnMgdG8gYHNgIGFuZFxuICogYXBwbGllcyBgZm5gIHRvIGV2ZXJ5IG5ldyB2YWx1ZS5cbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiByZXN1bHQpIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSByZXN1bHRgXG4gKlxuICogQG5hbWUgZmx5ZC5tYXBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgdGhlIGVsZW1lbnRzIG9mIHRoZSBuZXcgc3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBtYXBcbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBuZXcgc3RyZWFtIHdpdGggdGhlIG1hcHBlZCB2YWx1ZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBzcXVhcmVkTnVtYmVycyA9IGZseWQubWFwKGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4qbjsgfSwgbnVtYmVycyk7XG4gKi9cbi8vIExpYnJhcnkgZnVuY3Rpb25zIHVzZSBzZWxmIGNhbGxiYWNrIHRvIGFjY2VwdCAobnVsbCwgdW5kZWZpbmVkKSB1cGRhdGUgdHJpZ2dlcnMuXG5mbHlkLm1hcCA9IGN1cnJ5TigyLCBmdW5jdGlvbihmLCBzKSB7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMsIHNlbGYpIHsgc2VsZihmKHMudmFsKSk7IH0sIFtzXSk7XG59KVxuXG4vKipcbiAqIExpc3RlbiB0byBzdHJlYW0gZXZlbnRzXG4gKlxuICogU2ltaWxhciB0byBgbWFwYCBleGNlcHQgdGhhdCB0aGUgcmV0dXJuZWQgc3RyZWFtIGlzIGVtcHR5LiBVc2UgYG9uYCBmb3IgZG9pbmdcbiAqIHNpZGUgZWZmZWN0cyBpbiByZWFjdGlvbiB0byBzdHJlYW0gY2hhbmdlcy4gVXNlIHRoZSByZXR1cm5lZCBzdHJlYW0gb25seSBpZiB5b3VcbiAqIG5lZWQgdG8gbWFudWFsbHkgZW5kIGl0LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiByZXN1bHQpIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSB1bmRlZmluZWRgXG4gKlxuICogQG5hbWUgZmx5ZC5vblxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2IgLSB0aGUgY2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IGFuIGVtcHR5IHN0cmVhbSAoY2FuIGJlIGVuZGVkKVxuICovXG5mbHlkLm9uID0gY3VycnlOKDIsIGZ1bmN0aW9uKGYsIHMpIHtcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24ocykgeyBmKHMudmFsKTsgfSwgW3NdKTtcbn0pXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gd2l0aCB0aGUgcmVzdWx0cyBvZiBjYWxsaW5nIHRoZSBmdW5jdGlvbiBvbiBldmVyeSBpbmNvbWluZ1xuICogc3RyZWFtIHdpdGggYW5kIGFjY3VtdWxhdG9yIGFuZCB0aGUgaW5jb21pbmcgdmFsdWUuXG4gKlxuICogX19TaWduYXR1cmVfXzogYChhIC0+IGIgLT4gYSkgLT4gYSAtPiBTdHJlYW0gYiAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLnNjYW5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7Kn0gdmFsIC0gdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIGFjY3VtdWxhdG9yXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSBzb3VyY2VcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIHN1bSA9IGZseWQuc2NhbihmdW5jdGlvbihzdW0sIG4pIHsgcmV0dXJuIHN1bStuOyB9LCAwLCBudW1iZXJzKTtcbiAqIG51bWJlcnMoMikoMykoNSk7XG4gKiBzdW0oKTsgLy8gMTBcbiAqL1xuZmx5ZC5zY2FuID0gY3VycnlOKDMsIGZ1bmN0aW9uKGYsIGFjYywgcykge1xuICB2YXIgbnMgPSBjb21iaW5lKGZ1bmN0aW9uKHMsIHNlbGYpIHtcbiAgICBzZWxmKGFjYyA9IGYoYWNjLCBzLnZhbCkpO1xuICB9LCBbc10pO1xuICBpZiAoIW5zLmhhc1ZhbCkgbnMoYWNjKTtcbiAgcmV0dXJuIG5zO1xufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gZG93biB3aGljaCBhbGwgdmFsdWVzIGZyb20gYm90aCBgc3RyZWFtMWAgYW5kIGBzdHJlYW0yYFxuICogd2lsbCBiZSBzZW50LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLm1lcmdlXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlMSAtIG9uZSBzdHJlYW0gdG8gYmUgbWVyZ2VkXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlMiAtIHRoZSBvdGhlciBzdHJlYW0gdG8gYmUgbWVyZ2VkXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgc3RyZWFtIHdpdGggdGhlIHZhbHVlcyBmcm9tIGJvdGggc291cmNlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgYnRuMUNsaWNrcyA9IGZseWQuc3RyZWFtKCk7XG4gKiBidXR0b24xRWxtLmFkZEV2ZW50TGlzdGVuZXIoYnRuMUNsaWNrcyk7XG4gKiB2YXIgYnRuMkNsaWNrcyA9IGZseWQuc3RyZWFtKCk7XG4gKiBidXR0b24yRWxtLmFkZEV2ZW50TGlzdGVuZXIoYnRuMkNsaWNrcyk7XG4gKiB2YXIgYWxsQ2xpY2tzID0gZmx5ZC5tZXJnZShidG4xQ2xpY2tzLCBidG4yQ2xpY2tzKTtcbiAqL1xuZmx5ZC5tZXJnZSA9IGN1cnJ5TigyLCBmdW5jdGlvbihzMSwgczIpIHtcbiAgdmFyIHMgPSBmbHlkLmltbWVkaWF0ZShjb21iaW5lKGZ1bmN0aW9uKHMxLCBzMiwgc2VsZiwgY2hhbmdlZCkge1xuICAgIGlmIChjaGFuZ2VkWzBdKSB7XG4gICAgICBzZWxmKGNoYW5nZWRbMF0oKSk7XG4gICAgfSBlbHNlIGlmIChzMS5oYXNWYWwpIHtcbiAgICAgIHNlbGYoczEudmFsKTtcbiAgICB9IGVsc2UgaWYgKHMyLmhhc1ZhbCkge1xuICAgICAgc2VsZihzMi52YWwpO1xuICAgIH1cbiAgfSwgW3MxLCBzMl0pKTtcbiAgZmx5ZC5lbmRzT24oY29tYmluZShmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgW3MxLmVuZCwgczIuZW5kXSksIHMpO1xuICByZXR1cm4gcztcbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtIHJlc3VsdGluZyBmcm9tIGFwcGx5aW5nIGB0cmFuc2R1Y2VyYCB0byBgc3RyZWFtYC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgVHJhbnNkdWNlciAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLnRyYW5zZHVjZVxuICogQHBhcmFtIHtUcmFuc2R1Y2VyfSB4Zm9ybSAtIHRoZSB0cmFuc2R1Y2VyIHRyYW5zZm9ybWF0aW9uXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlIC0gdGhlIHN0cmVhbSBzb3VyY2VcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHQgPSByZXF1aXJlKCd0cmFuc2R1Y2Vycy5qcycpO1xuICpcbiAqIHZhciByZXN1bHRzID0gW107XG4gKiB2YXIgczEgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIHR4ID0gdC5jb21wb3NlKHQubWFwKGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHggKiAyOyB9KSwgdC5kZWR1cGUoKSk7XG4gKiB2YXIgczIgPSBmbHlkLnRyYW5zZHVjZSh0eCwgczEpO1xuICogZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKHMyKSB7IHJlc3VsdHMucHVzaChzMigpKTsgfSwgW3MyXSk7XG4gKiBzMSgxKSgxKSgyKSgzKSgzKSgzKSg0KTtcbiAqIHJlc3VsdHM7IC8vID0+IFsyLCA0LCA2LCA4XVxuICovXG5mbHlkLnRyYW5zZHVjZSA9IGN1cnJ5TigyLCBmdW5jdGlvbih4Zm9ybSwgc291cmNlKSB7XG4gIHhmb3JtID0geGZvcm0obmV3IFN0cmVhbVRyYW5zZm9ybWVyKCkpO1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzb3VyY2UsIHNlbGYpIHtcbiAgICB2YXIgcmVzID0geGZvcm1bJ0BAdHJhbnNkdWNlci9zdGVwJ10odW5kZWZpbmVkLCBzb3VyY2UudmFsKTtcbiAgICBpZiAocmVzICYmIHJlc1snQEB0cmFuc2R1Y2VyL3JlZHVjZWQnXSA9PT0gdHJ1ZSkge1xuICAgICAgc2VsZi5lbmQodHJ1ZSk7XG4gICAgICByZXR1cm4gcmVzWydAQHRyYW5zZHVjZXIvdmFsdWUnXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gIH0sIFtzb3VyY2VdKTtcbn0pO1xuXG4vKipcbiAqIFJldHVybnMgYGZuYCBjdXJyaWVkIHRvIGBuYC4gVXNlIHRoaXMgZnVuY3Rpb24gdG8gY3VycnkgZnVuY3Rpb25zIGV4cG9zZWQgYnlcbiAqIG1vZHVsZXMgZm9yIEZseWQuXG4gKlxuICogQG5hbWUgZmx5ZC5jdXJyeU5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtJbnRlZ2VyfSBhcml0eSAtIHRoZSBmdW5jdGlvbiBhcml0eVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdG8gY3VycnlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSB0aGUgY3VycmllZCBmdW5jdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBmdW5jdGlvbiBhZGQoeCwgeSkgeyByZXR1cm4geCArIHk7IH07XG4gKiB2YXIgYSA9IGZseWQuY3VycnlOKDIsIGFkZCk7XG4gKiBhKDIpKDQpIC8vID0+IDZcbiAqL1xuZmx5ZC5jdXJyeU4gPSBjdXJyeU5cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSBpZGVudGljYWwgdG8gdGhlIG9yaWdpbmFsIGV4Y2VwdCBldmVyeVxuICogdmFsdWUgd2lsbCBiZSBwYXNzZWQgdGhyb3VnaCBgZmAuXG4gKlxuICogX05vdGU6XyBUaGlzIGZ1bmN0aW9uIGlzIGluY2x1ZGVkIGluIG9yZGVyIHRvIHN1cHBvcnQgdGhlIGZhbnRhc3kgbGFuZFxuICogc3BlY2lmaWNhdGlvbi5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSBhYDogYChhIC0+IGIpIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIHN0cmVhbS5tYXBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uIC0gdGhlIGZ1bmN0aW9uIHRvIGFwcGx5XG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmVhbSB3aXRoIHRoZSB2YWx1ZXMgbWFwcGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBudW1iZXJzID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgc3F1YXJlZE51bWJlcnMgPSBudW1iZXJzLm1hcChmdW5jdGlvbihuKSB7IHJldHVybiBuKm47IH0pO1xuICovXG5mdW5jdGlvbiBib3VuZE1hcChmKSB7IHJldHVybiBmbHlkLm1hcChmLCB0aGlzKTsgfVxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIHdoaWNoIGlzIHRoZSByZXN1bHQgb2YgYXBwbHlpbmcgdGhlXG4gKiBmdW5jdGlvbnMgZnJvbSBgdGhpc2Agc3RyZWFtIHRvIHRoZSB2YWx1ZXMgaW4gYHN0cmVhbWAgcGFyYW1ldGVyLlxuICpcbiAqIGB0aGlzYCBzdHJlYW0gbXVzdCBiZSBhIHN0cmVhbSBvZiBmdW5jdGlvbnMuXG4gKlxuICogX05vdGU6XyBUaGlzIGZ1bmN0aW9uIGlzIGluY2x1ZGVkIGluIG9yZGVyIHRvIHN1cHBvcnQgdGhlIGZhbnRhc3kgbGFuZFxuICogc3BlY2lmaWNhdGlvbi5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSAoYSAtPiBiKWA6IGBhIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIHN0cmVhbS5hcFxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSB2YWx1ZXMgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmFtIHdpdGggdGhlIGZ1bmN0aW9ucyBhcHBsaWVkIHRvIHZhbHVlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgYWRkID0gZmx5ZC5jdXJyeU4oMiwgZnVuY3Rpb24oeCwgeSkgeyByZXR1cm4geCArIHk7IH0pO1xuICogdmFyIG51bWJlcnMxID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBudW1iZXJzMiA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgYWRkVG9OdW1iZXJzMSA9IGZseWQubWFwKGFkZCwgbnVtYmVyczEpO1xuICogdmFyIGFkZGVkID0gYWRkVG9OdW1iZXJzMS5hcChudW1iZXJzMik7XG4gKi9cbmZ1bmN0aW9uIGFwKHMyKSB7XG4gIHZhciBzMSA9IHRoaXM7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMxLCBzMiwgc2VsZikgeyBzZWxmKHMxLnZhbChzMi52YWwpKTsgfSwgW3MxLCBzMl0pO1xufVxuXG4vKipcbiAqIEdldCBhIGh1bWFuIHJlYWRhYmxlIHZpZXcgb2YgYSBzdHJlYW1cbiAqIEBuYW1lIHN0cmVhbS50b1N0cmluZ1xuICogQHJldHVybiB7U3RyaW5nfSB0aGUgc3RyZWFtIHN0cmluZyByZXByZXNlbnRhdGlvblxuICovXG5mdW5jdGlvbiBzdHJlYW1Ub1N0cmluZygpIHtcbiAgcmV0dXJuICdzdHJlYW0oJyArIHRoaXMudmFsICsgJyknO1xufVxuXG4vKipcbiAqIEBuYW1lIHN0cmVhbS5lbmRcbiAqIEBtZW1iZXJvZiBzdHJlYW1cbiAqIEEgc3RyZWFtIHRoYXQgZW1pdHMgYHRydWVgIHdoZW4gdGhlIHN0cmVhbSBlbmRzLiBJZiBgdHJ1ZWAgaXMgcHVzaGVkIGRvd24gdGhlXG4gKiBzdHJlYW0gdGhlIHBhcmVudCBzdHJlYW0gZW5kcy5cbiAqL1xuXG4vKipcbiAqIEBuYW1lIHN0cmVhbS5vZlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2Ygc3RyZWFtXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSB3aXRoIGB2YWx1ZWAgYXMgaXRzIGluaXRpYWwgdmFsdWUuIEl0IGlzIGlkZW50aWNhbCB0b1xuICogY2FsbGluZyBgZmx5ZC5zdHJlYW1gIHdpdGggb25lIGFyZ3VtZW50LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IENhbGxlZCBib3VuZCB0byBgU3RyZWFtIChhKWA6IGBiIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgLSB0aGUgaW5pdGlhbCB2YWx1ZVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgbmV3IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpO1xuICogdmFyIG0gPSBuLm9mKDEpO1xuICovXG5cbi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBQUklWQVRFIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyAvL1xuLyoqXG4gKiBAcHJpdmF0ZVxuICogQ3JlYXRlIGEgc3RyZWFtIHdpdGggbm8gZGVwZW5kZW5jaWVzIGFuZCBubyB2YWx1ZVxuICogQHJldHVybiB7RnVuY3Rpb259IGEgZmx5ZCBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlU3RyZWFtKCkge1xuICBmdW5jdGlvbiBzKG4pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHMudmFsXG4gICAgdXBkYXRlU3RyZWFtVmFsdWUocywgbilcbiAgICByZXR1cm4gc1xuICB9XG4gIHMuaGFzVmFsID0gZmFsc2U7XG4gIHMudmFsID0gdW5kZWZpbmVkO1xuICBzLnZhbHMgPSBbXTtcbiAgcy5saXN0ZW5lcnMgPSBbXTtcbiAgcy5xdWV1ZWQgPSBmYWxzZTtcbiAgcy5lbmQgPSB1bmRlZmluZWQ7XG4gIHMubWFwID0gYm91bmRNYXA7XG4gIHMuYXAgPSBhcDtcbiAgcy5vZiA9IGZseWQuc3RyZWFtO1xuICBzLnRvU3RyaW5nID0gc3RyZWFtVG9TdHJpbmc7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDcmVhdGUgYSBkZXBlbmRlbnQgc3RyZWFtXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llcyAtIGFuIGFycmF5IG9mIHRoZSBzdHJlYW1zXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgbmV3IHN0cmVhbSB2YWx1ZVxuICogZnJvbSB0aGUgZGVwZW5kZW5jaWVzXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBjcmVhdGVkIHN0cmVhbVxuICovXG5mdW5jdGlvbiBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oZGVwcywgZm4pIHtcbiAgdmFyIHMgPSBjcmVhdGVTdHJlYW0oKTtcbiAgcy5mbiA9IGZuO1xuICBzLmRlcHMgPSBkZXBzO1xuICBzLmRlcHNNZXQgPSBmYWxzZTtcbiAgcy5kZXBzQ2hhbmdlZCA9IGRlcHMubGVuZ3RoID4gMCA/IFtdIDogdW5kZWZpbmVkO1xuICBzLnNob3VsZFVwZGF0ZSA9IGZhbHNlO1xuICBhZGRMaXN0ZW5lcnMoZGVwcywgcyk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDaGVjayBpZiBhbGwgdGhlIGRlcGVuZGVuY2llcyBoYXZlIHZhbHVlc1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gY2hlY2sgZGVwZW5jZW5jaWVzIGZyb21cbiAqIEByZXR1cm4ge0Jvb2xlYW59IGB0cnVlYCBpZiBhbGwgZGVwZW5kZW5jaWVzIGhhdmUgdmFsZXMsIGBmYWxzZWAgb3RoZXJ3aXNlXG4gKi9cbmZ1bmN0aW9uIGluaXRpYWxEZXBzTm90TWV0KHN0cmVhbSkge1xuICBzdHJlYW0uZGVwc01ldCA9IHN0cmVhbS5kZXBzLmV2ZXJ5KGZ1bmN0aW9uKHMpIHtcbiAgICByZXR1cm4gcy5oYXNWYWw7XG4gIH0pO1xuICByZXR1cm4gIXN0cmVhbS5kZXBzTWV0O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBVcGRhdGUgYSBkZXBlbmRlbnQgc3RyZWFtIHVzaW5nIGl0cyBkZXBlbmRlbmNpZXMgaW4gYW4gYXRvbWljIHdheVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gdXBkYXRlXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZVN0cmVhbShzKSB7XG4gIGlmICgocy5kZXBzTWV0ICE9PSB0cnVlICYmIGluaXRpYWxEZXBzTm90TWV0KHMpKSB8fFxuICAgICAgKHMuZW5kICE9PSB1bmRlZmluZWQgJiYgcy5lbmQudmFsID09PSB0cnVlKSkgcmV0dXJuO1xuICBpZiAoaW5TdHJlYW0gIT09IHVuZGVmaW5lZCkge1xuICAgIHRvVXBkYXRlLnB1c2gocyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGluU3RyZWFtID0gcztcbiAgaWYgKHMuZGVwc0NoYW5nZWQpIHMuZm5BcmdzW3MuZm5BcmdzLmxlbmd0aCAtIDFdID0gcy5kZXBzQ2hhbmdlZDtcbiAgdmFyIHJldHVyblZhbCA9IHMuZm4uYXBwbHkocy5mbiwgcy5mbkFyZ3MpO1xuICBpZiAocmV0dXJuVmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICBzKHJldHVyblZhbCk7XG4gIH1cbiAgaW5TdHJlYW0gPSB1bmRlZmluZWQ7XG4gIGlmIChzLmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIHMuZGVwc0NoYW5nZWQgPSBbXTtcbiAgcy5zaG91bGRVcGRhdGUgPSBmYWxzZTtcbiAgaWYgKGZsdXNoaW5nID09PSBmYWxzZSkgZmx1c2hVcGRhdGUoKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogVXBkYXRlIHRoZSBkZXBlbmRlbmNpZXMgb2YgYSBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGVwcyhzKSB7XG4gIHZhciBpLCBvLCBsaXN0XG4gIHZhciBsaXN0ZW5lcnMgPSBzLmxpc3RlbmVycztcbiAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7ICsraSkge1xuICAgIGxpc3QgPSBsaXN0ZW5lcnNbaV07XG4gICAgaWYgKGxpc3QuZW5kID09PSBzKSB7XG4gICAgICBlbmRTdHJlYW0obGlzdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChsaXN0LmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIGxpc3QuZGVwc0NoYW5nZWQucHVzaChzKTtcbiAgICAgIGxpc3Quc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICAgIGZpbmREZXBzKGxpc3QpO1xuICAgIH1cbiAgfVxuICBmb3IgKDsgb3JkZXJOZXh0SWR4ID49IDA7IC0tb3JkZXJOZXh0SWR4KSB7XG4gICAgbyA9IG9yZGVyW29yZGVyTmV4dElkeF07XG4gICAgaWYgKG8uc2hvdWxkVXBkYXRlID09PSB0cnVlKSB1cGRhdGVTdHJlYW0obyk7XG4gICAgby5xdWV1ZWQgPSBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBBZGQgc3RyZWFtIGRlcGVuZGVuY2llcyB0byB0aGUgZ2xvYmFsIGBvcmRlcmAgcXVldWUuXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKiBAc2VlIHVwZGF0ZURlcHNcbiAqL1xuZnVuY3Rpb24gZmluZERlcHMocykge1xuICB2YXIgaVxuICB2YXIgbGlzdGVuZXJzID0gcy5saXN0ZW5lcnM7XG4gIGlmIChzLnF1ZXVlZCA9PT0gZmFsc2UpIHtcbiAgICBzLnF1ZXVlZCA9IHRydWU7XG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7ICsraSkge1xuICAgICAgZmluZERlcHMobGlzdGVuZXJzW2ldKTtcbiAgICB9XG4gICAgb3JkZXJbKytvcmRlck5leHRJZHhdID0gcztcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGZsdXNoVXBkYXRlKCkge1xuICBmbHVzaGluZyA9IHRydWU7XG4gIHdoaWxlICh0b1VwZGF0ZS5sZW5ndGggPiAwKSB7XG4gICAgdmFyIHMgPSB0b1VwZGF0ZS5zaGlmdCgpO1xuICAgIGlmIChzLnZhbHMubGVuZ3RoID4gMCkgcy52YWwgPSBzLnZhbHMuc2hpZnQoKTtcbiAgICB1cGRhdGVEZXBzKHMpO1xuICB9XG4gIGZsdXNoaW5nID0gZmFsc2U7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFB1c2ggZG93biBhIHZhbHVlIGludG8gYSBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU3RyZWFtVmFsdWUocywgbikge1xuICBpZiAobiAhPT0gdW5kZWZpbmVkICYmIG4gIT09IG51bGwgJiYgaXNGdW5jdGlvbihuLnRoZW4pKSB7XG4gICAgbi50aGVuKHMpO1xuICAgIHJldHVybjtcbiAgfVxuICBzLnZhbCA9IG47XG4gIHMuaGFzVmFsID0gdHJ1ZTtcbiAgaWYgKGluU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICBmbHVzaGluZyA9IHRydWU7XG4gICAgdXBkYXRlRGVwcyhzKTtcbiAgICBpZiAodG9VcGRhdGUubGVuZ3RoID4gMCkgZmx1c2hVcGRhdGUoKTsgZWxzZSBmbHVzaGluZyA9IGZhbHNlO1xuICB9IGVsc2UgaWYgKGluU3RyZWFtID09PSBzKSB7XG4gICAgbWFya0xpc3RlbmVycyhzLCBzLmxpc3RlbmVycyk7XG4gIH0gZWxzZSB7XG4gICAgcy52YWxzLnB1c2gobik7XG4gICAgdG9VcGRhdGUucHVzaChzKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIG1hcmtMaXN0ZW5lcnMocywgbGlzdHMpIHtcbiAgdmFyIGksIGxpc3Q7XG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0cy5sZW5ndGg7ICsraSkge1xuICAgIGxpc3QgPSBsaXN0c1tpXTtcbiAgICBpZiAobGlzdC5lbmQgIT09IHMpIHtcbiAgICAgIGlmIChsaXN0LmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGlzdC5kZXBzQ2hhbmdlZC5wdXNoKHMpO1xuICAgICAgfVxuICAgICAgbGlzdC5zaG91bGRVcGRhdGUgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmRTdHJlYW0obGlzdCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEFkZCBkZXBlbmRlbmNpZXMgdG8gYSBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGFkZExpc3RlbmVycyhkZXBzLCBzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGVwcy5sZW5ndGg7ICsraSkge1xuICAgIGRlcHNbaV0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogUmVtb3ZlcyBhbiBzdHJlYW0gZnJvbSBhIGRlcGVuZGVuY3kgYXJyYXlcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKHMsIGxpc3RlbmVycykge1xuICB2YXIgaWR4ID0gbGlzdGVuZXJzLmluZGV4T2Yocyk7XG4gIGxpc3RlbmVyc1tpZHhdID0gbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXTtcbiAgbGlzdGVuZXJzLmxlbmd0aC0tO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBEZXRhY2ggYSBzdHJlYW0gZnJvbSBpdHMgZGVwZW5kZW5jaWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGRldGFjaERlcHMocykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHMuZGVwcy5sZW5ndGg7ICsraSkge1xuICAgIHJlbW92ZUxpc3RlbmVyKHMsIHMuZGVwc1tpXS5saXN0ZW5lcnMpO1xuICB9XG4gIHMuZGVwcy5sZW5ndGggPSAwO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBFbmRzIGEgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGVuZFN0cmVhbShzKSB7XG4gIGlmIChzLmRlcHMgIT09IHVuZGVmaW5lZCkgZGV0YWNoRGVwcyhzKTtcbiAgaWYgKHMuZW5kICE9PSB1bmRlZmluZWQpIGRldGFjaERlcHMocy5lbmQpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiB0cmFuc2R1Y2VyIHN0cmVhbSB0cmFuc2Zvcm1lclxuICovXG5mdW5jdGlvbiBTdHJlYW1UcmFuc2Zvcm1lcigpIHsgfVxuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvaW5pdCddID0gZnVuY3Rpb24oKSB7IH07XG5TdHJlYW1UcmFuc2Zvcm1lci5wcm90b3R5cGVbJ0BAdHJhbnNkdWNlci9yZXN1bHQnXSA9IGZ1bmN0aW9uKCkgeyB9O1xuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvc3RlcCddID0gZnVuY3Rpb24ocywgdikgeyByZXR1cm4gdjsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbHlkO1xuIiwidmFyIF9hcml0eSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2FyaXR5Jyk7XG52YXIgX2N1cnJ5MSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2N1cnJ5MScpO1xudmFyIF9jdXJyeTIgPSByZXF1aXJlKCcuL2ludGVybmFsL19jdXJyeTInKTtcbnZhciBfY3VycnlOID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9fY3VycnlOJyk7XG5cblxuLyoqXG4gKiBSZXR1cm5zIGEgY3VycmllZCBlcXVpdmFsZW50IG9mIHRoZSBwcm92aWRlZCBmdW5jdGlvbiwgd2l0aCB0aGUgc3BlY2lmaWVkXG4gKiBhcml0eS4gVGhlIGN1cnJpZWQgZnVuY3Rpb24gaGFzIHR3byB1bnVzdWFsIGNhcGFiaWxpdGllcy4gRmlyc3QsIGl0c1xuICogYXJndW1lbnRzIG5lZWRuJ3QgYmUgcHJvdmlkZWQgb25lIGF0IGEgdGltZS4gSWYgYGdgIGlzIGBSLmN1cnJ5TigzLCBmKWAsIHRoZVxuICogZm9sbG93aW5nIGFyZSBlcXVpdmFsZW50OlxuICpcbiAqICAgLSBgZygxKSgyKSgzKWBcbiAqICAgLSBgZygxKSgyLCAzKWBcbiAqICAgLSBgZygxLCAyKSgzKWBcbiAqICAgLSBgZygxLCAyLCAzKWBcbiAqXG4gKiBTZWNvbmRseSwgdGhlIHNwZWNpYWwgcGxhY2Vob2xkZXIgdmFsdWUgYFIuX19gIG1heSBiZSB1c2VkIHRvIHNwZWNpZnlcbiAqIFwiZ2Fwc1wiLCBhbGxvd2luZyBwYXJ0aWFsIGFwcGxpY2F0aW9uIG9mIGFueSBjb21iaW5hdGlvbiBvZiBhcmd1bWVudHMsXG4gKiByZWdhcmRsZXNzIG9mIHRoZWlyIHBvc2l0aW9ucy4gSWYgYGdgIGlzIGFzIGFib3ZlIGFuZCBgX2AgaXMgYFIuX19gLCB0aGVcbiAqIGZvbGxvd2luZyBhcmUgZXF1aXZhbGVudDpcbiAqXG4gKiAgIC0gYGcoMSwgMiwgMylgXG4gKiAgIC0gYGcoXywgMiwgMykoMSlgXG4gKiAgIC0gYGcoXywgXywgMykoMSkoMilgXG4gKiAgIC0gYGcoXywgXywgMykoMSwgMilgXG4gKiAgIC0gYGcoXywgMikoMSkoMylgXG4gKiAgIC0gYGcoXywgMikoMSwgMylgXG4gKiAgIC0gYGcoXywgMikoXywgMykoMSlgXG4gKlxuICogQGZ1bmNcbiAqIEBtZW1iZXJPZiBSXG4gKiBAc2luY2UgdjAuNS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBzaWcgTnVtYmVyIC0+ICgqIC0+IGEpIC0+ICgqIC0+IGEpXG4gKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBhcml0eSBmb3IgdGhlIHJldHVybmVkIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbmV3LCBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHNlZSBSLmN1cnJ5XG4gKiBAZXhhbXBsZVxuICpcbiAqICAgICAgdmFyIHN1bUFyZ3MgPSAoLi4uYXJncykgPT4gUi5zdW0oYXJncyk7XG4gKlxuICogICAgICB2YXIgY3VycmllZEFkZEZvdXJOdW1iZXJzID0gUi5jdXJyeU4oNCwgc3VtQXJncyk7XG4gKiAgICAgIHZhciBmID0gY3VycmllZEFkZEZvdXJOdW1iZXJzKDEsIDIpO1xuICogICAgICB2YXIgZyA9IGYoMyk7XG4gKiAgICAgIGcoNCk7IC8vPT4gMTBcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBfY3VycnkyKGZ1bmN0aW9uIGN1cnJ5TihsZW5ndGgsIGZuKSB7XG4gIGlmIChsZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gX2N1cnJ5MShmbik7XG4gIH1cbiAgcmV0dXJuIF9hcml0eShsZW5ndGgsIF9jdXJyeU4obGVuZ3RoLCBbXSwgZm4pKTtcbn0pO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBfYXJpdHkobiwgZm4pIHtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbiAgc3dpdGNoIChuKSB7XG4gICAgY2FzZSAwOiByZXR1cm4gZnVuY3Rpb24oKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKGEwKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNDogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDY6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNzogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCwgYTUsIGE2KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgODogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCwgYTUsIGE2LCBhNykgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDk6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcsIGE4KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMTA6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcsIGE4LCBhOSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IHRvIF9hcml0eSBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIgbm8gZ3JlYXRlciB0aGFuIHRlbicpO1xuICB9XG59O1xuIiwidmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogT3B0aW1pemVkIGludGVybmFsIG9uZS1hcml0eSBjdXJyeSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5MShmbikge1xuICByZXR1cm4gZnVuY3Rpb24gZjEoYSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwIHx8IF9pc1BsYWNlaG9sZGVyKGEpKSB7XG4gICAgICByZXR1cm4gZjE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfTtcbn07XG4iLCJ2YXIgX2N1cnJ5MSA9IHJlcXVpcmUoJy4vX2N1cnJ5MScpO1xudmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogT3B0aW1pemVkIGludGVybmFsIHR3by1hcml0eSBjdXJyeSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5Mihmbikge1xuICByZXR1cm4gZnVuY3Rpb24gZjIoYSwgYikge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gZjI7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiBfaXNQbGFjZWhvbGRlcihhKSA/IGYyXG4gICAgICAgICAgICAgOiBfY3VycnkxKGZ1bmN0aW9uKF9iKSB7IHJldHVybiBmbihhLCBfYik7IH0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIF9pc1BsYWNlaG9sZGVyKGEpICYmIF9pc1BsYWNlaG9sZGVyKGIpID8gZjJcbiAgICAgICAgICAgICA6IF9pc1BsYWNlaG9sZGVyKGEpID8gX2N1cnJ5MShmdW5jdGlvbihfYSkgeyByZXR1cm4gZm4oX2EsIGIpOyB9KVxuICAgICAgICAgICAgIDogX2lzUGxhY2Vob2xkZXIoYikgPyBfY3VycnkxKGZ1bmN0aW9uKF9iKSB7IHJldHVybiBmbihhLCBfYik7IH0pXG4gICAgICAgICAgICAgOiBmbihhLCBiKTtcbiAgICB9XG4gIH07XG59O1xuIiwidmFyIF9hcml0eSA9IHJlcXVpcmUoJy4vX2FyaXR5Jyk7XG52YXIgX2lzUGxhY2Vob2xkZXIgPSByZXF1aXJlKCcuL19pc1BsYWNlaG9sZGVyJyk7XG5cblxuLyoqXG4gKiBJbnRlcm5hbCBjdXJyeU4gZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgYXJpdHkgb2YgdGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5fSByZWNlaXZlZCBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVjZWl2ZWQgdGh1cyBmYXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5TihsZW5ndGgsIHJlY2VpdmVkLCBmbikge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNvbWJpbmVkID0gW107XG4gICAgdmFyIGFyZ3NJZHggPSAwO1xuICAgIHZhciBsZWZ0ID0gbGVuZ3RoO1xuICAgIHZhciBjb21iaW5lZElkeCA9IDA7XG4gICAgd2hpbGUgKGNvbWJpbmVkSWR4IDwgcmVjZWl2ZWQubGVuZ3RoIHx8IGFyZ3NJZHggPCBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgaWYgKGNvbWJpbmVkSWR4IDwgcmVjZWl2ZWQubGVuZ3RoICYmXG4gICAgICAgICAgKCFfaXNQbGFjZWhvbGRlcihyZWNlaXZlZFtjb21iaW5lZElkeF0pIHx8XG4gICAgICAgICAgIGFyZ3NJZHggPj0gYXJndW1lbnRzLmxlbmd0aCkpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVjZWl2ZWRbY29tYmluZWRJZHhdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gYXJndW1lbnRzW2FyZ3NJZHhdO1xuICAgICAgICBhcmdzSWR4ICs9IDE7XG4gICAgICB9XG4gICAgICBjb21iaW5lZFtjb21iaW5lZElkeF0gPSByZXN1bHQ7XG4gICAgICBpZiAoIV9pc1BsYWNlaG9sZGVyKHJlc3VsdCkpIHtcbiAgICAgICAgbGVmdCAtPSAxO1xuICAgICAgfVxuICAgICAgY29tYmluZWRJZHggKz0gMTtcbiAgICB9XG4gICAgcmV0dXJuIGxlZnQgPD0gMCA/IGZuLmFwcGx5KHRoaXMsIGNvbWJpbmVkKVxuICAgICAgICAgICAgICAgICAgICAgOiBfYXJpdHkobGVmdCwgX2N1cnJ5TihsZW5ndGgsIGNvbWJpbmVkLCBmbikpO1xuICB9O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2lzUGxhY2Vob2xkZXIoYSkge1xuICByZXR1cm4gYSAhPSBudWxsICYmXG4gICAgICAgICB0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgIGFbJ0BAZnVuY3Rpb25hbC9wbGFjZWhvbGRlciddID09PSB0cnVlO1xufTtcbiIsInZhciBmbHlkID0gcmVxdWlyZSgnLi4vLi4vbGliJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc3JjLCB0ZXJtKSB7XG4gIHJldHVybiBmbHlkLmVuZHNPbihmbHlkLm1lcmdlKHRlcm0sIHNyYy5lbmQpLCBmbHlkLmNvbWJpbmUoZnVuY3Rpb24oc3JjLCBzZWxmKSB7XG4gICAgc2VsZihzcmMoKSk7XG4gIH0sIFtzcmNdKSk7XG59O1xuIl19 | |
| require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
| 'use strict'; | |
| var curryN = require('ramda/src/curryN'); | |
| // Utility | |
| function isFunction(obj) { | |
| return !!(obj && obj.constructor && obj.call && obj.apply); | |
| } | |
| function trueFn() { return true; } | |
| // Globals | |
| var toUpdate = []; | |
| var inStream; | |
| var order = []; | |
| var orderNextIdx = -1; | |
| var flushing = false; | |
| /** @namespace */ | |
| var flyd = {} | |
| // /////////////////////////// API ///////////////////////////////// // | |
| /** | |
| * Creates a new stream | |
| * | |
| * __Signature__: `a -> Stream a` | |
| * | |
| * @name flyd.stream | |
| * @param {*} initialValue - (Optional) the initial value of the stream | |
| * @return {stream} the stream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); // Stream with initial value `1` | |
| * var s = flyd.stream(); // Stream with no initial value | |
| */ | |
| flyd.stream = function(initialValue) { | |
| var endStream = createDependentStream([], trueFn); | |
| var s = createStream(); | |
| s.end = endStream; | |
| s.fnArgs = []; | |
| endStream.listeners.push(s); | |
| if (arguments.length > 0) s(initialValue); | |
| return s; | |
| } | |
| /** | |
| * Create a new dependent stream | |
| * | |
| * __Signature__: `(...Stream * -> Stream b -> b) -> [Stream *] -> Stream b` | |
| * | |
| * @name flyd.combine | |
| * @param {Function} fn - the function used to combine the streams | |
| * @param {Array<stream>} dependencies - the streams that this one depends on | |
| * @return {stream} the dependent stream | |
| * | |
| * @example | |
| * var n1 = flyd.stream(0); | |
| * var n2 = flyd.stream(0); | |
| * var max = flyd.combine(function(n1, n2, self, changed) { | |
| * return n1() > n2() ? n1() : n2(); | |
| * }, [n1, n2]); | |
| */ | |
| flyd.combine = curryN(2, combine); | |
| function combine(fn, streams) { | |
| var i, s, deps, depEndStreams; | |
| var endStream = createDependentStream([], trueFn); | |
| deps = []; depEndStreams = []; | |
| for (i = 0; i < streams.length; ++i) { | |
| if (streams[i] !== undefined) { | |
| deps.push(streams[i]); | |
| if (streams[i].end !== undefined) depEndStreams.push(streams[i].end); | |
| } | |
| } | |
| s = createDependentStream(deps, fn); | |
| s.depsChanged = []; | |
| s.fnArgs = s.deps.concat([s, s.depsChanged]); | |
| s.end = endStream; | |
| endStream.listeners.push(s); | |
| addListeners(depEndStreams, endStream); | |
| endStream.deps = depEndStreams; | |
| updateStream(s); | |
| return s; | |
| } | |
| /** | |
| * Returns `true` if the supplied argument is a Flyd stream and `false` otherwise. | |
| * | |
| * __Signature__: `* -> Boolean` | |
| * | |
| * @name flyd.isStream | |
| * @param {*} value - the value to test | |
| * @return {Boolean} `true` if is a Flyd streamn, `false` otherwise | |
| * | |
| * @example | |
| * var s = flyd.stream(1); | |
| * var n = 1; | |
| * flyd.isStream(s); //=> true | |
| * flyd.isStream(n); //=> false | |
| */ | |
| flyd.isStream = function(stream) { | |
| return isFunction(stream) && 'hasVal' in stream; | |
| } | |
| /** | |
| * Invokes the body (the function to calculate the value) of a dependent stream | |
| * | |
| * By default the body of a dependent stream is only called when all the streams | |
| * upon which it depends has a value. `immediate` can circumvent this behaviour. | |
| * It immediately invokes the body of a dependent stream. | |
| * | |
| * __Signature__: `Stream a -> Stream a` | |
| * | |
| * @name flyd.immediate | |
| * @param {stream} stream - the dependent stream | |
| * @return {stream} the same stream | |
| * | |
| * @example | |
| * var s = flyd.stream(); | |
| * var hasItems = flyd.immediate(flyd.combine(function(s) { | |
| * return s() !== undefined && s().length > 0; | |
| * }, [s]); | |
| * console.log(hasItems()); // logs `false`. Had `immediate` not been | |
| * // used `hasItems()` would've returned `undefined` | |
| * s([1]); | |
| * console.log(hasItems()); // logs `true`. | |
| * s([]); | |
| * console.log(hasItems()); // logs `false`. | |
| */ | |
| flyd.immediate = function(s) { | |
| if (s.depsMet === false) { | |
| s.depsMet = true; | |
| updateStream(s); | |
| } | |
| return s; | |
| } | |
| /** | |
| * Changes which `endsStream` should trigger the ending of `s`. | |
| * | |
| * __Signature__: `Stream a -> Stream b -> Stream b` | |
| * | |
| * @name flyd.endsOn | |
| * @param {stream} endStream - the stream to trigger the ending | |
| * @param {stream} stream - the stream to be ended by the endStream | |
| * @param {stream} the stream modified to be ended by endStream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); | |
| * var killer = flyd.stream(); | |
| * // `double` ends when `n` ends or when `killer` emits any value | |
| * var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.combine(function(n) { | |
| * return 2 * n(); | |
| * }, [n]); | |
| */ | |
| flyd.endsOn = function(endS, s) { | |
| detachDeps(s.end); | |
| endS.listeners.push(s.end); | |
| s.end.deps.push(endS); | |
| return s; | |
| } | |
| /** | |
| * Map a stream | |
| * | |
| * Returns a new stream consisting of every value from `s` passed through | |
| * `fn`. I.e. `map` creates a new stream that listens to `s` and | |
| * applies `fn` to every new value. | |
| * __Signature__: `(a -> result) -> Stream a -> Stream result` | |
| * | |
| * @name flyd.map | |
| * @param {Function} fn - the function that produces the elements of the new stream | |
| * @param {stream} stream - the stream to map | |
| * @return {stream} a new stream with the mapped values | |
| * | |
| * @example | |
| * var numbers = flyd.stream(0); | |
| * var squaredNumbers = flyd.map(function(n) { return n*n; }, numbers); | |
| */ | |
| // Library functions use self callback to accept (null, undefined) update triggers. | |
| flyd.map = curryN(2, function(f, s) { | |
| return combine(function(s, self) { self(f(s.val)); }, [s]); | |
| }) | |
| /** | |
| * Listen to stream events | |
| * | |
| * Similar to `map` except that the returned stream is empty. Use `on` for doing | |
| * side effects in reaction to stream changes. Use the returned stream only if you | |
| * need to manually end it. | |
| * | |
| * __Signature__: `(a -> result) -> Stream a -> Stream undefined` | |
| * | |
| * @name flyd.on | |
| * @param {Function} cb - the callback | |
| * @param {stream} stream - the stream | |
| * @return {stream} an empty stream (can be ended) | |
| */ | |
| flyd.on = curryN(2, function(f, s) { | |
| return combine(function(s) { f(s.val); }, [s]); | |
| }) | |
| /** | |
| * Creates a new stream with the results of calling the function on every incoming | |
| * stream with and accumulator and the incoming value. | |
| * | |
| * __Signature__: `(a -> b -> a) -> a -> Stream b -> Stream a` | |
| * | |
| * @name flyd.scan | |
| * @param {Function} fn - the function to call | |
| * @param {*} val - the initial value of the accumulator | |
| * @param {stream} stream - the stream source | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var numbers = flyd.stream(); | |
| * var sum = flyd.scan(function(sum, n) { return sum+n; }, 0, numbers); | |
| * numbers(2)(3)(5); | |
| * sum(); // 10 | |
| */ | |
| flyd.scan = curryN(3, function(f, acc, s) { | |
| var ns = combine(function(s, self) { | |
| self(acc = f(acc, s.val)); | |
| }, [s]); | |
| if (!ns.hasVal) ns(acc); | |
| return ns; | |
| }); | |
| /** | |
| * Creates a new stream down which all values from both `stream1` and `stream2` | |
| * will be sent. | |
| * | |
| * __Signature__: `Stream a -> Stream a -> Stream a` | |
| * | |
| * @name flyd.merge | |
| * @param {stream} source1 - one stream to be merged | |
| * @param {stream} source2 - the other stream to be merged | |
| * @return {stream} a stream with the values from both sources | |
| * | |
| * @example | |
| * var btn1Clicks = flyd.stream(); | |
| * button1Elm.addEventListener(btn1Clicks); | |
| * var btn2Clicks = flyd.stream(); | |
| * button2Elm.addEventListener(btn2Clicks); | |
| * var allClicks = flyd.merge(btn1Clicks, btn2Clicks); | |
| */ | |
| flyd.merge = curryN(2, function(s1, s2) { | |
| var s = flyd.immediate(combine(function(s1, s2, self, changed) { | |
| if (changed[0]) { | |
| self(changed[0]()); | |
| } else if (s1.hasVal) { | |
| self(s1.val); | |
| } else if (s2.hasVal) { | |
| self(s2.val); | |
| } | |
| }, [s1, s2])); | |
| flyd.endsOn(combine(function() { | |
| return true; | |
| }, [s1.end, s2.end]), s); | |
| return s; | |
| }); | |
| /** | |
| * Creates a new stream resulting from applying `transducer` to `stream`. | |
| * | |
| * __Signature__: `Transducer -> Stream a -> Stream b` | |
| * | |
| * @name flyd.transduce | |
| * @param {Transducer} xform - the transducer transformation | |
| * @param {stream} source - the stream source | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var t = require('transducers.js'); | |
| * | |
| * var results = []; | |
| * var s1 = flyd.stream(); | |
| * var tx = t.compose(t.map(function(x) { return x * 2; }), t.dedupe()); | |
| * var s2 = flyd.transduce(tx, s1); | |
| * flyd.combine(function(s2) { results.push(s2()); }, [s2]); | |
| * s1(1)(1)(2)(3)(3)(3)(4); | |
| * results; // => [2, 4, 6, 8] | |
| */ | |
| flyd.transduce = curryN(2, function(xform, source) { | |
| xform = xform(new StreamTransformer()); | |
| return combine(function(source, self) { | |
| var res = xform['@@transducer/step'](undefined, source.val); | |
| if (res && res['@@transducer/reduced'] === true) { | |
| self.end(true); | |
| return res['@@transducer/value']; | |
| } else { | |
| return res; | |
| } | |
| }, [source]); | |
| }); | |
| /** | |
| * Returns `fn` curried to `n`. Use this function to curry functions exposed by | |
| * modules for Flyd. | |
| * | |
| * @name flyd.curryN | |
| * @function | |
| * @param {Integer} arity - the function arity | |
| * @param {Function} fn - the function to curry | |
| * @return {Function} the curried function | |
| * | |
| * @example | |
| * function add(x, y) { return x + y; }; | |
| * var a = flyd.curryN(2, add); | |
| * a(2)(4) // => 6 | |
| */ | |
| flyd.curryN = curryN | |
| /** | |
| * Returns a new stream identical to the original except every | |
| * value will be passed through `f`. | |
| * | |
| * _Note:_ This function is included in order to support the fantasy land | |
| * specification. | |
| * | |
| * __Signature__: Called bound to `Stream a`: `(a -> b) -> Stream b` | |
| * | |
| * @name stream.map | |
| * @param {Function} function - the function to apply | |
| * @return {stream} a new stream with the values mapped | |
| * | |
| * @example | |
| * var numbers = flyd.stream(0); | |
| * var squaredNumbers = numbers.map(function(n) { return n*n; }); | |
| */ | |
| function boundMap(f) { return flyd.map(f, this); } | |
| /** | |
| * Returns a new stream which is the result of applying the | |
| * functions from `this` stream to the values in `stream` parameter. | |
| * | |
| * `this` stream must be a stream of functions. | |
| * | |
| * _Note:_ This function is included in order to support the fantasy land | |
| * specification. | |
| * | |
| * __Signature__: Called bound to `Stream (a -> b)`: `a -> Stream b` | |
| * | |
| * @name stream.ap | |
| * @param {stream} stream - the values stream | |
| * @return {stream} a new stram with the functions applied to values | |
| * | |
| * @example | |
| * var add = flyd.curryN(2, function(x, y) { return x + y; }); | |
| * var numbers1 = flyd.stream(); | |
| * var numbers2 = flyd.stream(); | |
| * var addToNumbers1 = flyd.map(add, numbers1); | |
| * var added = addToNumbers1.ap(numbers2); | |
| */ | |
| function ap(s2) { | |
| var s1 = this; | |
| return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]); | |
| } | |
| /** | |
| * Get a human readable view of a stream | |
| * @name stream.toString | |
| * @return {String} the stream string representation | |
| */ | |
| function streamToString() { | |
| return 'stream(' + this.val + ')'; | |
| } | |
| /** | |
| * @name stream.end | |
| * @memberof stream | |
| * A stream that emits `true` when the stream ends. If `true` is pushed down the | |
| * stream the parent stream ends. | |
| */ | |
| /** | |
| * @name stream.of | |
| * @function | |
| * @memberof stream | |
| * Returns a new stream with `value` as its initial value. It is identical to | |
| * calling `flyd.stream` with one argument. | |
| * | |
| * __Signature__: Called bound to `Stream (a)`: `b -> Stream b` | |
| * | |
| * @param {*} value - the initial value | |
| * @return {stream} the new stream | |
| * | |
| * @example | |
| * var n = flyd.stream(1); | |
| * var m = n.of(1); | |
| */ | |
| // /////////////////////////// PRIVATE ///////////////////////////////// // | |
| /** | |
| * @private | |
| * Create a stream with no dependencies and no value | |
| * @return {Function} a flyd stream | |
| */ | |
| function createStream() { | |
| function s(n) { | |
| if (arguments.length === 0) return s.val | |
| updateStreamValue(s, n) | |
| return s | |
| } | |
| s.hasVal = false; | |
| s.val = undefined; | |
| s.vals = []; | |
| s.listeners = []; | |
| s.queued = false; | |
| s.end = undefined; | |
| s.map = boundMap; | |
| s.ap = ap; | |
| s.of = flyd.stream; | |
| s.toString = streamToString; | |
| return s; | |
| } | |
| /** | |
| * @private | |
| * Create a dependent stream | |
| * @param {Array<stream>} dependencies - an array of the streams | |
| * @param {Function} fn - the function used to calculate the new stream value | |
| * from the dependencies | |
| * @return {stream} the created stream | |
| */ | |
| function createDependentStream(deps, fn) { | |
| var s = createStream(); | |
| s.fn = fn; | |
| s.deps = deps; | |
| s.depsMet = false; | |
| s.depsChanged = deps.length > 0 ? [] : undefined; | |
| s.shouldUpdate = false; | |
| addListeners(deps, s); | |
| return s; | |
| } | |
| /** | |
| * @private | |
| * Check if all the dependencies have values | |
| * @param {stream} stream - the stream to check depencencies from | |
| * @return {Boolean} `true` if all dependencies have vales, `false` otherwise | |
| */ | |
| function initialDepsNotMet(stream) { | |
| stream.depsMet = stream.deps.every(function(s) { | |
| return s.hasVal; | |
| }); | |
| return !stream.depsMet; | |
| } | |
| /** | |
| * @private | |
| * Update a dependent stream using its dependencies in an atomic way | |
| * @param {stream} stream - the stream to update | |
| */ | |
| function updateStream(s) { | |
| if ((s.depsMet !== true && initialDepsNotMet(s)) || | |
| (s.end !== undefined && s.end.val === true)) return; | |
| if (inStream !== undefined) { | |
| toUpdate.push(s); | |
| return; | |
| } | |
| inStream = s; | |
| if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged; | |
| var returnVal = s.fn.apply(s.fn, s.fnArgs); | |
| if (returnVal !== undefined) { | |
| s(returnVal); | |
| } | |
| inStream = undefined; | |
| if (s.depsChanged !== undefined) s.depsChanged = []; | |
| s.shouldUpdate = false; | |
| if (flushing === false) flushUpdate(); | |
| } | |
| /** | |
| * @private | |
| * Update the dependencies of a stream | |
| * @param {stream} stream | |
| */ | |
| function updateDeps(s) { | |
| var i, o, list | |
| var listeners = s.listeners; | |
| for (i = 0; i < listeners.length; ++i) { | |
| list = listeners[i]; | |
| if (list.end === s) { | |
| endStream(list); | |
| } else { | |
| if (list.depsChanged !== undefined) list.depsChanged.push(s); | |
| list.shouldUpdate = true; | |
| findDeps(list); | |
| } | |
| } | |
| for (; orderNextIdx >= 0; --orderNextIdx) { | |
| o = order[orderNextIdx]; | |
| if (o.shouldUpdate === true) updateStream(o); | |
| o.queued = false; | |
| } | |
| } | |
| /** | |
| * @private | |
| * Add stream dependencies to the global `order` queue. | |
| * @param {stream} stream | |
| * @see updateDeps | |
| */ | |
| function findDeps(s) { | |
| var i | |
| var listeners = s.listeners; | |
| if (s.queued === false) { | |
| s.queued = true; | |
| for (i = 0; i < listeners.length; ++i) { | |
| findDeps(listeners[i]); | |
| } | |
| order[++orderNextIdx] = s; | |
| } | |
| } | |
| /** | |
| * @private | |
| */ | |
| function flushUpdate() { | |
| flushing = true; | |
| while (toUpdate.length > 0) { | |
| var s = toUpdate.shift(); | |
| if (s.vals.length > 0) s.val = s.vals.shift(); | |
| updateDeps(s); | |
| } | |
| flushing = false; | |
| } | |
| /** | |
| * @private | |
| * Push down a value into a stream | |
| * @param {stream} stream | |
| * @param {*} value | |
| */ | |
| function updateStreamValue(s, n) { | |
| if (n !== undefined && n !== null && isFunction(n.then)) { | |
| n.then(s); | |
| return; | |
| } | |
| s.val = n; | |
| s.hasVal = true; | |
| if (inStream === undefined) { | |
| flushing = true; | |
| updateDeps(s); | |
| if (toUpdate.length > 0) flushUpdate(); else flushing = false; | |
| } else if (inStream === s) { | |
| markListeners(s, s.listeners); | |
| } else { | |
| s.vals.push(n); | |
| toUpdate.push(s); | |
| } | |
| } | |
| /** | |
| * @private | |
| */ | |
| function markListeners(s, lists) { | |
| var i, list; | |
| for (i = 0; i < lists.length; ++i) { | |
| list = lists[i]; | |
| if (list.end !== s) { | |
| if (list.depsChanged !== undefined) { | |
| list.depsChanged.push(s); | |
| } | |
| list.shouldUpdate = true; | |
| } else { | |
| endStream(list); | |
| } | |
| } | |
| } | |
| /** | |
| * @private | |
| * Add dependencies to a stream | |
| * @param {Array<stream>} dependencies | |
| * @param {stream} stream | |
| */ | |
| function addListeners(deps, s) { | |
| for (var i = 0; i < deps.length; ++i) { | |
| deps[i].listeners.push(s); | |
| } | |
| } | |
| /** | |
| * @private | |
| * Removes an stream from a dependency array | |
| * @param {stream} stream | |
| * @param {Array<stream>} dependencies | |
| */ | |
| function removeListener(s, listeners) { | |
| var idx = listeners.indexOf(s); | |
| listeners[idx] = listeners[listeners.length - 1]; | |
| listeners.length--; | |
| } | |
| /** | |
| * @private | |
| * Detach a stream from its dependencies | |
| * @param {stream} stream | |
| */ | |
| function detachDeps(s) { | |
| for (var i = 0; i < s.deps.length; ++i) { | |
| removeListener(s, s.deps[i].listeners); | |
| } | |
| s.deps.length = 0; | |
| } | |
| /** | |
| * @private | |
| * Ends a stream | |
| */ | |
| function endStream(s) { | |
| if (s.deps !== undefined) detachDeps(s); | |
| if (s.end !== undefined) detachDeps(s.end); | |
| } | |
| /** | |
| * @private | |
| * transducer stream transformer | |
| */ | |
| function StreamTransformer() { } | |
| StreamTransformer.prototype['@@transducer/init'] = function() { }; | |
| StreamTransformer.prototype['@@transducer/result'] = function() { }; | |
| StreamTransformer.prototype['@@transducer/step'] = function(s, v) { return v; }; | |
| module.exports = flyd; | |
| },{"ramda/src/curryN":2}],2:[function(require,module,exports){ | |
| var _arity = require('./internal/_arity'); | |
| var _curry1 = require('./internal/_curry1'); | |
| var _curry2 = require('./internal/_curry2'); | |
| var _curryN = require('./internal/_curryN'); | |
| /** | |
| * Returns a curried equivalent of the provided function, with the specified | |
| * arity. The curried function has two unusual capabilities. First, its | |
| * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the | |
| * following are equivalent: | |
| * | |
| * - `g(1)(2)(3)` | |
| * - `g(1)(2, 3)` | |
| * - `g(1, 2)(3)` | |
| * - `g(1, 2, 3)` | |
| * | |
| * Secondly, the special placeholder value `R.__` may be used to specify | |
| * "gaps", allowing partial application of any combination of arguments, | |
| * regardless of their positions. If `g` is as above and `_` is `R.__`, the | |
| * following are equivalent: | |
| * | |
| * - `g(1, 2, 3)` | |
| * - `g(_, 2, 3)(1)` | |
| * - `g(_, _, 3)(1)(2)` | |
| * - `g(_, _, 3)(1, 2)` | |
| * - `g(_, 2)(1)(3)` | |
| * - `g(_, 2)(1, 3)` | |
| * - `g(_, 2)(_, 3)(1)` | |
| * | |
| * @func | |
| * @memberOf R | |
| * @since v0.5.0 | |
| * @category Function | |
| * @sig Number -> (* -> a) -> (* -> a) | |
| * @param {Number} length The arity for the returned function. | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} A new, curried function. | |
| * @see R.curry | |
| * @example | |
| * | |
| * var sumArgs = (...args) => R.sum(args); | |
| * | |
| * var curriedAddFourNumbers = R.curryN(4, sumArgs); | |
| * var f = curriedAddFourNumbers(1, 2); | |
| * var g = f(3); | |
| * g(4); //=> 10 | |
| */ | |
| module.exports = _curry2(function curryN(length, fn) { | |
| if (length === 1) { | |
| return _curry1(fn); | |
| } | |
| return _arity(length, _curryN(length, [], fn)); | |
| }); | |
| },{"./internal/_arity":3,"./internal/_curry1":4,"./internal/_curry2":5,"./internal/_curryN":6}],3:[function(require,module,exports){ | |
| module.exports = function _arity(n, fn) { | |
| /* eslint-disable no-unused-vars */ | |
| switch (n) { | |
| case 0: return function() { return fn.apply(this, arguments); }; | |
| case 1: return function(a0) { return fn.apply(this, arguments); }; | |
| case 2: return function(a0, a1) { return fn.apply(this, arguments); }; | |
| case 3: return function(a0, a1, a2) { return fn.apply(this, arguments); }; | |
| case 4: return function(a0, a1, a2, a3) { return fn.apply(this, arguments); }; | |
| case 5: return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments); }; | |
| case 6: return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments); }; | |
| case 7: return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments); }; | |
| case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments); }; | |
| case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments); }; | |
| case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments); }; | |
| default: throw new Error('First argument to _arity must be a non-negative integer no greater than ten'); | |
| } | |
| }; | |
| },{}],4:[function(require,module,exports){ | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Optimized internal one-arity curry function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curry1(fn) { | |
| return function f1(a) { | |
| if (arguments.length === 0 || _isPlaceholder(a)) { | |
| return f1; | |
| } else { | |
| return fn.apply(this, arguments); | |
| } | |
| }; | |
| }; | |
| },{"./_isPlaceholder":7}],5:[function(require,module,exports){ | |
| var _curry1 = require('./_curry1'); | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Optimized internal two-arity curry function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curry2(fn) { | |
| return function f2(a, b) { | |
| switch (arguments.length) { | |
| case 0: | |
| return f2; | |
| case 1: | |
| return _isPlaceholder(a) ? f2 | |
| : _curry1(function(_b) { return fn(a, _b); }); | |
| default: | |
| return _isPlaceholder(a) && _isPlaceholder(b) ? f2 | |
| : _isPlaceholder(a) ? _curry1(function(_a) { return fn(_a, b); }) | |
| : _isPlaceholder(b) ? _curry1(function(_b) { return fn(a, _b); }) | |
| : fn(a, b); | |
| } | |
| }; | |
| }; | |
| },{"./_curry1":4,"./_isPlaceholder":7}],6:[function(require,module,exports){ | |
| var _arity = require('./_arity'); | |
| var _isPlaceholder = require('./_isPlaceholder'); | |
| /** | |
| * Internal curryN function. | |
| * | |
| * @private | |
| * @category Function | |
| * @param {Number} length The arity of the curried function. | |
| * @param {Array} received An array of arguments received thus far. | |
| * @param {Function} fn The function to curry. | |
| * @return {Function} The curried function. | |
| */ | |
| module.exports = function _curryN(length, received, fn) { | |
| return function() { | |
| var combined = []; | |
| var argsIdx = 0; | |
| var left = length; | |
| var combinedIdx = 0; | |
| while (combinedIdx < received.length || argsIdx < arguments.length) { | |
| var result; | |
| if (combinedIdx < received.length && | |
| (!_isPlaceholder(received[combinedIdx]) || | |
| argsIdx >= arguments.length)) { | |
| result = received[combinedIdx]; | |
| } else { | |
| result = arguments[argsIdx]; | |
| argsIdx += 1; | |
| } | |
| combined[combinedIdx] = result; | |
| if (!_isPlaceholder(result)) { | |
| left -= 1; | |
| } | |
| combinedIdx += 1; | |
| } | |
| return left <= 0 ? fn.apply(this, combined) | |
| : _arity(left, _curryN(length, combined, fn)); | |
| }; | |
| }; | |
| },{"./_arity":3,"./_isPlaceholder":7}],7:[function(require,module,exports){ | |
| module.exports = function _isPlaceholder(a) { | |
| return a != null && | |
| typeof a === 'object' && | |
| a['@@functional/placeholder'] === true; | |
| }; | |
| },{}],"flyd/module/filter":[function(require,module,exports){ | |
| var flyd = require('../../lib'); | |
| module.exports = flyd.curryN(2, function(fn, s) { | |
| return flyd.combine(function(s, self) { | |
| if (fn(s())) self(s.val); | |
| }, [s]); | |
| }); | |
| },{"../../lib":1}]},{},[]) | |
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImxpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9yYW1kYS9zcmMvY3VycnlOLmpzIiwibm9kZV9tb2R1bGVzL3JhbWRhL3NyYy9pbnRlcm5hbC9fYXJpdHkuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTEuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeTIuanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19jdXJyeU4uanMiLCJub2RlX21vZHVsZXMvcmFtZGEvc3JjL2ludGVybmFsL19pc1BsYWNlaG9sZGVyLmpzIiwibW9kdWxlL2ZpbHRlci9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VycnlOID0gcmVxdWlyZSgncmFtZGEvc3JjL2N1cnJ5TicpO1xuXG4vLyBVdGlsaXR5XG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iaikge1xuICByZXR1cm4gISEob2JqICYmIG9iai5jb25zdHJ1Y3RvciAmJiBvYmouY2FsbCAmJiBvYmouYXBwbHkpO1xufVxuZnVuY3Rpb24gdHJ1ZUZuKCkgeyByZXR1cm4gdHJ1ZTsgfVxuXG4vLyBHbG9iYWxzXG52YXIgdG9VcGRhdGUgPSBbXTtcbnZhciBpblN0cmVhbTtcbnZhciBvcmRlciA9IFtdO1xudmFyIG9yZGVyTmV4dElkeCA9IC0xO1xudmFyIGZsdXNoaW5nID0gZmFsc2U7XG5cbi8qKiBAbmFtZXNwYWNlICovXG52YXIgZmx5ZCA9IHt9XG5cbi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBBUEkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIC8vXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW1cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLnN0cmVhbVxuICogQHBhcmFtIHsqfSBpbml0aWFsVmFsdWUgLSAoT3B0aW9uYWwpIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBzdHJlYW1cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpOyAvLyBTdHJlYW0gd2l0aCBpbml0aWFsIHZhbHVlIGAxYFxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgpOyAvLyBTdHJlYW0gd2l0aCBubyBpbml0aWFsIHZhbHVlXG4gKi9cbmZseWQuc3RyZWFtID0gZnVuY3Rpb24oaW5pdGlhbFZhbHVlKSB7XG4gIHZhciBlbmRTdHJlYW0gPSBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oW10sIHRydWVGbik7XG4gIHZhciBzID0gY3JlYXRlU3RyZWFtKCk7XG4gIHMuZW5kID0gZW5kU3RyZWFtO1xuICBzLmZuQXJncyA9IFtdO1xuICBlbmRTdHJlYW0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMCkgcyhpbml0aWFsVmFsdWUpO1xuICByZXR1cm4gcztcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgZGVwZW5kZW50IHN0cmVhbVxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoLi4uU3RyZWFtICogLT4gU3RyZWFtIGIgLT4gYikgLT4gW1N0cmVhbSAqXSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLmNvbWJpbmVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY29tYmluZSB0aGUgc3RyZWFtc1xuICogQHBhcmFtIHtBcnJheTxzdHJlYW0+fSBkZXBlbmRlbmNpZXMgLSB0aGUgc3RyZWFtcyB0aGF0IHRoaXMgb25lIGRlcGVuZHMgb25cbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIGRlcGVuZGVudCBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4xID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgbjIgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBtYXggPSBmbHlkLmNvbWJpbmUoZnVuY3Rpb24objEsIG4yLCBzZWxmLCBjaGFuZ2VkKSB7XG4gKiAgIHJldHVybiBuMSgpID4gbjIoKSA/IG4xKCkgOiBuMigpO1xuICogfSwgW24xLCBuMl0pO1xuICovXG5mbHlkLmNvbWJpbmUgPSBjdXJyeU4oMiwgY29tYmluZSk7XG5mdW5jdGlvbiBjb21iaW5lKGZuLCBzdHJlYW1zKSB7XG4gIHZhciBpLCBzLCBkZXBzLCBkZXBFbmRTdHJlYW1zO1xuICB2YXIgZW5kU3RyZWFtID0gY3JlYXRlRGVwZW5kZW50U3RyZWFtKFtdLCB0cnVlRm4pO1xuICBkZXBzID0gW107IGRlcEVuZFN0cmVhbXMgPSBbXTtcbiAgZm9yIChpID0gMDsgaSA8IHN0cmVhbXMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoc3RyZWFtc1tpXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBkZXBzLnB1c2goc3RyZWFtc1tpXSk7XG4gICAgICBpZiAoc3RyZWFtc1tpXS5lbmQgIT09IHVuZGVmaW5lZCkgZGVwRW5kU3RyZWFtcy5wdXNoKHN0cmVhbXNbaV0uZW5kKTtcbiAgICB9XG4gIH1cbiAgcyA9IGNyZWF0ZURlcGVuZGVudFN0cmVhbShkZXBzLCBmbik7XG4gIHMuZGVwc0NoYW5nZWQgPSBbXTtcbiAgcy5mbkFyZ3MgPSBzLmRlcHMuY29uY2F0KFtzLCBzLmRlcHNDaGFuZ2VkXSk7XG4gIHMuZW5kID0gZW5kU3RyZWFtO1xuICBlbmRTdHJlYW0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIGFkZExpc3RlbmVycyhkZXBFbmRTdHJlYW1zLCBlbmRTdHJlYW0pO1xuICBlbmRTdHJlYW0uZGVwcyA9IGRlcEVuZFN0cmVhbXM7XG4gIHVwZGF0ZVN0cmVhbShzKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHN1cHBsaWVkIGFyZ3VtZW50IGlzIGEgRmx5ZCBzdHJlYW0gYW5kIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAqIC0+IEJvb2xlYW5gXG4gKlxuICogQG5hbWUgZmx5ZC5pc1N0cmVhbVxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIHRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJuIHtCb29sZWFufSBgdHJ1ZWAgaWYgaXMgYSBGbHlkIHN0cmVhbW4sIGBmYWxzZWAgb3RoZXJ3aXNlXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBzID0gZmx5ZC5zdHJlYW0oMSk7XG4gKiB2YXIgbiA9IDE7XG4gKiBmbHlkLmlzU3RyZWFtKHMpOyAvLz0+IHRydWVcbiAqIGZseWQuaXNTdHJlYW0obik7IC8vPT4gZmFsc2VcbiAqL1xuZmx5ZC5pc1N0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICByZXR1cm4gaXNGdW5jdGlvbihzdHJlYW0pICYmICdoYXNWYWwnIGluIHN0cmVhbTtcbn1cblxuLyoqXG4gKiBJbnZva2VzIHRoZSBib2R5ICh0aGUgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSB2YWx1ZSkgb2YgYSBkZXBlbmRlbnQgc3RyZWFtXG4gKlxuICogQnkgZGVmYXVsdCB0aGUgYm9keSBvZiBhIGRlcGVuZGVudCBzdHJlYW0gaXMgb25seSBjYWxsZWQgd2hlbiBhbGwgdGhlIHN0cmVhbXNcbiAqIHVwb24gd2hpY2ggaXQgZGVwZW5kcyBoYXMgYSB2YWx1ZS4gYGltbWVkaWF0ZWAgY2FuIGNpcmN1bXZlbnQgdGhpcyBiZWhhdmlvdXIuXG4gKiBJdCBpbW1lZGlhdGVseSBpbnZva2VzIHRoZSBib2R5IG9mIGEgZGVwZW5kZW50IHN0cmVhbS5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgU3RyZWFtIGEgLT4gU3RyZWFtIGFgXG4gKlxuICogQG5hbWUgZmx5ZC5pbW1lZGlhdGVcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgZGVwZW5kZW50IHN0cmVhbVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgc2FtZSBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHMgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIGhhc0l0ZW1zID0gZmx5ZC5pbW1lZGlhdGUoZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKHMpIHtcbiAqICAgcmV0dXJuIHMoKSAhPT0gdW5kZWZpbmVkICYmIHMoKS5sZW5ndGggPiAwO1xuICogfSwgW3NdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGBmYWxzZWAuIEhhZCBgaW1tZWRpYXRlYCBub3QgYmVlblxuICogICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZWQgYGhhc0l0ZW1zKClgIHdvdWxkJ3ZlIHJldHVybmVkIGB1bmRlZmluZWRgXG4gKiBzKFsxXSk7XG4gKiBjb25zb2xlLmxvZyhoYXNJdGVtcygpKTsgLy8gbG9ncyBgdHJ1ZWAuXG4gKiBzKFtdKTtcbiAqIGNvbnNvbGUubG9nKGhhc0l0ZW1zKCkpOyAvLyBsb2dzIGBmYWxzZWAuXG4gKi9cbmZseWQuaW1tZWRpYXRlID0gZnVuY3Rpb24ocykge1xuICBpZiAocy5kZXBzTWV0ID09PSBmYWxzZSkge1xuICAgIHMuZGVwc01ldCA9IHRydWU7XG4gICAgdXBkYXRlU3RyZWFtKHMpO1xuICB9XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIENoYW5nZXMgd2hpY2ggYGVuZHNTdHJlYW1gIHNob3VsZCB0cmlnZ2VyIHRoZSBlbmRpbmcgb2YgYHNgLlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYiAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLmVuZHNPblxuICogQHBhcmFtIHtzdHJlYW19IGVuZFN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gdHJpZ2dlciB0aGUgZW5kaW5nXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBiZSBlbmRlZCBieSB0aGUgZW5kU3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gdGhlIHN0cmVhbSBtb2RpZmllZCB0byBiZSBlbmRlZCBieSBlbmRTdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG4gPSBmbHlkLnN0cmVhbSgxKTtcbiAqIHZhciBraWxsZXIgPSBmbHlkLnN0cmVhbSgpO1xuICogLy8gYGRvdWJsZWAgZW5kcyB3aGVuIGBuYCBlbmRzIG9yIHdoZW4gYGtpbGxlcmAgZW1pdHMgYW55IHZhbHVlXG4gKiB2YXIgZG91YmxlID0gZmx5ZC5lbmRzT24oZmx5ZC5tZXJnZShuLmVuZCwga2lsbGVyKSwgZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKG4pIHtcbiAqICAgcmV0dXJuIDIgKiBuKCk7XG4gKiB9LCBbbl0pO1xuKi9cbmZseWQuZW5kc09uID0gZnVuY3Rpb24oZW5kUywgcykge1xuICBkZXRhY2hEZXBzKHMuZW5kKTtcbiAgZW5kUy5saXN0ZW5lcnMucHVzaChzLmVuZCk7XG4gIHMuZW5kLmRlcHMucHVzaChlbmRTKTtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogTWFwIGEgc3RyZWFtXG4gKlxuICogUmV0dXJucyBhIG5ldyBzdHJlYW0gY29uc2lzdGluZyBvZiBldmVyeSB2YWx1ZSBmcm9tIGBzYCBwYXNzZWQgdGhyb3VnaFxuICogYGZuYC4gSS5lLiBgbWFwYCBjcmVhdGVzIGEgbmV3IHN0cmVhbSB0aGF0IGxpc3RlbnMgdG8gYHNgIGFuZFxuICogYXBwbGllcyBgZm5gIHRvIGV2ZXJ5IG5ldyB2YWx1ZS5cbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiByZXN1bHQpIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSByZXN1bHRgXG4gKlxuICogQG5hbWUgZmx5ZC5tYXBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgdGhlIGVsZW1lbnRzIG9mIHRoZSBuZXcgc3RyZWFtXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSB0byBtYXBcbiAqIEByZXR1cm4ge3N0cmVhbX0gYSBuZXcgc3RyZWFtIHdpdGggdGhlIG1hcHBlZCB2YWx1ZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgwKTtcbiAqIHZhciBzcXVhcmVkTnVtYmVycyA9IGZseWQubWFwKGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4qbjsgfSwgbnVtYmVycyk7XG4gKi9cbi8vIExpYnJhcnkgZnVuY3Rpb25zIHVzZSBzZWxmIGNhbGxiYWNrIHRvIGFjY2VwdCAobnVsbCwgdW5kZWZpbmVkKSB1cGRhdGUgdHJpZ2dlcnMuXG5mbHlkLm1hcCA9IGN1cnJ5TigyLCBmdW5jdGlvbihmLCBzKSB7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMsIHNlbGYpIHsgc2VsZihmKHMudmFsKSk7IH0sIFtzXSk7XG59KVxuXG4vKipcbiAqIExpc3RlbiB0byBzdHJlYW0gZXZlbnRzXG4gKlxuICogU2ltaWxhciB0byBgbWFwYCBleGNlcHQgdGhhdCB0aGUgcmV0dXJuZWQgc3RyZWFtIGlzIGVtcHR5LiBVc2UgYG9uYCBmb3IgZG9pbmdcbiAqIHNpZGUgZWZmZWN0cyBpbiByZWFjdGlvbiB0byBzdHJlYW0gY2hhbmdlcy4gVXNlIHRoZSByZXR1cm5lZCBzdHJlYW0gb25seSBpZiB5b3VcbiAqIG5lZWQgdG8gbWFudWFsbHkgZW5kIGl0LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGAoYSAtPiByZXN1bHQpIC0+IFN0cmVhbSBhIC0+IFN0cmVhbSB1bmRlZmluZWRgXG4gKlxuICogQG5hbWUgZmx5ZC5vblxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2IgLSB0aGUgY2FsbGJhY2tcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW0gLSB0aGUgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IGFuIGVtcHR5IHN0cmVhbSAoY2FuIGJlIGVuZGVkKVxuICovXG5mbHlkLm9uID0gY3VycnlOKDIsIGZ1bmN0aW9uKGYsIHMpIHtcbiAgcmV0dXJuIGNvbWJpbmUoZnVuY3Rpb24ocykgeyBmKHMudmFsKTsgfSwgW3NdKTtcbn0pXG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gd2l0aCB0aGUgcmVzdWx0cyBvZiBjYWxsaW5nIHRoZSBmdW5jdGlvbiBvbiBldmVyeSBpbmNvbWluZ1xuICogc3RyZWFtIHdpdGggYW5kIGFjY3VtdWxhdG9yIGFuZCB0aGUgaW5jb21pbmcgdmFsdWUuXG4gKlxuICogX19TaWduYXR1cmVfXzogYChhIC0+IGIgLT4gYSkgLT4gYSAtPiBTdHJlYW0gYiAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLnNjYW5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7Kn0gdmFsIC0gdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIGFjY3VtdWxhdG9yXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtIC0gdGhlIHN0cmVhbSBzb3VyY2VcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIG51bWJlcnMgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIHN1bSA9IGZseWQuc2NhbihmdW5jdGlvbihzdW0sIG4pIHsgcmV0dXJuIHN1bStuOyB9LCAwLCBudW1iZXJzKTtcbiAqIG51bWJlcnMoMikoMykoNSk7XG4gKiBzdW0oKTsgLy8gMTBcbiAqL1xuZmx5ZC5zY2FuID0gY3VycnlOKDMsIGZ1bmN0aW9uKGYsIGFjYywgcykge1xuICB2YXIgbnMgPSBjb21iaW5lKGZ1bmN0aW9uKHMsIHNlbGYpIHtcbiAgICBzZWxmKGFjYyA9IGYoYWNjLCBzLnZhbCkpO1xuICB9LCBbc10pO1xuICBpZiAoIW5zLmhhc1ZhbCkgbnMoYWNjKTtcbiAgcmV0dXJuIG5zO1xufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzdHJlYW0gZG93biB3aGljaCBhbGwgdmFsdWVzIGZyb20gYm90aCBgc3RyZWFtMWAgYW5kIGBzdHJlYW0yYFxuICogd2lsbCBiZSBzZW50LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IGBTdHJlYW0gYSAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gYWBcbiAqXG4gKiBAbmFtZSBmbHlkLm1lcmdlXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlMSAtIG9uZSBzdHJlYW0gdG8gYmUgbWVyZ2VkXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlMiAtIHRoZSBvdGhlciBzdHJlYW0gdG8gYmUgbWVyZ2VkXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgc3RyZWFtIHdpdGggdGhlIHZhbHVlcyBmcm9tIGJvdGggc291cmNlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgYnRuMUNsaWNrcyA9IGZseWQuc3RyZWFtKCk7XG4gKiBidXR0b24xRWxtLmFkZEV2ZW50TGlzdGVuZXIoYnRuMUNsaWNrcyk7XG4gKiB2YXIgYnRuMkNsaWNrcyA9IGZseWQuc3RyZWFtKCk7XG4gKiBidXR0b24yRWxtLmFkZEV2ZW50TGlzdGVuZXIoYnRuMkNsaWNrcyk7XG4gKiB2YXIgYWxsQ2xpY2tzID0gZmx5ZC5tZXJnZShidG4xQ2xpY2tzLCBidG4yQ2xpY2tzKTtcbiAqL1xuZmx5ZC5tZXJnZSA9IGN1cnJ5TigyLCBmdW5jdGlvbihzMSwgczIpIHtcbiAgdmFyIHMgPSBmbHlkLmltbWVkaWF0ZShjb21iaW5lKGZ1bmN0aW9uKHMxLCBzMiwgc2VsZiwgY2hhbmdlZCkge1xuICAgIGlmIChjaGFuZ2VkWzBdKSB7XG4gICAgICBzZWxmKGNoYW5nZWRbMF0oKSk7XG4gICAgfSBlbHNlIGlmIChzMS5oYXNWYWwpIHtcbiAgICAgIHNlbGYoczEudmFsKTtcbiAgICB9IGVsc2UgaWYgKHMyLmhhc1ZhbCkge1xuICAgICAgc2VsZihzMi52YWwpO1xuICAgIH1cbiAgfSwgW3MxLCBzMl0pKTtcbiAgZmx5ZC5lbmRzT24oY29tYmluZShmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgW3MxLmVuZCwgczIuZW5kXSksIHMpO1xuICByZXR1cm4gcztcbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc3RyZWFtIHJlc3VsdGluZyBmcm9tIGFwcGx5aW5nIGB0cmFuc2R1Y2VyYCB0byBgc3RyZWFtYC5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBgVHJhbnNkdWNlciAtPiBTdHJlYW0gYSAtPiBTdHJlYW0gYmBcbiAqXG4gKiBAbmFtZSBmbHlkLnRyYW5zZHVjZVxuICogQHBhcmFtIHtUcmFuc2R1Y2VyfSB4Zm9ybSAtIHRoZSB0cmFuc2R1Y2VyIHRyYW5zZm9ybWF0aW9uXG4gKiBAcGFyYW0ge3N0cmVhbX0gc291cmNlIC0gdGhlIHN0cmVhbSBzb3VyY2VcbiAqIEByZXR1cm4ge3N0cmVhbX0gdGhlIG5ldyBzdHJlYW1cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIHQgPSByZXF1aXJlKCd0cmFuc2R1Y2Vycy5qcycpO1xuICpcbiAqIHZhciByZXN1bHRzID0gW107XG4gKiB2YXIgczEgPSBmbHlkLnN0cmVhbSgpO1xuICogdmFyIHR4ID0gdC5jb21wb3NlKHQubWFwKGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHggKiAyOyB9KSwgdC5kZWR1cGUoKSk7XG4gKiB2YXIgczIgPSBmbHlkLnRyYW5zZHVjZSh0eCwgczEpO1xuICogZmx5ZC5jb21iaW5lKGZ1bmN0aW9uKHMyKSB7IHJlc3VsdHMucHVzaChzMigpKTsgfSwgW3MyXSk7XG4gKiBzMSgxKSgxKSgyKSgzKSgzKSgzKSg0KTtcbiAqIHJlc3VsdHM7IC8vID0+IFsyLCA0LCA2LCA4XVxuICovXG5mbHlkLnRyYW5zZHVjZSA9IGN1cnJ5TigyLCBmdW5jdGlvbih4Zm9ybSwgc291cmNlKSB7XG4gIHhmb3JtID0geGZvcm0obmV3IFN0cmVhbVRyYW5zZm9ybWVyKCkpO1xuICByZXR1cm4gY29tYmluZShmdW5jdGlvbihzb3VyY2UsIHNlbGYpIHtcbiAgICB2YXIgcmVzID0geGZvcm1bJ0BAdHJhbnNkdWNlci9zdGVwJ10odW5kZWZpbmVkLCBzb3VyY2UudmFsKTtcbiAgICBpZiAocmVzICYmIHJlc1snQEB0cmFuc2R1Y2VyL3JlZHVjZWQnXSA9PT0gdHJ1ZSkge1xuICAgICAgc2VsZi5lbmQodHJ1ZSk7XG4gICAgICByZXR1cm4gcmVzWydAQHRyYW5zZHVjZXIvdmFsdWUnXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gIH0sIFtzb3VyY2VdKTtcbn0pO1xuXG4vKipcbiAqIFJldHVybnMgYGZuYCBjdXJyaWVkIHRvIGBuYC4gVXNlIHRoaXMgZnVuY3Rpb24gdG8gY3VycnkgZnVuY3Rpb25zIGV4cG9zZWQgYnlcbiAqIG1vZHVsZXMgZm9yIEZseWQuXG4gKlxuICogQG5hbWUgZmx5ZC5jdXJyeU5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtJbnRlZ2VyfSBhcml0eSAtIHRoZSBmdW5jdGlvbiBhcml0eVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdG8gY3VycnlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSB0aGUgY3VycmllZCBmdW5jdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBmdW5jdGlvbiBhZGQoeCwgeSkgeyByZXR1cm4geCArIHk7IH07XG4gKiB2YXIgYSA9IGZseWQuY3VycnlOKDIsIGFkZCk7XG4gKiBhKDIpKDQpIC8vID0+IDZcbiAqL1xuZmx5ZC5jdXJyeU4gPSBjdXJyeU5cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSBpZGVudGljYWwgdG8gdGhlIG9yaWdpbmFsIGV4Y2VwdCBldmVyeVxuICogdmFsdWUgd2lsbCBiZSBwYXNzZWQgdGhyb3VnaCBgZmAuXG4gKlxuICogX05vdGU6XyBUaGlzIGZ1bmN0aW9uIGlzIGluY2x1ZGVkIGluIG9yZGVyIHRvIHN1cHBvcnQgdGhlIGZhbnRhc3kgbGFuZFxuICogc3BlY2lmaWNhdGlvbi5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSBhYDogYChhIC0+IGIpIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIHN0cmVhbS5tYXBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uIC0gdGhlIGZ1bmN0aW9uIHRvIGFwcGx5XG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmVhbSB3aXRoIHRoZSB2YWx1ZXMgbWFwcGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBudW1iZXJzID0gZmx5ZC5zdHJlYW0oMCk7XG4gKiB2YXIgc3F1YXJlZE51bWJlcnMgPSBudW1iZXJzLm1hcChmdW5jdGlvbihuKSB7IHJldHVybiBuKm47IH0pO1xuICovXG5mdW5jdGlvbiBib3VuZE1hcChmKSB7IHJldHVybiBmbHlkLm1hcChmLCB0aGlzKTsgfVxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgc3RyZWFtIHdoaWNoIGlzIHRoZSByZXN1bHQgb2YgYXBwbHlpbmcgdGhlXG4gKiBmdW5jdGlvbnMgZnJvbSBgdGhpc2Agc3RyZWFtIHRvIHRoZSB2YWx1ZXMgaW4gYHN0cmVhbWAgcGFyYW1ldGVyLlxuICpcbiAqIGB0aGlzYCBzdHJlYW0gbXVzdCBiZSBhIHN0cmVhbSBvZiBmdW5jdGlvbnMuXG4gKlxuICogX05vdGU6XyBUaGlzIGZ1bmN0aW9uIGlzIGluY2x1ZGVkIGluIG9yZGVyIHRvIHN1cHBvcnQgdGhlIGZhbnRhc3kgbGFuZFxuICogc3BlY2lmaWNhdGlvbi5cbiAqXG4gKiBfX1NpZ25hdHVyZV9fOiBDYWxsZWQgYm91bmQgdG8gYFN0cmVhbSAoYSAtPiBiKWA6IGBhIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBuYW1lIHN0cmVhbS5hcFxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSB2YWx1ZXMgc3RyZWFtXG4gKiBAcmV0dXJuIHtzdHJlYW19IGEgbmV3IHN0cmFtIHdpdGggdGhlIGZ1bmN0aW9ucyBhcHBsaWVkIHRvIHZhbHVlc1xuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgYWRkID0gZmx5ZC5jdXJyeU4oMiwgZnVuY3Rpb24oeCwgeSkgeyByZXR1cm4geCArIHk7IH0pO1xuICogdmFyIG51bWJlcnMxID0gZmx5ZC5zdHJlYW0oKTtcbiAqIHZhciBudW1iZXJzMiA9IGZseWQuc3RyZWFtKCk7XG4gKiB2YXIgYWRkVG9OdW1iZXJzMSA9IGZseWQubWFwKGFkZCwgbnVtYmVyczEpO1xuICogdmFyIGFkZGVkID0gYWRkVG9OdW1iZXJzMS5hcChudW1iZXJzMik7XG4gKi9cbmZ1bmN0aW9uIGFwKHMyKSB7XG4gIHZhciBzMSA9IHRoaXM7XG4gIHJldHVybiBjb21iaW5lKGZ1bmN0aW9uKHMxLCBzMiwgc2VsZikgeyBzZWxmKHMxLnZhbChzMi52YWwpKTsgfSwgW3MxLCBzMl0pO1xufVxuXG4vKipcbiAqIEdldCBhIGh1bWFuIHJlYWRhYmxlIHZpZXcgb2YgYSBzdHJlYW1cbiAqIEBuYW1lIHN0cmVhbS50b1N0cmluZ1xuICogQHJldHVybiB7U3RyaW5nfSB0aGUgc3RyZWFtIHN0cmluZyByZXByZXNlbnRhdGlvblxuICovXG5mdW5jdGlvbiBzdHJlYW1Ub1N0cmluZygpIHtcbiAgcmV0dXJuICdzdHJlYW0oJyArIHRoaXMudmFsICsgJyknO1xufVxuXG4vKipcbiAqIEBuYW1lIHN0cmVhbS5lbmRcbiAqIEBtZW1iZXJvZiBzdHJlYW1cbiAqIEEgc3RyZWFtIHRoYXQgZW1pdHMgYHRydWVgIHdoZW4gdGhlIHN0cmVhbSBlbmRzLiBJZiBgdHJ1ZWAgaXMgcHVzaGVkIGRvd24gdGhlXG4gKiBzdHJlYW0gdGhlIHBhcmVudCBzdHJlYW0gZW5kcy5cbiAqL1xuXG4vKipcbiAqIEBuYW1lIHN0cmVhbS5vZlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2Ygc3RyZWFtXG4gKiBSZXR1cm5zIGEgbmV3IHN0cmVhbSB3aXRoIGB2YWx1ZWAgYXMgaXRzIGluaXRpYWwgdmFsdWUuIEl0IGlzIGlkZW50aWNhbCB0b1xuICogY2FsbGluZyBgZmx5ZC5zdHJlYW1gIHdpdGggb25lIGFyZ3VtZW50LlxuICpcbiAqIF9fU2lnbmF0dXJlX186IENhbGxlZCBib3VuZCB0byBgU3RyZWFtIChhKWA6IGBiIC0+IFN0cmVhbSBiYFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgLSB0aGUgaW5pdGlhbCB2YWx1ZVxuICogQHJldHVybiB7c3RyZWFtfSB0aGUgbmV3IHN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbiA9IGZseWQuc3RyZWFtKDEpO1xuICogdmFyIG0gPSBuLm9mKDEpO1xuICovXG5cbi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBQUklWQVRFIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyAvL1xuLyoqXG4gKiBAcHJpdmF0ZVxuICogQ3JlYXRlIGEgc3RyZWFtIHdpdGggbm8gZGVwZW5kZW5jaWVzIGFuZCBubyB2YWx1ZVxuICogQHJldHVybiB7RnVuY3Rpb259IGEgZmx5ZCBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlU3RyZWFtKCkge1xuICBmdW5jdGlvbiBzKG4pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHMudmFsXG4gICAgdXBkYXRlU3RyZWFtVmFsdWUocywgbilcbiAgICByZXR1cm4gc1xuICB9XG4gIHMuaGFzVmFsID0gZmFsc2U7XG4gIHMudmFsID0gdW5kZWZpbmVkO1xuICBzLnZhbHMgPSBbXTtcbiAgcy5saXN0ZW5lcnMgPSBbXTtcbiAgcy5xdWV1ZWQgPSBmYWxzZTtcbiAgcy5lbmQgPSB1bmRlZmluZWQ7XG4gIHMubWFwID0gYm91bmRNYXA7XG4gIHMuYXAgPSBhcDtcbiAgcy5vZiA9IGZseWQuc3RyZWFtO1xuICBzLnRvU3RyaW5nID0gc3RyZWFtVG9TdHJpbmc7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDcmVhdGUgYSBkZXBlbmRlbnQgc3RyZWFtXG4gKiBAcGFyYW0ge0FycmF5PHN0cmVhbT59IGRlcGVuZGVuY2llcyAtIGFuIGFycmF5IG9mIHRoZSBzdHJlYW1zXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgbmV3IHN0cmVhbSB2YWx1ZVxuICogZnJvbSB0aGUgZGVwZW5kZW5jaWVzXG4gKiBAcmV0dXJuIHtzdHJlYW19IHRoZSBjcmVhdGVkIHN0cmVhbVxuICovXG5mdW5jdGlvbiBjcmVhdGVEZXBlbmRlbnRTdHJlYW0oZGVwcywgZm4pIHtcbiAgdmFyIHMgPSBjcmVhdGVTdHJlYW0oKTtcbiAgcy5mbiA9IGZuO1xuICBzLmRlcHMgPSBkZXBzO1xuICBzLmRlcHNNZXQgPSBmYWxzZTtcbiAgcy5kZXBzQ2hhbmdlZCA9IGRlcHMubGVuZ3RoID4gMCA/IFtdIDogdW5kZWZpbmVkO1xuICBzLnNob3VsZFVwZGF0ZSA9IGZhbHNlO1xuICBhZGRMaXN0ZW5lcnMoZGVwcywgcyk7XG4gIHJldHVybiBzO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBDaGVjayBpZiBhbGwgdGhlIGRlcGVuZGVuY2llcyBoYXZlIHZhbHVlc1xuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gY2hlY2sgZGVwZW5jZW5jaWVzIGZyb21cbiAqIEByZXR1cm4ge0Jvb2xlYW59IGB0cnVlYCBpZiBhbGwgZGVwZW5kZW5jaWVzIGhhdmUgdmFsZXMsIGBmYWxzZWAgb3RoZXJ3aXNlXG4gKi9cbmZ1bmN0aW9uIGluaXRpYWxEZXBzTm90TWV0KHN0cmVhbSkge1xuICBzdHJlYW0uZGVwc01ldCA9IHN0cmVhbS5kZXBzLmV2ZXJ5KGZ1bmN0aW9uKHMpIHtcbiAgICByZXR1cm4gcy5oYXNWYWw7XG4gIH0pO1xuICByZXR1cm4gIXN0cmVhbS5kZXBzTWV0O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBVcGRhdGUgYSBkZXBlbmRlbnQgc3RyZWFtIHVzaW5nIGl0cyBkZXBlbmRlbmNpZXMgaW4gYW4gYXRvbWljIHdheVxuICogQHBhcmFtIHtzdHJlYW19IHN0cmVhbSAtIHRoZSBzdHJlYW0gdG8gdXBkYXRlXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZVN0cmVhbShzKSB7XG4gIGlmICgocy5kZXBzTWV0ICE9PSB0cnVlICYmIGluaXRpYWxEZXBzTm90TWV0KHMpKSB8fFxuICAgICAgKHMuZW5kICE9PSB1bmRlZmluZWQgJiYgcy5lbmQudmFsID09PSB0cnVlKSkgcmV0dXJuO1xuICBpZiAoaW5TdHJlYW0gIT09IHVuZGVmaW5lZCkge1xuICAgIHRvVXBkYXRlLnB1c2gocyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGluU3RyZWFtID0gcztcbiAgaWYgKHMuZGVwc0NoYW5nZWQpIHMuZm5BcmdzW3MuZm5BcmdzLmxlbmd0aCAtIDFdID0gcy5kZXBzQ2hhbmdlZDtcbiAgdmFyIHJldHVyblZhbCA9IHMuZm4uYXBwbHkocy5mbiwgcy5mbkFyZ3MpO1xuICBpZiAocmV0dXJuVmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICBzKHJldHVyblZhbCk7XG4gIH1cbiAgaW5TdHJlYW0gPSB1bmRlZmluZWQ7XG4gIGlmIChzLmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIHMuZGVwc0NoYW5nZWQgPSBbXTtcbiAgcy5zaG91bGRVcGRhdGUgPSBmYWxzZTtcbiAgaWYgKGZsdXNoaW5nID09PSBmYWxzZSkgZmx1c2hVcGRhdGUoKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogVXBkYXRlIHRoZSBkZXBlbmRlbmNpZXMgb2YgYSBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGVwcyhzKSB7XG4gIHZhciBpLCBvLCBsaXN0XG4gIHZhciBsaXN0ZW5lcnMgPSBzLmxpc3RlbmVycztcbiAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7ICsraSkge1xuICAgIGxpc3QgPSBsaXN0ZW5lcnNbaV07XG4gICAgaWYgKGxpc3QuZW5kID09PSBzKSB7XG4gICAgICBlbmRTdHJlYW0obGlzdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChsaXN0LmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIGxpc3QuZGVwc0NoYW5nZWQucHVzaChzKTtcbiAgICAgIGxpc3Quc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICAgIGZpbmREZXBzKGxpc3QpO1xuICAgIH1cbiAgfVxuICBmb3IgKDsgb3JkZXJOZXh0SWR4ID49IDA7IC0tb3JkZXJOZXh0SWR4KSB7XG4gICAgbyA9IG9yZGVyW29yZGVyTmV4dElkeF07XG4gICAgaWYgKG8uc2hvdWxkVXBkYXRlID09PSB0cnVlKSB1cGRhdGVTdHJlYW0obyk7XG4gICAgby5xdWV1ZWQgPSBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBBZGQgc3RyZWFtIGRlcGVuZGVuY2llcyB0byB0aGUgZ2xvYmFsIGBvcmRlcmAgcXVldWUuXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKiBAc2VlIHVwZGF0ZURlcHNcbiAqL1xuZnVuY3Rpb24gZmluZERlcHMocykge1xuICB2YXIgaVxuICB2YXIgbGlzdGVuZXJzID0gcy5saXN0ZW5lcnM7XG4gIGlmIChzLnF1ZXVlZCA9PT0gZmFsc2UpIHtcbiAgICBzLnF1ZXVlZCA9IHRydWU7XG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7ICsraSkge1xuICAgICAgZmluZERlcHMobGlzdGVuZXJzW2ldKTtcbiAgICB9XG4gICAgb3JkZXJbKytvcmRlck5leHRJZHhdID0gcztcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGZsdXNoVXBkYXRlKCkge1xuICBmbHVzaGluZyA9IHRydWU7XG4gIHdoaWxlICh0b1VwZGF0ZS5sZW5ndGggPiAwKSB7XG4gICAgdmFyIHMgPSB0b1VwZGF0ZS5zaGlmdCgpO1xuICAgIGlmIChzLnZhbHMubGVuZ3RoID4gMCkgcy52YWwgPSBzLnZhbHMuc2hpZnQoKTtcbiAgICB1cGRhdGVEZXBzKHMpO1xuICB9XG4gIGZsdXNoaW5nID0gZmFsc2U7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIFB1c2ggZG93biBhIHZhbHVlIGludG8gYSBzdHJlYW1cbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU3RyZWFtVmFsdWUocywgbikge1xuICBpZiAobiAhPT0gdW5kZWZpbmVkICYmIG4gIT09IG51bGwgJiYgaXNGdW5jdGlvbihuLnRoZW4pKSB7XG4gICAgbi50aGVuKHMpO1xuICAgIHJldHVybjtcbiAgfVxuICBzLnZhbCA9IG47XG4gIHMuaGFzVmFsID0gdHJ1ZTtcbiAgaWYgKGluU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICBmbHVzaGluZyA9IHRydWU7XG4gICAgdXBkYXRlRGVwcyhzKTtcbiAgICBpZiAodG9VcGRhdGUubGVuZ3RoID4gMCkgZmx1c2hVcGRhdGUoKTsgZWxzZSBmbHVzaGluZyA9IGZhbHNlO1xuICB9IGVsc2UgaWYgKGluU3RyZWFtID09PSBzKSB7XG4gICAgbWFya0xpc3RlbmVycyhzLCBzLmxpc3RlbmVycyk7XG4gIH0gZWxzZSB7XG4gICAgcy52YWxzLnB1c2gobik7XG4gICAgdG9VcGRhdGUucHVzaChzKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIG1hcmtMaXN0ZW5lcnMocywgbGlzdHMpIHtcbiAgdmFyIGksIGxpc3Q7XG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0cy5sZW5ndGg7ICsraSkge1xuICAgIGxpc3QgPSBsaXN0c1tpXTtcbiAgICBpZiAobGlzdC5lbmQgIT09IHMpIHtcbiAgICAgIGlmIChsaXN0LmRlcHNDaGFuZ2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGlzdC5kZXBzQ2hhbmdlZC5wdXNoKHMpO1xuICAgICAgfVxuICAgICAgbGlzdC5zaG91bGRVcGRhdGUgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmRTdHJlYW0obGlzdCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEFkZCBkZXBlbmRlbmNpZXMgdG8gYSBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGFkZExpc3RlbmVycyhkZXBzLCBzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGVwcy5sZW5ndGg7ICsraSkge1xuICAgIGRlcHNbaV0ubGlzdGVuZXJzLnB1c2gocyk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogUmVtb3ZlcyBhbiBzdHJlYW0gZnJvbSBhIGRlcGVuZGVuY3kgYXJyYXlcbiAqIEBwYXJhbSB7c3RyZWFtfSBzdHJlYW1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyZWFtPn0gZGVwZW5kZW5jaWVzXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKHMsIGxpc3RlbmVycykge1xuICB2YXIgaWR4ID0gbGlzdGVuZXJzLmluZGV4T2Yocyk7XG4gIGxpc3RlbmVyc1tpZHhdID0gbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXTtcbiAgbGlzdGVuZXJzLmxlbmd0aC0tO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBEZXRhY2ggYSBzdHJlYW0gZnJvbSBpdHMgZGVwZW5kZW5jaWVzXG4gKiBAcGFyYW0ge3N0cmVhbX0gc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGRldGFjaERlcHMocykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHMuZGVwcy5sZW5ndGg7ICsraSkge1xuICAgIHJlbW92ZUxpc3RlbmVyKHMsIHMuZGVwc1tpXS5saXN0ZW5lcnMpO1xuICB9XG4gIHMuZGVwcy5sZW5ndGggPSAwO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBFbmRzIGEgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGVuZFN0cmVhbShzKSB7XG4gIGlmIChzLmRlcHMgIT09IHVuZGVmaW5lZCkgZGV0YWNoRGVwcyhzKTtcbiAgaWYgKHMuZW5kICE9PSB1bmRlZmluZWQpIGRldGFjaERlcHMocy5lbmQpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiB0cmFuc2R1Y2VyIHN0cmVhbSB0cmFuc2Zvcm1lclxuICovXG5mdW5jdGlvbiBTdHJlYW1UcmFuc2Zvcm1lcigpIHsgfVxuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvaW5pdCddID0gZnVuY3Rpb24oKSB7IH07XG5TdHJlYW1UcmFuc2Zvcm1lci5wcm90b3R5cGVbJ0BAdHJhbnNkdWNlci9yZXN1bHQnXSA9IGZ1bmN0aW9uKCkgeyB9O1xuU3RyZWFtVHJhbnNmb3JtZXIucHJvdG90eXBlWydAQHRyYW5zZHVjZXIvc3RlcCddID0gZnVuY3Rpb24ocywgdikgeyByZXR1cm4gdjsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBmbHlkO1xuIiwidmFyIF9hcml0eSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2FyaXR5Jyk7XG52YXIgX2N1cnJ5MSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvX2N1cnJ5MScpO1xudmFyIF9jdXJyeTIgPSByZXF1aXJlKCcuL2ludGVybmFsL19jdXJyeTInKTtcbnZhciBfY3VycnlOID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9fY3VycnlOJyk7XG5cblxuLyoqXG4gKiBSZXR1cm5zIGEgY3VycmllZCBlcXVpdmFsZW50IG9mIHRoZSBwcm92aWRlZCBmdW5jdGlvbiwgd2l0aCB0aGUgc3BlY2lmaWVkXG4gKiBhcml0eS4gVGhlIGN1cnJpZWQgZnVuY3Rpb24gaGFzIHR3byB1bnVzdWFsIGNhcGFiaWxpdGllcy4gRmlyc3QsIGl0c1xuICogYXJndW1lbnRzIG5lZWRuJ3QgYmUgcHJvdmlkZWQgb25lIGF0IGEgdGltZS4gSWYgYGdgIGlzIGBSLmN1cnJ5TigzLCBmKWAsIHRoZVxuICogZm9sbG93aW5nIGFyZSBlcXVpdmFsZW50OlxuICpcbiAqICAgLSBgZygxKSgyKSgzKWBcbiAqICAgLSBgZygxKSgyLCAzKWBcbiAqICAgLSBgZygxLCAyKSgzKWBcbiAqICAgLSBgZygxLCAyLCAzKWBcbiAqXG4gKiBTZWNvbmRseSwgdGhlIHNwZWNpYWwgcGxhY2Vob2xkZXIgdmFsdWUgYFIuX19gIG1heSBiZSB1c2VkIHRvIHNwZWNpZnlcbiAqIFwiZ2Fwc1wiLCBhbGxvd2luZyBwYXJ0aWFsIGFwcGxpY2F0aW9uIG9mIGFueSBjb21iaW5hdGlvbiBvZiBhcmd1bWVudHMsXG4gKiByZWdhcmRsZXNzIG9mIHRoZWlyIHBvc2l0aW9ucy4gSWYgYGdgIGlzIGFzIGFib3ZlIGFuZCBgX2AgaXMgYFIuX19gLCB0aGVcbiAqIGZvbGxvd2luZyBhcmUgZXF1aXZhbGVudDpcbiAqXG4gKiAgIC0gYGcoMSwgMiwgMylgXG4gKiAgIC0gYGcoXywgMiwgMykoMSlgXG4gKiAgIC0gYGcoXywgXywgMykoMSkoMilgXG4gKiAgIC0gYGcoXywgXywgMykoMSwgMilgXG4gKiAgIC0gYGcoXywgMikoMSkoMylgXG4gKiAgIC0gYGcoXywgMikoMSwgMylgXG4gKiAgIC0gYGcoXywgMikoXywgMykoMSlgXG4gKlxuICogQGZ1bmNcbiAqIEBtZW1iZXJPZiBSXG4gKiBAc2luY2UgdjAuNS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBzaWcgTnVtYmVyIC0+ICgqIC0+IGEpIC0+ICgqIC0+IGEpXG4gKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIFRoZSBhcml0eSBmb3IgdGhlIHJldHVybmVkIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICogQHJldHVybiB7RnVuY3Rpb259IEEgbmV3LCBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHNlZSBSLmN1cnJ5XG4gKiBAZXhhbXBsZVxuICpcbiAqICAgICAgdmFyIHN1bUFyZ3MgPSAoLi4uYXJncykgPT4gUi5zdW0oYXJncyk7XG4gKlxuICogICAgICB2YXIgY3VycmllZEFkZEZvdXJOdW1iZXJzID0gUi5jdXJyeU4oNCwgc3VtQXJncyk7XG4gKiAgICAgIHZhciBmID0gY3VycmllZEFkZEZvdXJOdW1iZXJzKDEsIDIpO1xuICogICAgICB2YXIgZyA9IGYoMyk7XG4gKiAgICAgIGcoNCk7IC8vPT4gMTBcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBfY3VycnkyKGZ1bmN0aW9uIGN1cnJ5TihsZW5ndGgsIGZuKSB7XG4gIGlmIChsZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gX2N1cnJ5MShmbik7XG4gIH1cbiAgcmV0dXJuIF9hcml0eShsZW5ndGgsIF9jdXJyeU4obGVuZ3RoLCBbXSwgZm4pKTtcbn0pO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBfYXJpdHkobiwgZm4pIHtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbiAgc3dpdGNoIChuKSB7XG4gICAgY2FzZSAwOiByZXR1cm4gZnVuY3Rpb24oKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKGEwKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNDogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzKSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDY6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgNzogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCwgYTUsIGE2KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgODogcmV0dXJuIGZ1bmN0aW9uKGEwLCBhMSwgYTIsIGEzLCBhNCwgYTUsIGE2LCBhNykgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBjYXNlIDk6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcsIGE4KSB7IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgIGNhc2UgMTA6IHJldHVybiBmdW5jdGlvbihhMCwgYTEsIGEyLCBhMywgYTQsIGE1LCBhNiwgYTcsIGE4LCBhOSkgeyByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IHRvIF9hcml0eSBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIgbm8gZ3JlYXRlciB0aGFuIHRlbicpO1xuICB9XG59O1xuIiwidmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogT3B0aW1pemVkIGludGVybmFsIG9uZS1hcml0eSBjdXJyeSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5MShmbikge1xuICByZXR1cm4gZnVuY3Rpb24gZjEoYSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwIHx8IF9pc1BsYWNlaG9sZGVyKGEpKSB7XG4gICAgICByZXR1cm4gZjE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfTtcbn07XG4iLCJ2YXIgX2N1cnJ5MSA9IHJlcXVpcmUoJy4vX2N1cnJ5MScpO1xudmFyIF9pc1BsYWNlaG9sZGVyID0gcmVxdWlyZSgnLi9faXNQbGFjZWhvbGRlcicpO1xuXG5cbi8qKlxuICogT3B0aW1pemVkIGludGVybmFsIHR3by1hcml0eSBjdXJyeSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5Mihmbikge1xuICByZXR1cm4gZnVuY3Rpb24gZjIoYSwgYikge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gZjI7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiBfaXNQbGFjZWhvbGRlcihhKSA/IGYyXG4gICAgICAgICAgICAgOiBfY3VycnkxKGZ1bmN0aW9uKF9iKSB7IHJldHVybiBmbihhLCBfYik7IH0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIF9pc1BsYWNlaG9sZGVyKGEpICYmIF9pc1BsYWNlaG9sZGVyKGIpID8gZjJcbiAgICAgICAgICAgICA6IF9pc1BsYWNlaG9sZGVyKGEpID8gX2N1cnJ5MShmdW5jdGlvbihfYSkgeyByZXR1cm4gZm4oX2EsIGIpOyB9KVxuICAgICAgICAgICAgIDogX2lzUGxhY2Vob2xkZXIoYikgPyBfY3VycnkxKGZ1bmN0aW9uKF9iKSB7IHJldHVybiBmbihhLCBfYik7IH0pXG4gICAgICAgICAgICAgOiBmbihhLCBiKTtcbiAgICB9XG4gIH07XG59O1xuIiwidmFyIF9hcml0eSA9IHJlcXVpcmUoJy4vX2FyaXR5Jyk7XG52YXIgX2lzUGxhY2Vob2xkZXIgPSByZXF1aXJlKCcuL19pc1BsYWNlaG9sZGVyJyk7XG5cblxuLyoqXG4gKiBJbnRlcm5hbCBjdXJyeU4gZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgYXJpdHkgb2YgdGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5fSByZWNlaXZlZCBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVjZWl2ZWQgdGh1cyBmYXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGN1cnJpZWQgZnVuY3Rpb24uXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2N1cnJ5TihsZW5ndGgsIHJlY2VpdmVkLCBmbikge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNvbWJpbmVkID0gW107XG4gICAgdmFyIGFyZ3NJZHggPSAwO1xuICAgIHZhciBsZWZ0ID0gbGVuZ3RoO1xuICAgIHZhciBjb21iaW5lZElkeCA9IDA7XG4gICAgd2hpbGUgKGNvbWJpbmVkSWR4IDwgcmVjZWl2ZWQubGVuZ3RoIHx8IGFyZ3NJZHggPCBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgaWYgKGNvbWJpbmVkSWR4IDwgcmVjZWl2ZWQubGVuZ3RoICYmXG4gICAgICAgICAgKCFfaXNQbGFjZWhvbGRlcihyZWNlaXZlZFtjb21iaW5lZElkeF0pIHx8XG4gICAgICAgICAgIGFyZ3NJZHggPj0gYXJndW1lbnRzLmxlbmd0aCkpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVjZWl2ZWRbY29tYmluZWRJZHhdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gYXJndW1lbnRzW2FyZ3NJZHhdO1xuICAgICAgICBhcmdzSWR4ICs9IDE7XG4gICAgICB9XG4gICAgICBjb21iaW5lZFtjb21iaW5lZElkeF0gPSByZXN1bHQ7XG4gICAgICBpZiAoIV9pc1BsYWNlaG9sZGVyKHJlc3VsdCkpIHtcbiAgICAgICAgbGVmdCAtPSAxO1xuICAgICAgfVxuICAgICAgY29tYmluZWRJZHggKz0gMTtcbiAgICB9XG4gICAgcmV0dXJuIGxlZnQgPD0gMCA/IGZuLmFwcGx5KHRoaXMsIGNvbWJpbmVkKVxuICAgICAgICAgICAgICAgICAgICAgOiBfYXJpdHkobGVmdCwgX2N1cnJ5TihsZW5ndGgsIGNvbWJpbmVkLCBmbikpO1xuICB9O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gX2lzUGxhY2Vob2xkZXIoYSkge1xuICByZXR1cm4gYSAhPSBudWxsICYmXG4gICAgICAgICB0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgIGFbJ0BAZnVuY3Rpb25hbC9wbGFjZWhvbGRlciddID09PSB0cnVlO1xufTtcbiIsInZhciBmbHlkID0gcmVxdWlyZSgnLi4vLi4vbGliJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZmx5ZC5jdXJyeU4oMiwgZnVuY3Rpb24oZm4sIHMpIHtcbiAgcmV0dXJuIGZseWQuY29tYmluZShmdW5jdGlvbihzLCBzZWxmKSB7XG4gICAgaWYgKGZuKHMoKSkpIHNlbGYocy52YWwpO1xuICB9LCBbc10pO1xufSk7XG4iXX0= | |
| require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"pex-geom/Rect":[function(require,module,exports){ | |
| function create(){ | |
| return [[Infinity,Infinity],[-Infinity,-Infinity]]; | |
| } | |
| function zero(){ | |
| return [[0,0],[0,0]]; | |
| } | |
| function copy(a){ | |
| return [a[0].slice(0),a[1].slice()]; | |
| } | |
| function set(a,b){ | |
| a[0][0] = b[0][0]; | |
| a[0][1] = b[0][1]; | |
| a[1][0] = b[1][0]; | |
| a[1][1] = b[1][1]; | |
| return a; | |
| } | |
| function set4(a,x,y,w,h){ | |
| a[0][0] = x; | |
| a[0][1] = y; | |
| a[1][0] = x + w; | |
| a[1][1] = y + h; | |
| return a; | |
| } | |
| function scale(a,n){ | |
| a[0][0] *= n; | |
| a[0][1] *= n; | |
| a[1][0] *= n; | |
| a[1][1] *= n; | |
| return a; | |
| } | |
| function setMinMax(a,min,max){ | |
| a[0][0] = min[0]; | |
| a[0][1] = min[1]; | |
| a[1][0] = max[0]; | |
| a[1][1] = max[1]; | |
| return a; | |
| } | |
| function setMinMax4(a,minx,miny,maxx,maxy){ | |
| a[0][0] = minx; | |
| a[0][1] = miny; | |
| a[1][0] = maxx; | |
| a[1][1] = maxy; | |
| return a; | |
| } | |
| function getMin(a,out){ | |
| if(out === undefined){ | |
| return [a[0][0],a[0][1]]; | |
| } | |
| out[0] = a[0][0]; | |
| out[1] = a[0][1]; | |
| return out; | |
| } | |
| function getMax(a,out){ | |
| if(out === undefined){ | |
| return [a[1][0],a[1][1]]; | |
| } | |
| out[0] = a[1][0]; | |
| out[1] = a[1][1]; | |
| return out; | |
| } | |
| function setSize2(a,width,height){ | |
| a[1][0] = a[0][0] + width; | |
| a[1][1] = a[0][1] + height; | |
| return a; | |
| } | |
| function setSize(a,size){ | |
| a[1][0] = a[0][0] + size[0]; | |
| a[1][1] = a[0][1] + size[1]; | |
| return a; | |
| } | |
| function getSize(a,out){ | |
| var width = getWidth(a); | |
| var height = getHeight(a); | |
| if(out === undefined){ | |
| return [width,height]; | |
| } | |
| out[0] = width; | |
| out[1] = height; | |
| return out; | |
| } | |
| function setWidth(a,width){ | |
| a[1][0] = a[0][0] + width; | |
| return a; | |
| } | |
| function setHeight(a,height){ | |
| a[1][1] = a[0][1] + height; | |
| return a; | |
| } | |
| function getWidth(a){ | |
| return a[1][0] - a[0][0]; | |
| } | |
| function getHeight(a){ | |
| return a[1][1] - a[0][1]; | |
| } | |
| function getAspectRatio(a){ | |
| return getWidth(a) / getHeight(a); | |
| } | |
| function setPosition(a,position){ | |
| return setPosition2(a,position[0],position[1]); | |
| } | |
| function setPosition2(a,x,y){ | |
| a[0][0] = x; | |
| a[0][1] = y; | |
| a[1][0] = x + getWidth(a); | |
| a[1][1] = y + getHeight(a); | |
| return a; | |
| } | |
| function getTR(a,out){ | |
| if(out === undefined){ | |
| return [a[1][0],a[1]]; | |
| } | |
| out[0] = a[1][0]; | |
| out[1] = a[0][1]; | |
| return out; | |
| } | |
| function getBL(a,out){ | |
| if(out === undefined){ | |
| return [a[0][0],a[1][1]]; | |
| } | |
| out[0] = a[0][0]; | |
| out[1] = a[1][1]; | |
| return out; | |
| } | |
| function getCenter(a,out){ | |
| var x = getWidth(a) * 0.5; | |
| var y = getHeight(a) * 0.5; | |
| if(out === undefined){ | |
| return [x,y]; | |
| } | |
| out[0] = x; | |
| out[1] = y; | |
| return out; | |
| } | |
| function containsPoint(a,point){ | |
| return containsPoint2(a,point[0],point[1]); | |
| } | |
| function containsPoint2(a,x,y){ | |
| return x >= a[0][0] && x <= a[1][0] && y >= a[0][1] && y <= a[1][1]; | |
| } | |
| function containsRect(a,b){ | |
| return containsPoint2(a,b[0][0],b[0][1]) && containsPoint2(a,b[1][0],b[1][1]); | |
| } | |
| function includePoint(a,point){ | |
| return includePoint2(a,point[0],point[1]); | |
| } | |
| function includePoint2(a,x,y){ | |
| var minx = a[0][0]; | |
| var miny = a[0][1]; | |
| var maxx = a[1][0]; | |
| var maxy = a[1][1]; | |
| a[0][0] = minx > x ? x : minx; | |
| a[0][1] = miny > y ? y : miny; | |
| a[1][0] = maxx < x ? x : maxx; | |
| a[1][1] = maxy < y ? y : maxy; | |
| return a; | |
| } | |
| function includePoints(a,points){ | |
| var minx = a[0][0]; | |
| var miny = a[0][1]; | |
| var maxx = a[1][0]; | |
| var maxy = a[1][1]; | |
| for(var i = 0, l = points.length, x, y; i < l; ++i){ | |
| x = points[i][0]; | |
| y = points[i][1]; | |
| minx = minx > x ? x : minx; | |
| miny = miny > y ? y : miny; | |
| maxx = maxx < x ? x : maxx; | |
| maxy = maxy < y ? y : maxy; | |
| } | |
| a[0][0] = minx; | |
| a[0][1] = miny; | |
| a[1][0] = maxx; | |
| a[1][1] = maxy; | |
| return a; | |
| } | |
| function includePointsFlat(a,points){ | |
| var minx = a[0][0]; | |
| var miny = a[0][1]; | |
| var maxx = a[1][0]; | |
| var maxy = a[1][1]; | |
| for(var i = 0, l = points.length, x, y; i < l; i+=2){ | |
| x = points[i ]; | |
| y = points[i+1]; | |
| minx = minx > x ? x : minx; | |
| miny = miny > y ? y : miny; | |
| maxx = maxx < x ? x : maxx; | |
| maxy = maxy < y ? y : maxy; | |
| } | |
| a[0][0] = minx; | |
| a[0][1] = miny; | |
| a[1][0] = maxx; | |
| a[1][1] = maxy; | |
| return a; | |
| } | |
| function includeRect(a,rect){ | |
| includePoint(a,rect[0]); | |
| includePoint(a,rect[1]); | |
| return a; | |
| } | |
| function includeRects(a,rects){ | |
| for(var i = 0, l = rects.length; i < l; ++i){ | |
| includeRect(a,rects[i]); | |
| } | |
| return a; | |
| } | |
| function mapPoint(a,point){ | |
| var minx = a[0][0]; | |
| var miny = a[0][1]; | |
| var maxx = a[1][0]; | |
| var maxy = a[1][1]; | |
| var x = point[0]; | |
| var y = point[1]; | |
| point[0] = Math.max(minx,Math.min(x,maxx)) - minx; | |
| point[1] = Math.max(miny,Math.min(y,maxy)) - miny; | |
| return point; | |
| } | |
| function clampPoint(a,point){ | |
| var minx = a[0][0]; | |
| var miny = a[0][1]; | |
| var maxx = a[1][0]; | |
| var maxy = a[1][1]; | |
| point[0] = Math.max(minx,Math.min(point[0],maxx)); | |
| point[1] = Math.max(miny,Math.min(point[1],maxy)); | |
| return point; | |
| } | |
| function toMax(a){ | |
| a[0][0] = a[1][0] = -Number.MAX_VALUE; | |
| a[0][1] = a[1][1] = Number.MAX_VALUE; | |
| } | |
| function setEmpty(a){ | |
| a[0][0] = a[0][1] = Infinity; | |
| a[1][0] = a[1][1] = -Infinity; | |
| return a; | |
| } | |
| function isEmpty(a){ | |
| return (a[0][0] > a[1][0]) || (a[0][1] > a[1][1]); | |
| } | |
| function isZero(a){ | |
| return a[0][0] == 0 && a[0][1] == 0 && a[1][0] == 0 && a[1][1] == 0; | |
| } | |
| function setZero(a){ | |
| a[0][0] = a[0][1] = a[1][0] = a[1][1] = 0; | |
| return a; | |
| } | |
| function createFromPoints(points){ | |
| return includePoints(create(),points); | |
| } | |
| function createFromPointsFlat(points){ | |
| return includePointsFlat(create(),points); | |
| } | |
| function createFromRects(rects){ | |
| return includeRects(create(),rects); | |
| } | |
| /** | |
| * [Rect description] | |
| * @type {Object} | |
| */ | |
| var Rect = { | |
| /** | |
| * [create description] | |
| * @type {[type]} | |
| */ | |
| create : create, | |
| /** | |
| * [zero description] | |
| * @type {[type]} | |
| */ | |
| zero : zero, | |
| /** | |
| * [copy description] | |
| * @type {[type]} | |
| */ | |
| copy : copy, | |
| /** | |
| * [set description] | |
| * @type {[type]} | |
| */ | |
| set : set, | |
| /** | |
| * [set4 description] | |
| * @type {[type]} | |
| */ | |
| set4 : set4, | |
| /** | |
| * [scale description] | |
| * @type {[type]} | |
| */ | |
| scale : scale, | |
| /** | |
| * [setMinMax description] | |
| * @type {[type]} | |
| */ | |
| setMinMax : setMinMax, | |
| /** | |
| * [setMinMax4 description] | |
| * @type {[type]} | |
| */ | |
| setMinMax4 : setMinMax4, | |
| /** | |
| * [getMin description] | |
| * @type {[type]} | |
| */ | |
| getMin : getMin, | |
| /** | |
| * [getMax description] | |
| * @type {[type]} | |
| */ | |
| getMax : getMax, | |
| /** | |
| * [setSize2 description] | |
| * @type {[type]} | |
| */ | |
| setSize2 : setSize2, | |
| /** | |
| * [setSize description] | |
| * @type {[type]} | |
| */ | |
| setSize : setSize, | |
| /** | |
| * [getSize description] | |
| * @type {[type]} | |
| */ | |
| getSize : getSize, | |
| /** | |
| * [setWidth description] | |
| * @type {[type]} | |
| */ | |
| setWidth : setWidth, | |
| /** | |
| * [getWidth description] | |
| * @type {[type]} | |
| */ | |
| getWidth : getWidth, | |
| /** | |
| * [setHeight description] | |
| * @type {[type]} | |
| */ | |
| setHeight : setHeight, | |
| /** | |
| * [getHeight description] | |
| * @type {[type]} | |
| */ | |
| getHeight : getHeight, | |
| /** | |
| * [getAspectRatio description] | |
| * @type {[type]} | |
| */ | |
| getAspectRatio : getAspectRatio, | |
| /** | |
| * [setPosition description] | |
| * @type {[type]} | |
| */ | |
| setPosition : setPosition, | |
| /** | |
| * [setPosition2 description] | |
| * @type {[type]} | |
| */ | |
| setPosition2 : setPosition2, | |
| /** | |
| * [getPosition description] | |
| * @type {[type]} | |
| */ | |
| getPosition : getMin, | |
| /** | |
| * [getTL description] | |
| * @type {[type]} | |
| */ | |
| getTL : getMin, | |
| /** | |
| * [getTR description] | |
| * @type {[type]} | |
| */ | |
| getTR : getTR, | |
| /** | |
| * [getBL description] | |
| * @type {[type]} | |
| */ | |
| getBL : getBL, | |
| /** | |
| * [getBR description] | |
| * @type {[type]} | |
| */ | |
| getBR : getMax, | |
| /** | |
| * [getCenter description] | |
| * @type {[type]} | |
| */ | |
| getCenter : getCenter, | |
| /** | |
| * [containsPoint description] | |
| * @type {[type]} | |
| */ | |
| containsPoint : containsPoint, | |
| /** | |
| * [containsPoint2 description] | |
| * @type {[type]} | |
| */ | |
| containsPoint2 : containsPoint2, | |
| /** | |
| * [containsRect description] | |
| * @type {[type]} | |
| */ | |
| containsRect : containsRect, | |
| /** | |
| * [includePoint description] | |
| * @type {[type]} | |
| */ | |
| includePoint : includePoint, | |
| /** | |
| * [includePoint2 description] | |
| * @type {[type]} | |
| */ | |
| includePoint2 : includePoint2, | |
| /** | |
| * [includePoints description] | |
| * @type {[type]} | |
| */ | |
| includePoints : includePoints, | |
| /** | |
| * [includePointsFlat description] | |
| * @type {[type]} | |
| */ | |
| includePointsFlat : includePointsFlat, | |
| /** | |
| * [includeRect description] | |
| * @type {[type]} | |
| */ | |
| includeRect : includeRect, | |
| /** | |
| * [includeRects description] | |
| * @type {[type]} | |
| */ | |
| includeRects : includeRects, | |
| /** | |
| * [mapPoint description] | |
| * @type {[type]} | |
| */ | |
| mapPoint : mapPoint, | |
| /** | |
| * [clampPoint description] | |
| * @type {[type]} | |
| */ | |
| clampPoint : clampPoint, | |
| /** | |
| * [isZero description] | |
| * @type {Boolean} | |
| */ | |
| isZero : isZero, | |
| /** | |
| * [isEmpty description] | |
| * @type {Boolean} | |
| */ | |
| isEmpty : isEmpty, | |
| /** | |
| * [setEmpty description] | |
| * @type {[type]} | |
| */ | |
| setEmpty : setEmpty, | |
| /** | |
| * [toMax description] | |
| * @type {[type]} | |
| */ | |
| toMax : toMax, | |
| /** | |
| * [setZero description] | |
| * @type {[type]} | |
| */ | |
| setZero : setZero, | |
| /** | |
| * [createFromPoints description] | |
| * @type {[type]} | |
| */ | |
| createFromPoints : createFromPoints, | |
| /** | |
| * [createFromPointsFlat description] | |
| * @type {[type]} | |
| */ | |
| createFromPointsFlat : createFromPointsFlat, | |
| /** | |
| * [createFromRects description] | |
| * @type {[type]} | |
| */ | |
| createFromRects : createFromRects | |
| }; | |
| module.exports = Rect; | |
| },{}]},{},[]) | |
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIlJlY3QuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsImZ1bmN0aW9uIGNyZWF0ZSgpe1xuICAgIHJldHVybiBbW0luZmluaXR5LEluZmluaXR5XSxbLUluZmluaXR5LC1JbmZpbml0eV1dO1xufVxuXG5mdW5jdGlvbiB6ZXJvKCl7XG4gICAgcmV0dXJuIFtbMCwwXSxbMCwwXV07XG59XG5cbmZ1bmN0aW9uIGNvcHkoYSl7XG4gICAgcmV0dXJuIFthWzBdLnNsaWNlKDApLGFbMV0uc2xpY2UoKV07XG59XG5cbmZ1bmN0aW9uIHNldChhLGIpe1xuICAgIGFbMF1bMF0gPSBiWzBdWzBdO1xuICAgIGFbMF1bMV0gPSBiWzBdWzFdO1xuICAgIGFbMV1bMF0gPSBiWzFdWzBdO1xuICAgIGFbMV1bMV0gPSBiWzFdWzFdO1xuICAgIHJldHVybiBhO1xufVxuXG5mdW5jdGlvbiBzZXQ0KGEseCx5LHcsaCl7XG4gICAgYVswXVswXSA9IHg7XG4gICAgYVswXVsxXSA9IHk7XG4gICAgYVsxXVswXSA9IHggKyB3O1xuICAgIGFbMV1bMV0gPSB5ICsgaDtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gc2NhbGUoYSxuKXtcbiAgICBhWzBdWzBdICo9IG47XG4gICAgYVswXVsxXSAqPSBuO1xuICAgIGFbMV1bMF0gKj0gbjtcbiAgICBhWzFdWzFdICo9IG47XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIHNldE1pbk1heChhLG1pbixtYXgpe1xuICAgIGFbMF1bMF0gPSBtaW5bMF07XG4gICAgYVswXVsxXSA9IG1pblsxXTtcbiAgICBhWzFdWzBdID0gbWF4WzBdO1xuICAgIGFbMV1bMV0gPSBtYXhbMV07XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIHNldE1pbk1heDQoYSxtaW54LG1pbnksbWF4eCxtYXh5KXtcbiAgICBhWzBdWzBdID0gbWlueDtcbiAgICBhWzBdWzFdID0gbWlueTtcbiAgICBhWzFdWzBdID0gbWF4eDtcbiAgICBhWzFdWzFdID0gbWF4eTtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gZ2V0TWluKGEsb3V0KXtcbiAgICBpZihvdXQgPT09IHVuZGVmaW5lZCl7XG4gICAgICAgIHJldHVybiBbYVswXVswXSxhWzBdWzFdXTtcbiAgICB9XG4gICAgb3V0WzBdID0gYVswXVswXTtcbiAgICBvdXRbMV0gPSBhWzBdWzFdO1xuICAgIHJldHVybiBvdXQ7XG59XG5cbmZ1bmN0aW9uIGdldE1heChhLG91dCl7XG4gICAgaWYob3V0ID09PSB1bmRlZmluZWQpe1xuICAgICAgICByZXR1cm4gW2FbMV1bMF0sYVsxXVsxXV07XG4gICAgfVxuICAgIG91dFswXSA9IGFbMV1bMF07XG4gICAgb3V0WzFdID0gYVsxXVsxXTtcbiAgICByZXR1cm4gb3V0O1xufVxuXG5mdW5jdGlvbiBzZXRTaXplMihhLHdpZHRoLGhlaWdodCl7XG4gICAgYVsxXVswXSA9IGFbMF1bMF0gKyB3aWR0aDtcbiAgICBhWzFdWzFdID0gYVswXVsxXSArIGhlaWdodDtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gc2V0U2l6ZShhLHNpemUpe1xuICAgIGFbMV1bMF0gPSBhWzBdWzBdICsgc2l6ZVswXTtcbiAgICBhWzFdWzFdID0gYVswXVsxXSArIHNpemVbMV07XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGdldFNpemUoYSxvdXQpe1xuICAgIHZhciB3aWR0aCAgPSBnZXRXaWR0aChhKTtcbiAgICB2YXIgaGVpZ2h0ID0gZ2V0SGVpZ2h0KGEpO1xuICAgIGlmKG91dCA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgcmV0dXJuIFt3aWR0aCxoZWlnaHRdO1xuICAgIH1cbiAgICBvdXRbMF0gPSB3aWR0aDtcbiAgICBvdXRbMV0gPSBoZWlnaHQ7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gc2V0V2lkdGgoYSx3aWR0aCl7XG4gICAgYVsxXVswXSA9IGFbMF1bMF0gKyB3aWR0aDtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gc2V0SGVpZ2h0KGEsaGVpZ2h0KXtcbiAgICBhWzFdWzFdID0gYVswXVsxXSArIGhlaWdodDtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gZ2V0V2lkdGgoYSl7XG4gICAgcmV0dXJuIGFbMV1bMF0gLSBhWzBdWzBdO1xufVxuXG5mdW5jdGlvbiBnZXRIZWlnaHQoYSl7XG4gICAgcmV0dXJuIGFbMV1bMV0gLSBhWzBdWzFdO1xufVxuXG5mdW5jdGlvbiBnZXRBc3BlY3RSYXRpbyhhKXtcbiAgICByZXR1cm4gZ2V0V2lkdGgoYSkgLyBnZXRIZWlnaHQoYSk7XG59XG5cbmZ1bmN0aW9uIHNldFBvc2l0aW9uKGEscG9zaXRpb24pe1xuICAgIHJldHVybiBzZXRQb3NpdGlvbjIoYSxwb3NpdGlvblswXSxwb3NpdGlvblsxXSk7XG59XG5cbmZ1bmN0aW9uIHNldFBvc2l0aW9uMihhLHgseSl7XG4gICAgYVswXVswXSA9IHg7XG4gICAgYVswXVsxXSA9IHk7XG4gICAgYVsxXVswXSA9IHggKyBnZXRXaWR0aChhKTtcbiAgICBhWzFdWzFdID0geSArIGdldEhlaWdodChhKTtcbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gZ2V0VFIoYSxvdXQpe1xuICAgIGlmKG91dCA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgcmV0dXJuIFthWzFdWzBdLGFbMV1dO1xuICAgIH1cbiAgICBvdXRbMF0gPSBhWzFdWzBdO1xuICAgIG91dFsxXSA9IGFbMF1bMV07XG4gICAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gZ2V0QkwoYSxvdXQpe1xuICAgIGlmKG91dCA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgcmV0dXJuIFthWzBdWzBdLGFbMV1bMV1dO1xuICAgIH1cbiAgICBvdXRbMF0gPSBhWzBdWzBdO1xuICAgIG91dFsxXSA9IGFbMV1bMV07XG4gICAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gZ2V0Q2VudGVyKGEsb3V0KXtcbiAgICB2YXIgeCA9IGdldFdpZHRoKGEpICogMC41O1xuICAgIHZhciB5ID0gZ2V0SGVpZ2h0KGEpICogMC41O1xuICAgIGlmKG91dCA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgcmV0dXJuIFt4LHldO1xuICAgIH1cbiAgICBvdXRbMF0gPSB4O1xuICAgIG91dFsxXSA9IHk7XG4gICAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gY29udGFpbnNQb2ludChhLHBvaW50KXtcbiAgICByZXR1cm4gY29udGFpbnNQb2ludDIoYSxwb2ludFswXSxwb2ludFsxXSk7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zUG9pbnQyKGEseCx5KXtcbiAgICByZXR1cm4geCA+PSBhWzBdWzBdICYmIHggPD0gYVsxXVswXSAmJiB5ID49IGFbMF1bMV0gJiYgeSA8PSBhWzFdWzFdO1xufVxuXG5mdW5jdGlvbiBjb250YWluc1JlY3QoYSxiKXtcbiAgICByZXR1cm4gY29udGFpbnNQb2ludDIoYSxiWzBdWzBdLGJbMF1bMV0pICYmIGNvbnRhaW5zUG9pbnQyKGEsYlsxXVswXSxiWzFdWzFdKTtcbn1cblxuZnVuY3Rpb24gaW5jbHVkZVBvaW50KGEscG9pbnQpe1xuICAgIHJldHVybiBpbmNsdWRlUG9pbnQyKGEscG9pbnRbMF0scG9pbnRbMV0pO1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlUG9pbnQyKGEseCx5KXtcbiAgICB2YXIgbWlueCA9IGFbMF1bMF07XG4gICAgdmFyIG1pbnkgPSBhWzBdWzFdO1xuICAgIHZhciBtYXh4ID0gYVsxXVswXTtcbiAgICB2YXIgbWF4eSA9IGFbMV1bMV07XG5cbiAgICBhWzBdWzBdID0gbWlueCA+IHggPyB4IDogbWlueDtcbiAgICBhWzBdWzFdID0gbWlueSA+IHkgPyB5IDogbWlueTtcbiAgICBhWzFdWzBdID0gbWF4eCA8IHggPyB4IDogbWF4eDtcbiAgICBhWzFdWzFdID0gbWF4eSA8IHkgPyB5IDogbWF4eTtcblxuICAgIHJldHVybiBhO1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlUG9pbnRzKGEscG9pbnRzKXtcbiAgICB2YXIgbWlueCA9IGFbMF1bMF07XG4gICAgdmFyIG1pbnkgPSBhWzBdWzFdO1xuICAgIHZhciBtYXh4ID0gYVsxXVswXTtcbiAgICB2YXIgbWF4eSA9IGFbMV1bMV07XG5cbiAgICBmb3IodmFyIGkgPSAwLCBsID0gcG9pbnRzLmxlbmd0aCwgeCwgeTsgaSA8IGw7ICsraSl7XG4gICAgICAgIHggPSBwb2ludHNbaV1bMF07XG4gICAgICAgIHkgPSBwb2ludHNbaV1bMV07XG5cbiAgICAgICAgbWlueCA9IG1pbnggPiB4ID8geCA6IG1pbng7XG4gICAgICAgIG1pbnkgPSBtaW55ID4geSA/IHkgOiBtaW55O1xuICAgICAgICBtYXh4ID0gbWF4eCA8IHggPyB4IDogbWF4eDtcbiAgICAgICAgbWF4eSA9IG1heHkgPCB5ID8geSA6IG1heHk7XG4gICAgfVxuXG4gICAgYVswXVswXSA9IG1pbng7XG4gICAgYVswXVsxXSA9IG1pbnk7XG4gICAgYVsxXVswXSA9IG1heHg7XG4gICAgYVsxXVsxXSA9IG1heHk7XG5cbiAgICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gaW5jbHVkZVBvaW50c0ZsYXQoYSxwb2ludHMpe1xuICAgIHZhciBtaW54ID0gYVswXVswXTtcbiAgICB2YXIgbWlueSA9IGFbMF1bMV07XG4gICAgdmFyIG1heHggPSBhWzFdWzBdO1xuICAgIHZhciBtYXh5ID0gYVsxXVsxXTtcblxuICAgIGZvcih2YXIgaSA9IDAsIGwgPSBwb2ludHMubGVuZ3RoLCB4LCB5OyBpIDwgbDsgaSs9Mil7XG4gICAgICAgIHggPSBwb2ludHNbaSAgXTtcbiAgICAgICAgeSA9IHBvaW50c1tpKzFdO1xuXG4gICAgICAgIG1pbnggPSBtaW54ID4geCA/IHggOiBtaW54O1xuICAgICAgICBtaW55ID0gbWlueSA+IHkgPyB5IDogbWlueTtcbiAgICAgICAgbWF4eCA9IG1heHggPCB4ID8geCA6IG1heHg7XG4gICAgICAgIG1heHkgPSBtYXh5IDwgeSA/IHkgOiBtYXh5O1xuICAgIH1cblxuICAgIGFbMF1bMF0gPSBtaW54O1xuICAgIGFbMF1bMV0gPSBtaW55O1xuICAgIGFbMV1bMF0gPSBtYXh4O1xuICAgIGFbMV1bMV0gPSBtYXh5O1xuXG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVSZWN0KGEscmVjdCl7XG4gICAgaW5jbHVkZVBvaW50KGEscmVjdFswXSk7XG4gICAgaW5jbHVkZVBvaW50KGEscmVjdFsxXSk7XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVSZWN0cyhhLHJlY3RzKXtcbiAgICBmb3IodmFyIGkgPSAwLCBsID0gcmVjdHMubGVuZ3RoOyBpIDwgbDsgKytpKXtcbiAgICAgICAgaW5jbHVkZVJlY3QoYSxyZWN0c1tpXSk7XG4gICAgfVxuICAgIHJldHVybiBhO1xufVxuXG5mdW5jdGlvbiBtYXBQb2ludChhLHBvaW50KXtcbiAgICB2YXIgbWlueCA9IGFbMF1bMF07XG4gICAgdmFyIG1pbnkgPSBhWzBdWzFdO1xuICAgIHZhciBtYXh4ID0gYVsxXVswXTtcbiAgICB2YXIgbWF4eSA9IGFbMV1bMV07XG4gICAgdmFyIHggPSBwb2ludFswXTtcbiAgICB2YXIgeSA9IHBvaW50WzFdO1xuXG4gICAgcG9pbnRbMF0gPSBNYXRoLm1heChtaW54LE1hdGgubWluKHgsbWF4eCkpIC0gbWlueDtcbiAgICBwb2ludFsxXSA9IE1hdGgubWF4KG1pbnksTWF0aC5taW4oeSxtYXh5KSkgLSBtaW55O1xuICAgIHJldHVybiBwb2ludDtcbn1cblxuZnVuY3Rpb24gY2xhbXBQb2ludChhLHBvaW50KXtcblxuICAgIHZhciBtaW54ID0gYVswXVswXTtcbiAgICB2YXIgbWlueSA9IGFbMF1bMV07XG4gICAgdmFyIG1heHggPSBhWzFdWzBdO1xuICAgIHZhciBtYXh5ID0gYVsxXVsxXTtcblxuICAgIHBvaW50WzBdID0gTWF0aC5tYXgobWlueCxNYXRoLm1pbihwb2ludFswXSxtYXh4KSk7XG4gICAgcG9pbnRbMV0gPSBNYXRoLm1heChtaW55LE1hdGgubWluKHBvaW50WzFdLG1heHkpKTtcbiAgICByZXR1cm4gcG9pbnQ7XG59XG5cbmZ1bmN0aW9uIHRvTWF4KGEpe1xuICAgIGFbMF1bMF0gPSBhWzFdWzBdID0gLU51bWJlci5NQVhfVkFMVUU7XG4gICAgYVswXVsxXSA9IGFbMV1bMV0gPSAgTnVtYmVyLk1BWF9WQUxVRTtcbn1cblxuZnVuY3Rpb24gc2V0RW1wdHkoYSl7XG4gICAgYVswXVswXSA9IGFbMF1bMV0gPSAgSW5maW5pdHk7XG4gICAgYVsxXVswXSA9IGFbMV1bMV0gPSAtSW5maW5pdHk7XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGlzRW1wdHkoYSl7XG4gICAgcmV0dXJuIChhWzBdWzBdID4gYVsxXVswXSkgfHwgKGFbMF1bMV0gPiBhWzFdWzFdKTtcbn1cblxuZnVuY3Rpb24gaXNaZXJvKGEpe1xuICAgIHJldHVybiBhWzBdWzBdID09IDAgJiYgYVswXVsxXSA9PSAwICYmIGFbMV1bMF0gPT0gMCAmJiBhWzFdWzFdID09IDA7XG59XG5cbmZ1bmN0aW9uIHNldFplcm8oYSl7XG4gICAgYVswXVswXSA9IGFbMF1bMV0gPSBhWzFdWzBdID0gYVsxXVsxXSA9IDA7XG4gICAgcmV0dXJuIGE7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUZyb21Qb2ludHMocG9pbnRzKXtcbiAgICByZXR1cm4gaW5jbHVkZVBvaW50cyhjcmVhdGUoKSxwb2ludHMpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGcm9tUG9pbnRzRmxhdChwb2ludHMpe1xuICAgIHJldHVybiBpbmNsdWRlUG9pbnRzRmxhdChjcmVhdGUoKSxwb2ludHMpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGcm9tUmVjdHMocmVjdHMpe1xuICAgIHJldHVybiBpbmNsdWRlUmVjdHMoY3JlYXRlKCkscmVjdHMpO1xufVxuXG4vKipcbiAqIFtSZWN0IGRlc2NyaXB0aW9uXVxuICogQHR5cGUge09iamVjdH1cbiAqL1xudmFyIFJlY3QgPSB7XG4gICAgLyoqXG4gICAgICogW2NyZWF0ZSBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGNyZWF0ZSA6IGNyZWF0ZSxcbiAgICAvKipcbiAgICAgKiBbemVybyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHplcm8gICA6IHplcm8sXG4gICAgLyoqXG4gICAgICogW2NvcHkgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBjb3B5ICAgOiBjb3B5LFxuICAgIC8qKlxuICAgICAqIFtzZXQgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBzZXQgIDogc2V0LFxuICAgIC8qKlxuICAgICAqIFtzZXQ0IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0NCA6IHNldDQsXG4gICAgLyoqXG4gICAgICogW3NjYWxlIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2NhbGUgOiBzY2FsZSxcbiAgICAvKipcbiAgICAgKiBbc2V0TWluTWF4IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0TWluTWF4IDogc2V0TWluTWF4LFxuICAgIC8qKlxuICAgICAqIFtzZXRNaW5NYXg0IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0TWluTWF4NCA6IHNldE1pbk1heDQsXG4gICAgLyoqXG4gICAgICogW2dldE1pbiBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGdldE1pbiA6IGdldE1pbixcbiAgICAvKipcbiAgICAgKiBbZ2V0TWF4IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0TWF4IDogZ2V0TWF4LFxuICAgIC8qKlxuICAgICAqIFtzZXRTaXplMiBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHNldFNpemUyICA6IHNldFNpemUyLFxuICAgIC8qKlxuICAgICAqIFtzZXRTaXplIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0U2l6ZSAgIDogc2V0U2l6ZSxcbiAgICAvKipcbiAgICAgKiBbZ2V0U2l6ZSBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGdldFNpemUgICA6IGdldFNpemUsXG4gICAgLyoqXG4gICAgICogW3NldFdpZHRoIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0V2lkdGggIDogc2V0V2lkdGgsXG4gICAgLyoqXG4gICAgICogW2dldFdpZHRoIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0V2lkdGggIDogZ2V0V2lkdGgsXG4gICAgLyoqXG4gICAgICogW3NldEhlaWdodCBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHNldEhlaWdodCA6IHNldEhlaWdodCxcbiAgICAvKipcbiAgICAgKiBbZ2V0SGVpZ2h0IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0SGVpZ2h0IDogZ2V0SGVpZ2h0LFxuICAgIC8qKlxuICAgICAqIFtnZXRBc3BlY3RSYXRpbyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGdldEFzcGVjdFJhdGlvIDogZ2V0QXNwZWN0UmF0aW8sXG4gICAgLyoqXG4gICAgICogW3NldFBvc2l0aW9uIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0UG9zaXRpb24gIDogc2V0UG9zaXRpb24sXG4gICAgLyoqXG4gICAgICogW3NldFBvc2l0aW9uMiBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uMiA6IHNldFBvc2l0aW9uMixcbiAgICAvKipcbiAgICAgKiBbZ2V0UG9zaXRpb24gZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBnZXRQb3NpdGlvbiAgOiBnZXRNaW4sXG4gICAgLyoqXG4gICAgICogW2dldFRMIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0VEwgOiBnZXRNaW4sXG4gICAgLyoqXG4gICAgICogW2dldFRSIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgZ2V0VFIgOiBnZXRUUixcbiAgICAvKipcbiAgICAgKiBbZ2V0QkwgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBnZXRCTCA6IGdldEJMLFxuICAgIC8qKlxuICAgICAqIFtnZXRCUiBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGdldEJSIDogZ2V0TWF4LFxuICAgIC8qKlxuICAgICAqIFtnZXRDZW50ZXIgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBnZXRDZW50ZXIgOiBnZXRDZW50ZXIsXG4gICAgLyoqXG4gICAgICogW2NvbnRhaW5zUG9pbnQgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBjb250YWluc1BvaW50IDogY29udGFpbnNQb2ludCxcbiAgICAvKipcbiAgICAgKiBbY29udGFpbnNQb2ludDIgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBjb250YWluc1BvaW50MiA6IGNvbnRhaW5zUG9pbnQyLFxuICAgIC8qKlxuICAgICAqIFtjb250YWluc1JlY3QgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBjb250YWluc1JlY3QgICA6IGNvbnRhaW5zUmVjdCxcbiAgICAvKipcbiAgICAgKiBbaW5jbHVkZVBvaW50IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgaW5jbHVkZVBvaW50ICAgICAgOiBpbmNsdWRlUG9pbnQsXG4gICAgLyoqXG4gICAgICogW2luY2x1ZGVQb2ludDIgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBpbmNsdWRlUG9pbnQyICAgICA6IGluY2x1ZGVQb2ludDIsXG4gICAgLyoqXG4gICAgICogW2luY2x1ZGVQb2ludHMgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBpbmNsdWRlUG9pbnRzICAgICA6IGluY2x1ZGVQb2ludHMsXG4gICAgLyoqXG4gICAgICogW2luY2x1ZGVQb2ludHNGbGF0IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgaW5jbHVkZVBvaW50c0ZsYXQgOiBpbmNsdWRlUG9pbnRzRmxhdCxcbiAgICAvKipcbiAgICAgKiBbaW5jbHVkZVJlY3QgZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICBpbmNsdWRlUmVjdCAgIDogaW5jbHVkZVJlY3QsXG4gICAgLyoqXG4gICAgICogW2luY2x1ZGVSZWN0cyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGluY2x1ZGVSZWN0cyAgOiBpbmNsdWRlUmVjdHMsXG4gICAgLyoqXG4gICAgICogW21hcFBvaW50IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgbWFwUG9pbnQgICA6IG1hcFBvaW50LFxuICAgIC8qKlxuICAgICAqIFtjbGFtcFBvaW50IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgY2xhbXBQb2ludCA6IGNsYW1wUG9pbnQsXG4gICAgLyoqXG4gICAgICogW2lzWmVybyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBpc1plcm8gICA6IGlzWmVybyxcbiAgICAvKipcbiAgICAgKiBbaXNFbXB0eSBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0VtcHR5ICA6IGlzRW1wdHksXG4gICAgLyoqXG4gICAgICogW3NldEVtcHR5IGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgc2V0RW1wdHkgOiBzZXRFbXB0eSxcbiAgICAvKipcbiAgICAgKiBbdG9NYXggZGVzY3JpcHRpb25dXG4gICAgICogQHR5cGUge1t0eXBlXX1cbiAgICAgKi9cbiAgICB0b01heCAgOiB0b01heCxcbiAgICAvKipcbiAgICAgKiBbc2V0WmVybyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIHNldFplcm8gOiBzZXRaZXJvLFxuICAgIC8qKlxuICAgICAqIFtjcmVhdGVGcm9tUG9pbnRzIGRlc2NyaXB0aW9uXVxuICAgICAqIEB0eXBlIHtbdHlwZV19XG4gICAgICovXG4gICAgY3JlYXRlRnJvbVBvaW50cyAgICAgOiBjcmVhdGVGcm9tUG9pbnRzLFxuICAgIC8qKlxuICAgICAqIFtjcmVhdGVGcm9tUG9pbnRzRmxhdCBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGNyZWF0ZUZyb21Qb2ludHNGbGF0IDogY3JlYXRlRnJvbVBvaW50c0ZsYXQsXG4gICAgLyoqXG4gICAgICogW2NyZWF0ZUZyb21SZWN0cyBkZXNjcmlwdGlvbl1cbiAgICAgKiBAdHlwZSB7W3R5cGVdfVxuICAgICAqL1xuICAgIGNyZWF0ZUZyb21SZWN0cyAgICAgIDogY3JlYXRlRnJvbVJlY3RzXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlY3Q7XG4iXX0= | |
| // Streams implementation for mouse events. | |
| // Started based thinking in https://github.com/pex-gl/pex-gui/issues/8 | |
| // IMPORT DEPENDENCIES | |
| // Flyd is "The less is more, modular, functional reactive programming library" | |
| const flyd = require('flyd') | |
| // emit events from one stream until another stream fires | |
| const takeUntil = require('flyd/module/takeuntil') | |
| // merge multiple streams into one | |
| const mergeAll = require('flyd/module/mergeall') | |
| // filter stream events based on predicate | |
| const filterStream = require('flyd/module/filter') | |
| // map events from a stream using a function | |
| const mapStream = flyd.map | |
| // check if point is inside a rectangle | |
| const containsPoint = require('pex-geom/Rect').containsPoint | |
| // UI | |
| // Draw a red canvas with yellow "button" on the left | |
| const btnRect = [[10, 10], [100, 100]] | |
| const canvas = document.createElement('canvas') | |
| canvas.style.background = 'red' | |
| document.body.appendChild(canvas) | |
| const ctx = canvas.getContext('2d') | |
| ctx.fillStyle = '#FFFF00' | |
| ctx.fillRect(btnRect[0][0], btnRect[0][1], btnRect[1][0] - btnRect[0][0], btnRect[1][1] - btnRect[0][1]) | |
| // crate streams for all mouse events | |
| const mousedown = flyd.stream() | |
| const mouseup = flyd.stream() | |
| const mousemove = flyd.stream() | |
| const windowmouseup = flyd.stream() | |
| canvas.addEventListener('mousedown', mousedown) | |
| canvas.addEventListener('mouseup', mouseup) | |
| canvas.addEventListener('mousemove', mousemove) | |
| window.addEventListener('mouseup', windowmouseup) | |
| //flyd.on((e) => console.log('windowmouseup', e), windowmouseup) | |
| // DRAG event stream implementation | |
| // This shows how to combine streams (down, move, up) into a new stream | |
| function createMouseDragStream (mousedown, mousemove, mouseup) { | |
| const mousedrag = flyd.stream() | |
| // on each mousedown event | |
| flyd.on((e) => { | |
| // create new stream that take events from mousemove | |
| // until mouse up on canvas or window | |
| const drag = takeUntil(mousemove, mergeAll([mouseup, windowmouseup])) | |
| // then forward all events from drag to mousedrag | |
| flyd.on(mousedrag, drag) | |
| }, mousedown) | |
| return mousedrag | |
| } | |
| const mousedrag = createMouseDragStream(mousedown, mousemove, mouseup) | |
| // print mousedrag when dragging mouse over canvas | |
| //flyd.on((e) => console.log('mousedrag', e), mousedrag) | |
| // filter functon checking if mouse event is inside rectangle | |
| function inRect (rect) { | |
| return function (e) { | |
| // TODO: curry this! | |
| return containsPoint(rect, [e.clientX, e.clientY]) | |
| } | |
| } | |
| // we use preventDefault to mark handled streams | |
| function markAsHandled (e) { | |
| e.preventDefault() | |
| return e | |
| } | |
| function notHandledYet (e) { | |
| return !e.defaultPrevented | |
| } | |
| // we add background event listener first as we go from broad to more specific | |
| const bgmousedown = filterStream(notHandledYet, mousedown) | |
| flyd.on((e) => console.log('bg mousedown', e), bgmousedown) | |
| /* | |
| const bgmousedrag = mapStream(markAsHandled, createMouseDragStream( | |
| bgmousedown, | |
| mousemove, | |
| mouseup | |
| ) | |
| ) | |
| flyd.on((e) => console.log('bg mousedrag', e), bgmousedrag) | |
| */ | |
| // mouse clicks inside yellow rect | |
| //const buttonmousedown = mapStream(markAsHandled, filterStream(inRect(btnRect), mousedown)) | |
| // mouse clicks outside yellow rect | |
| //flyd.on((e) => console.log('button mousedown', e), buttonmousedown) | |
| // crate drag event stream that happens only if we click inside button | |
| const buttonmousedrag = createMouseDragStream( | |
| mapStream(markAsHandled, filterStream(inRect(btnRect), mousedown)), | |
| mousemove, | |
| mouseup | |
| ) | |
| //flyd.on((e) => console.log('button drag', e), buttonmousedrag) | |
| /* | |
| const a = flyd.stream() | |
| const g = flyd.stream() | |
| window.addEventListener('mousedown', a) | |
| window.addEventListener('mousedown', g) | |
| flyd.on((e) => console.log('a', e), a) | |
| flyd.on((e) => console.log('g background', e), g) | |
| flyd.on((e) => console.log('g slider', e), g) | |
| */ | |
| //const pointer = require('pointer-events-stream')(gl.canvas) | |
| canvas.addEventListener('mousedown', (e) => { | |
| e.preventDefault() | |
| console.log('canvas down') | |
| }) | |
| canvas.addEventListener('mouseup', (e) => { | |
| console.log('canvas up', e.defaultPrevented) | |
| }) | |
| window.addEventListener('mouseup', (e) => { | |
| console.log('window up', e.defaultPrevented) | |
| }) | |
| window.addEventListener('mouseout', (e) => { | |
| console.log('window out', e.defaultPrevented) | |
| }) | |
| /* Ideal scenario | |
| var mouseclicks = stream() | |
| var leftoferclicks = gui.addMouse(mouseclicks) | |
| // inside gui | |
| var click = mouseclicks.peak() | |
| if (insideSlier(click)) { | |
| mouseclicks.take() | |
| } | |
| */ | |
| // PROBLEM | |
| // - calling e.preventDefault in canvas.mousedown prevents window.mouseup released outside of browser bounds | |
| // - gui and arcball / scene are using same canvas events. That wouldn't happen with canvas + dom dat.gui | |
| // SCENARIOS | |
| // gui vs arcball conflicks, picking bounding boxes vs arcball | |
| // SOLUTIONS | |
| // - keep using pex-sys/MouseEvent | |
| // - flyd: add a handled flag to the Event object | |
| // - create sepate window for gui | |
| ;}, 0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "requirebin-sketch", | |
| "version": "1.0.0", | |
| "dependencies": { | |
| "flyd": "0.2.2", | |
| "pex-geom": "1.0.0-beta.2" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- contents of this file will be placed inside the <body> --> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- contents of this file will be placed inside the <head> --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment