├── .babelrc
├── .gitignore
├── README.md
├── build
├── reactive-react.es.js
└── reactive-react.umd.js
├── demos
├── components
│ ├── blink.js
│ ├── button.css
│ ├── counter.js
│ ├── crappybird.js
│ ├── index.js
│ ├── sourceswitching.js
│ └── timer.js
├── custom.css
├── eleventy.css
├── index.html
├── index.js
└── time-slicing
│ ├── Charts.js
│ ├── Clock.js
│ ├── README.md
│ ├── index.css
│ ├── index.html
│ └── index.js
├── dependencygraph.svg
├── netlify.toml
├── package.json
├── prototypeAPI.js
├── reactive-react
├── component.js
├── element.js
├── index.js
├── reconciler.js
├── scheduler.js
├── swyxjs.js
└── updateProperties.js
└── rollup.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "transform-object-rest-spread",
4 | "transform-class-properties",
5 | [
6 | "transform-react-jsx",
7 | {}
8 | ]
9 | ],
10 | "presets": [
11 | [
12 | "env",
13 | {
14 | "targets": {
15 | "node": "current"
16 | }
17 | }
18 | ]
19 | ]
20 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | yarn.lock
4 | .cache
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a prototype mockup of a "Reactive" version of React. Do not use unless you are swyx.
2 |
3 | ## Watch the React Rally talk
4 |
5 | Talk video: https://www.youtube.com/watch?v=nyFHR0dDZo0
6 |
7 | TL;DR with writeup: https://www.swyx.io/ReactRally
8 |
9 | ## Description
10 |
11 | **Note: we are aware of the double subscribe bug when a source is switched. didnt have time to figure out the fix before react rally. Blink tag example has a hacky patch for this.**
12 |
13 | In this alternate universe, Observables became a part of Javascript.
14 |
15 | We take a minimal implementation of Observables, zen-observable.
16 |
17 |
18 | # Try it out
19 |
20 | `yarn start` to run the demo locally
21 |
22 | # The `reactive-react` API
23 |
24 | The React API we are targeting looks something like this (see `/demos` for actual examples):
25 |
26 | ```js
27 | class Counter extends Component {
28 | // demonstrate basic counter
29 | initialState = 0
30 | increment = createHandler(e => 1)
31 | decrement = createHandler(e => -1)
32 | source($) {
33 | const source = merge(this.increment.$, this.decrement.$)
34 | const reducer = (acc, n) => acc + n
35 | return {source, reducer}
36 | }
37 | render(state, stateMap) {
38 | const {name = "counter"} = this.props
39 | return
40 | {name}: {state}
41 |
42 |
43 |
44 | }
45 | }
46 |
47 | // taking info from event handler
48 | class Echo extends Component {
49 | handler = createHandler(e => e.target.value)
50 | initialState = 'hello world'
51 | source($) {
52 | const source = this.handler.$
53 | const reducer = (acc, n) => n
54 | return {source, reducer}
55 | }
56 | render(state, prevState) {
57 | return
58 |
59 | {state}
60 |
61 | }
62 | }
63 |
64 | class Timer extends Component {
65 | // demonstrate interval time
66 | initialState = 0
67 | source($) {
68 | const reducer = x => x + 1 // count up
69 | const source = Interval(this.props.ms) // tick every second
70 | // source returns an observable
71 | return scan(source, reducer, 0) // from zero
72 | }
73 | render(state, stateMap) {
74 | return number of seconds elapsed: {state}
75 | }
76 | }
77 |
78 | class Blink extends Component {
79 | // more fun time demo
80 | initialState = true
81 | source($) {
82 | const reducer = x => !x
83 | // tick every ms milliseconds
84 | const source = Interval(this.props.ms)
85 | // source can also return an observable
86 | return scan(source, reducer, true)
87 | }
88 | render(state) {
89 | const style = {display: state ? 'block' : 'none'}
90 | return Bring back the blink tag!
91 | }
92 | }
93 |
94 | class CrappyBird extends Component {
95 | // merging time and counter
96 | initialState = {
97 | input: 50,
98 | target: 50
99 | }
100 | increment = createHandler(e => 3)
101 | source($) {
102 | return this.combineReducer({
103 | input: () => {
104 | const source = merge(this.increment.$, Interval(200,-1))
105 | const reducer = (acc, x) => Math.max(0,acc + x)
106 | return {source, reducer}
107 | },
108 | target: () => {
109 | const source = Interval(200)
110 | const reducer = (acc) => {
111 | const int = acc + Math.random() * 8 - 4
112 | return int - (int-50)/30 // bias toward 50
113 | }
114 | return {source, reducer}
115 | }
116 | })
117 | }
118 | render(state, stateMap) {
119 | const {input, target} = state
120 | return
121 |
122 |
Crappy bird
123 |
Bird:
124 |
Target:
125 |
126 | }
127 | }
128 |
129 | function Counters() {
130 | // demonstrate independent states
131 | return
132 |
133 |
134 |
135 | }
136 | function Source() {
137 | // demonstrate ability to switch sources
138 | return }
140 | right={}
141 | />
142 | }
143 |
144 | class SourceSwitching extends Component {
145 | initialState = true
146 | toggle = createHandler()
147 | source($) {
148 | const source = this.toggle.$
149 | const reducer = x => !x
150 | return {source, reducer}
151 | }
152 | render(state, stateMap) {
153 | return
154 |
155 | {
156 | state ? this.props.left : this.props.right
157 | }
158 |
159 | }
160 | }
161 |
162 | ```
163 |
164 | # Local development
165 |
166 | `yarn run build` and then `npm publish` (but its under my namespace @swyx/reactive-react cos someone else has the generic one)
167 |
168 | Here is the project structure:
169 |
170 | 
171 |
--------------------------------------------------------------------------------
/build/reactive-react.es.js:
--------------------------------------------------------------------------------
1 | import Observable from 'zen-observable';
2 | import { createChangeEmitter } from 'change-emitter';
3 | import { merge } from 'zen-observable/extras';
4 | import h from 'virtual-dom/h';
5 | import VText from 'virtual-dom/vnode/vtext';
6 | import diff from 'virtual-dom/diff';
7 | import patch from 'virtual-dom/patch';
8 | import createElement from 'virtual-dom/create-element';
9 |
10 | var TEXT_ELEMENT = "TEXT ELEMENT";
11 |
12 | function createElement$1(type, config) {
13 | var _ref;
14 |
15 | var props = Object.assign({}, config);
16 |
17 | for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
18 | args[_key - 2] = arguments[_key];
19 | }
20 |
21 | var hasChildren = args.length > 0;
22 | var rawChildren = hasChildren ? (_ref = []).concat.apply(_ref, args) : [];
23 | props.children = rawChildren.filter(function (c) {
24 | return c != null && c !== false;
25 | }).map(function (c) {
26 | return c instanceof Object ? c : createTextElement(c);
27 | });
28 | return { type: type, props: props };
29 | }
30 |
31 | function createTextElement(value) {
32 | return createElement$1(TEXT_ELEMENT, { nodeValue: value });
33 | }
34 |
35 | function createHandler(_fn) {
36 | var emitter = createChangeEmitter();
37 | var handler = function handler(x) {
38 | emitter.emit(x);
39 | };
40 | handler.$ = new Observable(function (observer) {
41 | return emitter.listen(function (value) {
42 | observer.next(_fn ? _fn(value) : value);
43 | });
44 | });
45 | return handler;
46 | }
47 |
48 | var NOINIT = Symbol('NO_INITIAL_VALUE');
49 | function scan(obs, cb) {
50 | var seed = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : NOINIT;
51 |
52 | var sub = void 0,
53 | acc = seed,
54 | hasValue = false;
55 | var hasSeed = acc !== NOINIT;
56 | return new Observable(function (observer) {
57 | sub = obs.subscribe(function (value) {
58 | if (observer.closed) return;
59 | var first = !hasValue;
60 | hasValue = true;
61 | if (!first || hasSeed) {
62 | try {
63 | acc = cb(acc, value);
64 | } catch (e) {
65 | return observer.error(e);
66 | }
67 | observer.next(acc);
68 | } else {
69 | acc = value;
70 | }
71 | });
72 | return sub;
73 | });
74 | }
75 |
76 | // Flatten a collection of observables and only output the newest from each
77 |
78 |
79 |
80 |
81 | function startWith(obs, val) {
82 | return new Observable(function (observer) {
83 | observer.next(val); // immediately output this value
84 | var handler = obs.subscribe(function (x) {
85 | return observer.next(x);
86 | });
87 | return function () {
88 | return handler();
89 | };
90 | });
91 | }
92 |
93 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
94 |
95 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
96 |
97 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
98 |
99 | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
100 |
101 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
102 |
103 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
104 |
105 | // import { reconcile } from "./reconciler";
106 | var Component = function () {
107 | function Component(props) {
108 | _classCallCheck(this, Component);
109 |
110 | this.props = props;
111 | this.state = this.state || {};
112 | }
113 |
114 | // setState(partialState) {
115 | // this.state = Object.assign({}, this.state, partialState);
116 | // updateInstance(this.__internalInstance);
117 | // }
118 |
119 | // class method because it feeds in this.initialState
120 |
121 |
122 | _createClass(Component, [{
123 | key: 'combineReducer',
124 | value: function combineReducer(obj) {
125 | var _this = this;
126 |
127 | var sources = Object.entries(obj).map(function (_ref) {
128 | var _ref2 = _slicedToArray(_ref, 2),
129 | k = _ref2[0],
130 | fn = _ref2[1];
131 |
132 | var subReducer = fn(obj);
133 | // there are two forms of return the subreducer can have
134 | // straight stream form
135 | // or object form where we need to scan it into string
136 | if (subReducer.source && subReducer.reducer) {
137 | // object form
138 | subReducer = scan(subReducer.source, subReducer.reducer || function (_, n) {
139 | return n;
140 | }, _this.initialState[k]);
141 | }
142 | return subReducer.map(function (x) {
143 | return _defineProperty({}, k, x);
144 | }); // map to its particular namespace
145 | });
146 | var source = merge.apply(undefined, _toConsumableArray(sources));
147 | var reducer = function reducer(acc, n) {
148 | return _extends({}, acc, n);
149 | };
150 | return { source: source, reducer: reducer };
151 | }
152 | }]);
153 |
154 | return Component;
155 | }();
156 |
157 | // function updateInstance(internalInstance) {
158 | // const parentDom = internalInstance.dom.parentNode;
159 | // const element = internalInstance.element;
160 | // reconcile(parentDom, internalInstance, element);
161 | // }
162 |
163 | function createPublicInstance(element /*, internalInstance*/) {
164 | var type = element.type,
165 | props = element.props;
166 |
167 | var publicInstance = new type(props);
168 | // publicInstance.__internalInstance = internalInstance;
169 | return publicInstance;
170 | }
171 |
172 | var _slicedToArray$1 = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
173 |
174 | function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
175 |
176 | // import { updateDomProperties } from "./updateProperties";
177 | // import VNode from "virtual-dom/vnode/vnode"
178 | // const circuitBreakerflag = false // set true to enable debugger in infinite loops
179 | // let circuitBreaker = -50
180 | // traverse all children and collect a stream of all sources
181 | // AND render. a bit of duplication, but we get persistent instances which is good
182 | function renderStream(element, instance, state, stateMap) {
183 | // this is a separate function because scope gets messy when being recursive
184 | var isNewStream = false; // assume no stream switching by default
185 | // this is the first ping of data throughout the app
186 | var source = Observable.of(state);
187 | var addToStream = function addToStream(_source) {
188 | // visit each source and merge with source
189 | if (_source) return source = merge(source, _source);
190 | };
191 | var markNewStream = function markNewStream() {
192 | return isNewStream = true;
193 | };
194 | var newInstance = render(source, addToStream, markNewStream)(element, instance, state, stateMap);
195 | return { source: source, instance: newInstance, isNewStream: isNewStream };
196 | }
197 |
198 | /** core render logic */
199 | function render(source, addToStream, markNewStream) {
200 | // this is the nonrecursive part
201 | return function renderWithStream(element, instance, state, stateMap) {
202 | // recursive part
203 | var newInstance = void 0;
204 | var type = element.type,
205 | props = element.props;
206 |
207 |
208 | var isDomElement = typeof type === "string";
209 | // if (circuitBreakerflag && circuitBreaker++ > 0) debugger
210 |
211 | var _props$children = props.children,
212 | children = _props$children === undefined ? [] : _props$children,
213 | rest = _objectWithoutProperties(props, ['children']);
214 |
215 | if (isDomElement) {
216 | var childInstances = children.map(function (el, i) {
217 | // ugly but necessary to allow functional children
218 | // mapping element's children to instance's childInstances
219 | var _childInstances = instance && (instance.childInstance || instance.childInstances[i]);
220 | return renderWithStream( // recursion
221 | el, _childInstances, state, stateMap);
222 | });
223 | var childDoms = childInstances.map(function (childInstance) {
224 | return childInstance.dom;
225 | });
226 | var lcaseProps = {};
227 | Object.entries(rest).forEach(function (_ref) {
228 | var _ref2 = _slicedToArray$1(_ref, 2),
229 | k = _ref2[0],
230 | v = _ref2[1];
231 |
232 | return lcaseProps[formatProps(k)] = v;
233 | });
234 | var dom = type === TEXT_ELEMENT ? new VText(props.nodeValue) : h(type, lcaseProps, childDoms); // equivalent of appendchild
235 | newInstance = { dom: dom, element: element, childInstances: childInstances };
236 | } else {
237 | // component element
238 | var publicInstance = void 0;
239 | // debugger
240 | if (instance && instance.publicInstance && instance.element === element) {
241 | // might have to do more diffing of props
242 | // just reuse old instance if it already exists
243 | publicInstance = instance && instance.publicInstance;
244 | } else {
245 | markNewStream(); // mark as dirty in parent scope; will rerender
246 | publicInstance = createPublicInstance(element);
247 | }
248 | var localState = stateMap.get(publicInstance);
249 | if (localState === undefined) localState = publicInstance.initialState;
250 | publicInstance.state = localState; // for access with this.state
251 | if (Object.keys(rest).length) publicInstance.props = rest; // update with new props // TODO: potentially buggy
252 | // console.log({rest})
253 | if (publicInstance.source) {
254 | var src = publicInstance.source(source);
255 | // there are two forms of Component.source
256 | var src$ = src.reducer && publicInstance.initialState !== undefined ?
257 | // 1. the reducer form
258 | scan(src.source, src.reducer, publicInstance.initialState) :
259 | // 2. and raw stream form
260 | src;
261 | addToStream(src$.map(function (event) {
262 | stateMap.set(publicInstance, event);
263 | return { instance: publicInstance, event: event // tag it to the instance
264 | };
265 | }));
266 | }
267 | var childElement = publicInstance.render ? publicInstance.render(localState, stateMap) : publicInstance;
268 |
269 | var childInstance = renderWithStream(childElement, instance && instance.childInstance, state, stateMap);
270 | var _dom = childInstance.dom;
271 | newInstance = { dom: _dom, element: element, childInstance: childInstance, publicInstance: publicInstance };
272 | }
273 | return newInstance;
274 | };
275 | }
276 |
277 | function formatProps(k) {
278 | if (k.startsWith('on')) return k.toLowerCase();
279 | return k;
280 | }
281 |
282 | var stateMapPointer = new Map();
283 |
284 | var emitter = createChangeEmitter();
285 | // single UI thread; this is the observable that sticks around and swaps out source
286 | var UIthread = new Observable(function (observer) {
287 | emitter.listen(function (x) {
288 | // debugger // success! thread switching!
289 | observer.next(x);
290 | });
291 | });
292 | // mount the vdom on to the dom and
293 | // set up the runtime from sources and
294 | // patch the vdom
295 | // ---
296 | // returns an unsubscribe method you can use to unmount
297 | function mount(rootElement, container) {
298 | // initial, throwaway-ish frame
299 | var _renderStream = renderStream(rootElement, {}, undefined, stateMapPointer),
300 | source = _renderStream.source,
301 | instance = _renderStream.instance;
302 |
303 | var instancePointer = instance;
304 | var rootNode = createElement(instance.dom);
305 | var containerChild = container.firstElementChild;
306 | if (containerChild) {
307 | container.replaceChild(rootNode, containerChild); // hot reloaded mount
308 | } else {
309 | container.appendChild(rootNode); // initial mount
310 | }
311 | var currentSrc$ = null;
312 | var SoS = startWith(UIthread, source); // stream of streams
313 | return SoS.subscribe(function (src$) {
314 | // this is the current sourceStream we are working with
315 | if (currentSrc$) console.log('unsub!') || currentSrc$.unsubscribe(); // unsub from old stream
316 | /**** main */
317 | var source2$ = scan(src$, function (_ref, nextState) {
318 | var instance = _ref.instance,
319 | stateMap = _ref.stateMap;
320 |
321 | var streamOutput = renderStream(rootElement, instance, nextState, stateMap);
322 | if (streamOutput.isNewStream) {
323 | // quick check
324 | var nextSource$ = streamOutput.source;
325 | // debugger
326 | instancePointer = streamOutput.instance;
327 | patch(rootNode, diff(instance.dom, instancePointer.dom)); // render to screen
328 | emitter.emit(nextSource$); // update the UI thread; source will switch
329 | } else {
330 | var nextinstance = streamOutput.instance;
331 | patch(rootNode, diff(instance.dom, nextinstance.dom)); // render to screen
332 | return { instance: nextinstance, stateMap: stateMap };
333 | }
334 | }, { instance: instancePointer, stateMap: stateMapPointer // accumulator
335 | });
336 | /**** end main */
337 | currentSrc$ = source2$.subscribe();
338 | });
339 | }
340 |
341 | var index = {
342 | renderStream: renderStream,
343 | createElement: createElement$1,
344 | createHandler: createHandler,
345 | Component: Component,
346 | mount: mount
347 | };
348 |
349 | export { createElement$1 as createElement, createHandler, Component, renderStream, mount };export default index;
350 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3RpdmUtcmVhY3QuZXMuanMiLCJzb3VyY2VzIjpbIi4uL3JlYWN0aXZlLXJlYWN0L2VsZW1lbnQuanMiLCIuLi9yZWFjdGl2ZS1yZWFjdC9zd3l4anMuanMiLCIuLi9yZWFjdGl2ZS1yZWFjdC9jb21wb25lbnQuanMiLCIuLi9yZWFjdGl2ZS1yZWFjdC9yZWNvbmNpbGVyLmpzIiwiLi4vcmVhY3RpdmUtcmVhY3Qvc2NoZWR1bGVyLmpzIiwiLi4vcmVhY3RpdmUtcmVhY3QvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IE9ic2VydmFibGUgZnJvbSAnemVuLW9ic2VydmFibGUnXG5pbXBvcnQgeyBjcmVhdGVDaGFuZ2VFbWl0dGVyIH0gZnJvbSAnY2hhbmdlLWVtaXR0ZXInXG5cbmV4cG9ydCBjb25zdCBURVhUX0VMRU1FTlQgPSBcIlRFWFQgRUxFTUVOVFwiO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRWxlbWVudCh0eXBlLCBjb25maWcsIC4uLmFyZ3MpIHtcbiAgY29uc3QgcHJvcHMgPSBPYmplY3QuYXNzaWduKHt9LCBjb25maWcpO1xuICBjb25zdCBoYXNDaGlsZHJlbiA9IGFyZ3MubGVuZ3RoID4gMDtcbiAgY29uc3QgcmF3Q2hpbGRyZW4gPSBoYXNDaGlsZHJlbiA/IFtdLmNvbmNhdCguLi5hcmdzKSA6IFtdO1xuICBwcm9wcy5jaGlsZHJlbiA9IHJhd0NoaWxkcmVuXG4gICAgLmZpbHRlcihjID0+IGMgIT0gbnVsbCAmJiBjICE9PSBmYWxzZSlcbiAgICAubWFwKGMgPT4gYyBpbnN0YW5jZW9mIE9iamVjdCA/IGMgOiBjcmVhdGVUZXh0RWxlbWVudChjKSk7XG4gIHJldHVybiB7IHR5cGUsIHByb3BzIH07XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVRleHRFbGVtZW50KHZhbHVlKSB7XG4gIHJldHVybiBjcmVhdGVFbGVtZW50KFRFWFRfRUxFTUVOVCwgeyBub2RlVmFsdWU6IHZhbHVlIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSGFuZGxlcihfZm4pIHtcbiAgY29uc3QgZW1pdHRlciA9IGNyZWF0ZUNoYW5nZUVtaXR0ZXIoKVxuICBsZXQgaGFuZGxlciA9IHggPT4ge1xuICAgIGVtaXR0ZXIuZW1pdCh4KVxuICB9XG4gIGhhbmRsZXIuJCA9IG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW4odmFsdWUgPT4ge1xuICAgICAgb2JzZXJ2ZXIubmV4dChfZm4gPyBfZm4odmFsdWUpIDogdmFsdWUpXG4gICAgfVxuICAgIClcbiAgfSlcbiAgcmV0dXJuIGhhbmRsZXJcbn0iLCJpbXBvcnQgT2JzZXJ2YWJsZSBmcm9tICd6ZW4tb2JzZXJ2YWJsZSdcbmV4cG9ydCB7IG1lcmdlLCBjb21iaW5lTGF0ZXN0LCB6aXAgfSBmcm9tICd6ZW4tb2JzZXJ2YWJsZS9leHRyYXMnXG5cbmV4cG9ydCBmdW5jdGlvbiBJbnRlcnZhbCh0aWNrID0gMTAwMCwgdGlja0RhdGEgPSBTeW1ib2woJ3RpY2snKSkge1xuICByZXR1cm4gbmV3IE9ic2VydmFibGUob2JzZXJ2ZXIgPT4ge1xuICAgIGxldCB0aW1lciA9ICgpID0+IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0aWNrRGF0YSA9PT0gJ2Z1bmN0aW9uJykgdGlja0RhdGEgPSB0aWNrRGF0YSgpXG4gICAgICBvYnNlcnZlci5uZXh0KHRpY2tEYXRhKTtcbiAgICAgIHRpbWVyKClcbiAgICAgIC8vIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgfSwgdGljayk7XG4gICAgdGltZXIoKVxuICBcbiAgICAvLyBPbiB1bnN1YnNjcmlwdGlvbiwgY2FuY2VsIHRoZSB0aW1lclxuICAgIHJldHVybiAoKSA9PiBjbGVhclRpbWVvdXQodGltZXIpO1xuXG4gIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tRXZlbnQoZWwsIGV2ZW50VHlwZSkge1xuICByZXR1cm4gbmV3IE9ic2VydmFibGUob2JzZXJ2ZXIgPT4ge1xuICAgIGNvbnN0IGhhbmRsZXIgPSBlID0+IG9ic2VydmVyLm5leHQoZSlcbiAgICBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgaGFuZGxlcilcbiAgICAvLyBvbiB1bnN1YiwgcmVtb3ZlIGV2ZW50IGxpc3RlbmVyXG4gICAgcmV0dXJuICgpID0+IGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBoYW5kbGVyKVxuICB9KVxufVxuXG5jb25zdCBOT0lOSVQgPSBTeW1ib2woJ05PX0lOSVRJQUxfVkFMVUUnKVxuZXhwb3J0IGZ1bmN0aW9uIHNjYW4ob2JzLCBjYiwgc2VlZCA9IE5PSU5JVCkge1xuICBsZXQgc3ViLCBhY2MgPSBzZWVkLCBoYXNWYWx1ZSA9IGZhbHNlXG4gIGNvbnN0IGhhc1NlZWQgPSBhY2MgIT09IE5PSU5JVFxuICByZXR1cm4gbmV3IE9ic2VydmFibGUob2JzZXJ2ZXIgPT4ge1xuICAgIHN1YiA9IG9icy5zdWJzY3JpYmUodmFsdWUgPT4ge1xuICAgICAgaWYgKG9ic2VydmVyLmNsb3NlZCkgcmV0dXJuXG4gICAgICBsZXQgZmlyc3QgPSAhaGFzVmFsdWU7XG4gICAgICBoYXNWYWx1ZSA9IHRydWVcbiAgICAgIGlmICghZmlyc3QgfHwgaGFzU2VlZCApIHtcbiAgICAgICAgdHJ5IHsgYWNjID0gY2IoYWNjLCB2YWx1ZSkgfVxuICAgICAgICBjYXRjaCAoZSkgeyByZXR1cm4gb2JzZXJ2ZXIuZXJyb3IoZSkgfVxuICAgICAgICBvYnNlcnZlci5uZXh0KGFjYyk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgYWNjID0gdmFsdWVcbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiBzdWJcbiAgfSlcbn1cblxuLy8gRmxhdHRlbiBhIGNvbGxlY3Rpb24gb2Ygb2JzZXJ2YWJsZXMgYW5kIG9ubHkgb3V0cHV0IHRoZSBuZXdlc3QgZnJvbSBlYWNoXG5leHBvcnQgZnVuY3Rpb24gc3dpdGNoTGF0ZXN0KGhpZ2hlck9ic2VydmFibGUpIHtcbiAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICBsZXQgY3VycmVudE9icyA9IG51bGxcbiAgICByZXR1cm4gaGlnaGVyT2JzZXJ2YWJsZS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dChvYnMpIHtcbiAgICAgICAgaWYgKGN1cnJlbnRPYnMpIGN1cnJlbnRPYnMudW5zdWJzY3JpYmUoKSAvLyB1bnN1YiBhbmQgc3dpdGNoXG4gICAgICAgIGN1cnJlbnRPYnMgPSBvYnMuc3Vic2NyaWJlKG9ic2VydmVyLnN1YnNjcmliZSlcbiAgICAgIH0sXG4gICAgICBlcnJvcihlKSB7XG4gICAgICAgIG9ic2VydmVyLmVycm9yKGUpIC8vIHVudGVzdGVkXG4gICAgICB9LFxuICAgICAgY29tcGxldGUoKSB7XG4gICAgICAgIC8vIGkgZG9udCB0aGluayBpdCBzaG91bGQgY29tcGxldGU/XG4gICAgICAgIC8vIG9ic2VydmVyLmNvbXBsZXRlKClcbiAgICAgIH1cbiAgICB9KVxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1hcFRvQ29uc3RhbnQob2JzLCB2YWwpIHtcbiAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICBjb25zdCBoYW5kbGVyID0gb2JzLnN1YnNjcmliZSgoKSA9PiBvYnNlcnZlci5uZXh0KHZhbCkpXG4gICAgcmV0dXJuIGhhbmRsZXJcbiAgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0V2l0aChvYnMsIHZhbCkge1xuICByZXR1cm4gbmV3IE9ic2VydmFibGUob2JzZXJ2ZXIgPT4ge1xuICAgIG9ic2VydmVyLm5leHQodmFsKSAvLyBpbW1lZGlhdGVseSBvdXRwdXQgdGhpcyB2YWx1ZVxuICAgIGNvbnN0IGhhbmRsZXIgPSBvYnMuc3Vic2NyaWJlKHggPT4gb2JzZXJ2ZXIubmV4dCh4KSlcbiAgICByZXR1cm4gKCkgPT4gaGFuZGxlcigpXG4gIH0pXG59IiwiLy8gaW1wb3J0IHsgcmVjb25jaWxlIH0gZnJvbSBcIi4vcmVjb25jaWxlclwiO1xuaW1wb3J0IHtJbnRlcnZhbCwgc2Nhbiwgc3RhcnRXaXRoLCBtZXJnZSwgbWFwVG9Db25zdGFudH0gZnJvbSAnLi9zd3l4anMnXG5cbmV4cG9ydCBjbGFzcyBDb21wb25lbnQge1xuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgICB0aGlzLnN0YXRlID0gdGhpcy5zdGF0ZSB8fCB7fTtcbiAgfVxuXG4gIC8vIHNldFN0YXRlKHBhcnRpYWxTdGF0ZSkge1xuICAvLyAgIHRoaXMuc3RhdGUgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLnN0YXRlLCBwYXJ0aWFsU3RhdGUpO1xuICAvLyAgIHVwZGF0ZUluc3RhbmNlKHRoaXMuX19pbnRlcm5hbEluc3RhbmNlKTtcbiAgLy8gfVxuXG4gIC8vIGNsYXNzIG1ldGhvZCBiZWNhdXNlIGl0IGZlZWRzIGluIHRoaXMuaW5pdGlhbFN0YXRlXG4gIGNvbWJpbmVSZWR1Y2VyKG9iaikge1xuICAgIGNvbnN0IHNvdXJjZXMgPSBPYmplY3QuZW50cmllcyhvYmopLm1hcCgoW2ssZm5dKSA9PiB7XG4gICAgICBsZXQgc3ViUmVkdWNlciA9IGZuKG9iailcbiAgICAgIC8vIHRoZXJlIGFyZSB0d28gZm9ybXMgb2YgcmV0dXJuIHRoZSBzdWJyZWR1Y2VyIGNhbiBoYXZlXG4gICAgICAvLyBzdHJhaWdodCBzdHJlYW0gZm9ybVxuICAgICAgLy8gb3Igb2JqZWN0IGZvcm0gd2hlcmUgd2UgbmVlZCB0byBzY2FuIGl0IGludG8gc3RyaW5nXG4gICAgICBpZiAoc3ViUmVkdWNlci5zb3VyY2UgJiYgc3ViUmVkdWNlci5yZWR1Y2VyKSB7IC8vIG9iamVjdCBmb3JtXG4gICAgICAgIHN1YlJlZHVjZXIgPSBzY2FuKHN1YlJlZHVjZXIuc291cmNlLCBcbiAgICAgICAgICBzdWJSZWR1Y2VyLnJlZHVjZXIgfHwgKChfLCBuKSA9PiBuKSwgXG4gICAgICAgICAgdGhpcy5pbml0aWFsU3RhdGVba11cbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHN1YlJlZHVjZXJcbiAgICAgICAgLm1hcCh4ID0+ICh7W2tdOiB4fSkpIC8vIG1hcCB0byBpdHMgcGFydGljdWxhciBuYW1lc3BhY2VcbiAgICB9KVxuICAgIGNvbnN0IHNvdXJjZSA9IG1lcmdlKC4uLnNvdXJjZXMpXG4gICAgY29uc3QgcmVkdWNlciA9IChhY2MsIG4pID0+ICh7Li4uYWNjLCAuLi5ufSlcbiAgICByZXR1cm4ge3NvdXJjZSwgcmVkdWNlcn1cbiAgfVxufVxuXG4vLyBmdW5jdGlvbiB1cGRhdGVJbnN0YW5jZShpbnRlcm5hbEluc3RhbmNlKSB7XG4vLyAgIGNvbnN0IHBhcmVudERvbSA9IGludGVybmFsSW5zdGFuY2UuZG9tLnBhcmVudE5vZGU7XG4vLyAgIGNvbnN0IGVsZW1lbnQgPSBpbnRlcm5hbEluc3RhbmNlLmVsZW1lbnQ7XG4vLyAgIHJlY29uY2lsZShwYXJlbnREb20sIGludGVybmFsSW5zdGFuY2UsIGVsZW1lbnQpO1xuLy8gfVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHVibGljSW5zdGFuY2UoZWxlbWVudC8qLCBpbnRlcm5hbEluc3RhbmNlKi8pIHtcbiAgY29uc3QgeyB0eXBlLCBwcm9wcyB9ID0gZWxlbWVudDtcbiAgY29uc3QgcHVibGljSW5zdGFuY2UgPSBuZXcgdHlwZShwcm9wcyk7XG4gIC8vIHB1YmxpY0luc3RhbmNlLl9faW50ZXJuYWxJbnN0YW5jZSA9IGludGVybmFsSW5zdGFuY2U7XG4gIHJldHVybiBwdWJsaWNJbnN0YW5jZTtcbn1cbiIsImltcG9ydCBPYnNlcnZhYmxlIGZyb20gJ3plbi1vYnNlcnZhYmxlJ1xuaW1wb3J0IHtmcm9tRXZlbnQsIHNjYW4sIG1lcmdlLCBzdGFydFdpdGgsIHN3aXRjaExhdGVzdH0gZnJvbSAnLi9zd3l4anMnXG4vLyBpbXBvcnQgeyB1cGRhdGVEb21Qcm9wZXJ0aWVzIH0gZnJvbSBcIi4vdXBkYXRlUHJvcGVydGllc1wiO1xuaW1wb3J0IHsgVEVYVF9FTEVNRU5UIH0gZnJvbSBcIi4vZWxlbWVudFwiO1xuaW1wb3J0IHsgY3JlYXRlUHVibGljSW5zdGFuY2UgfSBmcm9tIFwiLi9jb21wb25lbnRcIjtcbmltcG9ydCBoIGZyb20gJ3ZpcnR1YWwtZG9tL2gnXG4vLyBpbXBvcnQgVk5vZGUgZnJvbSBcInZpcnR1YWwtZG9tL3Zub2RlL3Zub2RlXCJcbmltcG9ydCBWVGV4dCBmcm9tIFwidmlydHVhbC1kb20vdm5vZGUvdnRleHRcIlxuXG4vLyBjb25zdCBjaXJjdWl0QnJlYWtlcmZsYWcgPSBmYWxzZSAvLyBzZXQgdHJ1ZSB0byBlbmFibGUgZGVidWdnZXIgaW4gaW5maW5pdGUgbG9vcHNcbi8vIGxldCBjaXJjdWl0QnJlYWtlciA9IC01MFxuLy8gdHJhdmVyc2UgYWxsIGNoaWxkcmVuIGFuZCBjb2xsZWN0IGEgc3RyZWFtIG9mIGFsbCBzb3VyY2VzXG4vLyBBTkQgcmVuZGVyLiBhIGJpdCBvZiBkdXBsaWNhdGlvbiwgYnV0IHdlIGdldCBwZXJzaXN0ZW50IGluc3RhbmNlcyB3aGljaCBpcyBnb29kXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyU3RyZWFtKGVsZW1lbnQsIGluc3RhbmNlLCBzdGF0ZSwgc3RhdGVNYXApIHtcbiAgLy8gdGhpcyBpcyBhIHNlcGFyYXRlIGZ1bmN0aW9uIGJlY2F1c2Ugc2NvcGUgZ2V0cyBtZXNzeSB3aGVuIGJlaW5nIHJlY3Vyc2l2ZVxuICBsZXQgaXNOZXdTdHJlYW0gPSBmYWxzZSAvLyBhc3N1bWUgbm8gc3RyZWFtIHN3aXRjaGluZyBieSBkZWZhdWx0XG4gIC8vIHRoaXMgaXMgdGhlIGZpcnN0IHBpbmcgb2YgZGF0YSB0aHJvdWdob3V0IHRoZSBhcHBcbiAgbGV0IHNvdXJjZSA9IE9ic2VydmFibGUub2Yoc3RhdGUpIFxuICBjb25zdCBhZGRUb1N0cmVhbSA9IF9zb3VyY2UgPT4ge1xuICAgIC8vIHZpc2l0IGVhY2ggc291cmNlIGFuZCBtZXJnZSB3aXRoIHNvdXJjZVxuICAgIGlmIChfc291cmNlKSByZXR1cm4gc291cmNlID0gbWVyZ2Uoc291cmNlLCBfc291cmNlKVxuICB9XG4gIGNvbnN0IG1hcmtOZXdTdHJlYW0gPSAoKSA9PiBpc05ld1N0cmVhbSA9IHRydWVcbiAgY29uc3QgbmV3SW5zdGFuY2UgPSByZW5kZXIoc291cmNlLCBhZGRUb1N0cmVhbSwgbWFya05ld1N0cmVhbSkoZWxlbWVudCwgaW5zdGFuY2UsIHN0YXRlLCBzdGF0ZU1hcClcbiAgcmV0dXJuIHtzb3VyY2UsIGluc3RhbmNlOiBuZXdJbnN0YW5jZSwgaXNOZXdTdHJlYW19XG59XG5cbi8qKiBjb3JlIHJlbmRlciBsb2dpYyAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlcihzb3VyY2UsIGFkZFRvU3RyZWFtLCBtYXJrTmV3U3RyZWFtKSB7IC8vIHRoaXMgaXMgdGhlIG5vbnJlY3Vyc2l2ZSBwYXJ0XG4gIHJldHVybiBmdW5jdGlvbiByZW5kZXJXaXRoU3RyZWFtKGVsZW1lbnQsIGluc3RhbmNlLCBzdGF0ZSwgc3RhdGVNYXApIHsgLy8gcmVjdXJzaXZlIHBhcnRcbiAgICBsZXQgbmV3SW5zdGFuY2VcbiAgICBjb25zdCB7IHR5cGUsIHByb3BzIH0gPSBlbGVtZW50XG4gIFxuICAgIGNvbnN0IGlzRG9tRWxlbWVudCA9IHR5cGVvZiB0eXBlID09PSBcInN0cmluZ1wiO1xuICAgIC8vIGlmIChjaXJjdWl0QnJlYWtlcmZsYWcgJiYgY2lyY3VpdEJyZWFrZXIrKyA+IDApIGRlYnVnZ2VyXG4gICAgY29uc3Qge2NoaWxkcmVuID0gW10sIC4uLnJlc3R9ID0gcHJvcHNcbiAgICBpZiAoaXNEb21FbGVtZW50KSB7XG4gICAgICBjb25zdCBjaGlsZEluc3RhbmNlcyA9IGNoaWxkcmVuLm1hcChcbiAgICAgICAgKGVsLCBpKSA9PiB7XG4gICAgICAgICAgLy8gdWdseSBidXQgbmVjZXNzYXJ5IHRvIGFsbG93IGZ1bmN0aW9uYWwgY2hpbGRyZW5cbiAgICAgICAgICAvLyBtYXBwaW5nIGVsZW1lbnQncyBjaGlsZHJlbiB0byBpbnN0YW5jZSdzIGNoaWxkSW5zdGFuY2VzXG4gICAgICAgICAgY29uc3QgX2NoaWxkSW5zdGFuY2VzID0gaW5zdGFuY2UgJiYgKGluc3RhbmNlLmNoaWxkSW5zdGFuY2UgfHwgaW5zdGFuY2UuY2hpbGRJbnN0YW5jZXNbaV0pXG4gICAgICAgICAgcmV0dXJuIHJlbmRlcldpdGhTdHJlYW0oICAvLyByZWN1cnNpb25cbiAgICAgICAgICAgIGVsLCBcbiAgICAgICAgICAgIF9jaGlsZEluc3RhbmNlcywgXG4gICAgICAgICAgICBzdGF0ZSwgXG4gICAgICAgICAgICBzdGF0ZU1hcCkgXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICBjb25zdCBjaGlsZERvbXMgPSBjaGlsZEluc3RhbmNlcy5tYXAoY2hpbGRJbnN0YW5jZSA9PiBjaGlsZEluc3RhbmNlLmRvbSk7XG4gICAgICBsZXQgbGNhc2VQcm9wcyA9IHt9XG4gICAgICBPYmplY3QuZW50cmllcyhyZXN0KS5mb3JFYWNoKChbaywgdl0pID0+IGxjYXNlUHJvcHNbZm9ybWF0UHJvcHMoayldID0gdilcbiAgICAgIGNvbnN0IGRvbSA9IHR5cGUgPT09IFRFWFRfRUxFTUVOVFxuICAgICAgICA/IG5ldyBWVGV4dChwcm9wcy5ub2RlVmFsdWUpXG4gICAgICAgIDogaCh0eXBlLCBsY2FzZVByb3BzLCBjaGlsZERvbXMpOyAvLyBlcXVpdmFsZW50IG9mIGFwcGVuZGNoaWxkXG4gICAgICBuZXdJbnN0YW5jZSA9IHsgZG9tLCBlbGVtZW50LCBjaGlsZEluc3RhbmNlcyB9O1xuICAgIH0gZWxzZSB7IC8vIGNvbXBvbmVudCBlbGVtZW50XG4gICAgICBsZXQgcHVibGljSW5zdGFuY2UgXG4gICAgICAvLyBkZWJ1Z2dlclxuICAgICAgaWYgKGluc3RhbmNlICYmIGluc3RhbmNlLnB1YmxpY0luc3RhbmNlICYmIGluc3RhbmNlLmVsZW1lbnQgPT09IGVsZW1lbnQpIHsgLy8gbWlnaHQgaGF2ZSB0byBkbyBtb3JlIGRpZmZpbmcgb2YgcHJvcHNcbiAgICAgICAgLy8ganVzdCByZXVzZSBvbGQgaW5zdGFuY2UgaWYgaXQgYWxyZWFkeSBleGlzdHNcbiAgICAgICAgcHVibGljSW5zdGFuY2UgPSBpbnN0YW5jZSAmJiBpbnN0YW5jZS5wdWJsaWNJbnN0YW5jZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFya05ld1N0cmVhbSgpIC8vIG1hcmsgYXMgZGlydHkgaW4gcGFyZW50IHNjb3BlOyB3aWxsIHJlcmVuZGVyXG4gICAgICAgIHB1YmxpY0luc3RhbmNlID0gY3JlYXRlUHVibGljSW5zdGFuY2UoZWxlbWVudCk7XG4gICAgICB9XG4gICAgICBsZXQgbG9jYWxTdGF0ZSA9IHN0YXRlTWFwLmdldChwdWJsaWNJbnN0YW5jZSlcbiAgICAgIGlmIChsb2NhbFN0YXRlID09PSB1bmRlZmluZWQpIGxvY2FsU3RhdGUgPSBwdWJsaWNJbnN0YW5jZS5pbml0aWFsU3RhdGVcbiAgICAgIHB1YmxpY0luc3RhbmNlLnN0YXRlID0gbG9jYWxTdGF0ZSAvLyBmb3IgYWNjZXNzIHdpdGggdGhpcy5zdGF0ZVxuICAgICAgaWYgKE9iamVjdC5rZXlzKHJlc3QpLmxlbmd0aCkgcHVibGljSW5zdGFuY2UucHJvcHMgPSByZXN0IC8vIHVwZGF0ZSB3aXRoIG5ldyBwcm9wcyAvLyBUT0RPOiBwb3RlbnRpYWxseSBidWdneVxuICAgICAgLy8gY29uc29sZS5sb2coe3Jlc3R9KVxuICAgICAgaWYgKHB1YmxpY0luc3RhbmNlLnNvdXJjZSkge1xuICAgICAgICBjb25zdCBzcmMgPSBwdWJsaWNJbnN0YW5jZS5zb3VyY2Uoc291cmNlKVxuICAgICAgICAvLyB0aGVyZSBhcmUgdHdvIGZvcm1zIG9mIENvbXBvbmVudC5zb3VyY2VcbiAgICAgICAgY29uc3Qgc3JjJCA9IHNyYy5yZWR1Y2VyICYmIHB1YmxpY0luc3RhbmNlLmluaXRpYWxTdGF0ZSAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgICAgICAvLyAxLiB0aGUgcmVkdWNlciBmb3JtXG4gICAgICAgICAgICBzY2FuKHNyYy5zb3VyY2UsIHNyYy5yZWR1Y2VyLCBwdWJsaWNJbnN0YW5jZS5pbml0aWFsU3RhdGUpIDogXG4gICAgICAgICAgICAvLyAyLiBhbmQgcmF3IHN0cmVhbSBmb3JtXG4gICAgICAgICAgICBzcmNcbiAgICAgICAgYWRkVG9TdHJlYW0oc3JjJFxuICAgICAgICAgIC5tYXAoZXZlbnQgPT4ge1xuICAgICAgICAgICAgc3RhdGVNYXAuc2V0KHB1YmxpY0luc3RhbmNlLCBldmVudClcbiAgICAgICAgICAgIHJldHVybiB7aW5zdGFuY2U6IHB1YmxpY0luc3RhbmNlLCBldmVudH0gLy8gdGFnIGl0IHRvIHRoZSBpbnN0YW5jZVxuICAgICAgICAgIH0pIFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29uc3QgY2hpbGRFbGVtZW50ID0gcHVibGljSW5zdGFuY2UucmVuZGVyID8gXG4gICAgICAgICAgcHVibGljSW5zdGFuY2UucmVuZGVyKGxvY2FsU3RhdGUsIHN0YXRlTWFwKSA6IFxuICAgICAgICAgIHB1YmxpY0luc3RhbmNlO1xuXG4gICAgICBjb25zdCBjaGlsZEluc3RhbmNlID0gcmVuZGVyV2l0aFN0cmVhbShjaGlsZEVsZW1lbnQsIGluc3RhbmNlICYmIGluc3RhbmNlLmNoaWxkSW5zdGFuY2UsIHN0YXRlLCBzdGF0ZU1hcClcbiAgICAgIGNvbnN0IGRvbSA9IGNoaWxkSW5zdGFuY2UuZG9tXG4gICAgICBuZXdJbnN0YW5jZSA9IHsgZG9tLCBlbGVtZW50LCBjaGlsZEluc3RhbmNlLCBwdWJsaWNJbnN0YW5jZSB9XG4gICAgfVxuICAgIHJldHVybiBuZXdJbnN0YW5jZVxuICB9XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BzKGspIHtcbiAgaWYgKGsuc3RhcnRzV2l0aCgnb24nKSkgcmV0dXJuIGsudG9Mb3dlckNhc2UoKVxuICByZXR1cm4ga1xufSIsImltcG9ydCBPYnNlcnZhYmxlIGZyb20gJ3plbi1vYnNlcnZhYmxlJ1xuaW1wb3J0IHtmcm9tRXZlbnQsIHNjYW4sIG1lcmdlLCBzdGFydFdpdGgsIHN3aXRjaExhdGVzdH0gZnJvbSAnLi9zd3l4anMnXG5pbXBvcnQgZGlmZiBmcm9tICd2aXJ0dWFsLWRvbS9kaWZmJztcbmltcG9ydCBwYXRjaCBmcm9tICd2aXJ0dWFsLWRvbS9wYXRjaCc7XG5pbXBvcnQgY3JlYXRlRWxlbWVudCBmcm9tICd2aXJ0dWFsLWRvbS9jcmVhdGUtZWxlbWVudCc7XG5pbXBvcnQgeyBjcmVhdGVDaGFuZ2VFbWl0dGVyIH0gZnJvbSAnY2hhbmdlLWVtaXR0ZXInXG5pbXBvcnQgeyByZW5kZXJTdHJlYW0gfSBmcm9tICcuL3JlY29uY2lsZXInXG5cbmV4cG9ydCBjb25zdCBzdGF0ZU1hcFBvaW50ZXIgPSBuZXcgTWFwKClcblxubGV0IGNpcmN1aXRCcmVha2VyID0gLTIwXG5cbmNvbnN0IGVtaXR0ZXIgPSBjcmVhdGVDaGFuZ2VFbWl0dGVyKClcbi8vIHNpbmdsZSBVSSB0aHJlYWQ7IHRoaXMgaXMgdGhlIG9ic2VydmFibGUgdGhhdCBzdGlja3MgYXJvdW5kIGFuZCBzd2FwcyBvdXQgc291cmNlXG5jb25zdCBVSXRocmVhZCA9IG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgZW1pdHRlci5saXN0ZW4oeCA9PiB7XG4gICAgLy8gZGVidWdnZXIgLy8gc3VjY2VzcyEgdGhyZWFkIHN3aXRjaGluZyFcbiAgICBvYnNlcnZlci5uZXh0KHgpXG4gIH0pXG59KVxuLy8gbW91bnQgdGhlIHZkb20gb24gdG8gdGhlIGRvbSBhbmQgXG4vLyBzZXQgdXAgdGhlIHJ1bnRpbWUgZnJvbSBzb3VyY2VzIGFuZFxuLy8gcGF0Y2ggdGhlIHZkb21cbi8vIC0tLVxuLy8gcmV0dXJucyBhbiB1bnN1YnNjcmliZSBtZXRob2QgeW91IGNhbiB1c2UgdG8gdW5tb3VudFxuZXhwb3J0IGZ1bmN0aW9uIG1vdW50KHJvb3RFbGVtZW50LCBjb250YWluZXIpIHtcbiAgLy8gaW5pdGlhbCwgdGhyb3dhd2F5LWlzaCBmcmFtZVxuICBsZXQge3NvdXJjZSwgaW5zdGFuY2V9ID0gcmVuZGVyU3RyZWFtKHJvb3RFbGVtZW50LCB7fSwgdW5kZWZpbmVkLCBzdGF0ZU1hcFBvaW50ZXIpXG4gIGxldCBpbnN0YW5jZVBvaW50ZXIgPSBpbnN0YW5jZVxuICBjb25zdCByb290Tm9kZSA9IGNyZWF0ZUVsZW1lbnQoaW5zdGFuY2UuZG9tKVxuICBjb25zdCBjb250YWluZXJDaGlsZCA9IGNvbnRhaW5lci5maXJzdEVsZW1lbnRDaGlsZFxuICBpZiAoY29udGFpbmVyQ2hpbGQpIHtcbiAgICBjb250YWluZXIucmVwbGFjZUNoaWxkKHJvb3ROb2RlLGNvbnRhaW5lckNoaWxkKSAvLyBob3QgcmVsb2FkZWQgbW91bnRcbiAgfSBlbHNlIHtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQocm9vdE5vZGUpIC8vIGluaXRpYWwgbW91bnRcbiAgfVxuICBsZXQgY3VycmVudFNyYyQgPSBudWxsXG4gIGxldCBTb1MgPSBzdGFydFdpdGgoVUl0aHJlYWQsIHNvdXJjZSkgLy8gc3RyZWFtIG9mIHN0cmVhbXNcbiAgcmV0dXJuIFNvUy5zdWJzY3JpYmUoXG4gICAgc3JjJCA9PiB7IC8vIHRoaXMgaXMgdGhlIGN1cnJlbnQgc291cmNlU3RyZWFtIHdlIGFyZSB3b3JraW5nIHdpdGhcbiAgICAgIGlmIChjdXJyZW50U3JjJCkgY29uc29sZS5sb2coJ3Vuc3ViIScpIHx8IGN1cnJlbnRTcmMkLnVuc3Vic2NyaWJlKCkgLy8gdW5zdWIgZnJvbSBvbGQgc3RyZWFtXG4gICAgICAvKioqKiBtYWluICovXG4gICAgICBjb25zdCBzb3VyY2UyJCA9IHNjYW4oXG4gICAgICAgIHNyYyQsIFxuICAgICAgICAoe2luc3RhbmNlLCBzdGF0ZU1hcH0sIG5leHRTdGF0ZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHN0cmVhbU91dHB1dCA9IHJlbmRlclN0cmVhbShyb290RWxlbWVudCwgaW5zdGFuY2UsIG5leHRTdGF0ZSwgc3RhdGVNYXApXG4gICAgICAgICAgaWYgKHN0cmVhbU91dHB1dC5pc05ld1N0cmVhbSkgeyAvLyBxdWljayBjaGVja1xuICAgICAgICAgICAgY29uc3QgbmV4dFNvdXJjZSQgPSBzdHJlYW1PdXRwdXQuc291cmNlXG4gICAgICAgICAgICAvLyBkZWJ1Z2dlclxuICAgICAgICAgICAgaW5zdGFuY2VQb2ludGVyID0gc3RyZWFtT3V0cHV0Lmluc3RhbmNlXG4gICAgICAgICAgICBwYXRjaChyb290Tm9kZSwgZGlmZihpbnN0YW5jZS5kb20sIGluc3RhbmNlUG9pbnRlci5kb20pKSAvLyByZW5kZXIgdG8gc2NyZWVuXG4gICAgICAgICAgICBlbWl0dGVyLmVtaXQobmV4dFNvdXJjZSQpIC8vIHVwZGF0ZSB0aGUgVUkgdGhyZWFkOyBzb3VyY2Ugd2lsbCBzd2l0Y2hcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbmV4dGluc3RhbmNlID0gc3RyZWFtT3V0cHV0Lmluc3RhbmNlXG4gICAgICAgICAgICBwYXRjaChyb290Tm9kZSwgZGlmZihpbnN0YW5jZS5kb20sIG5leHRpbnN0YW5jZS5kb20pKSAvLyByZW5kZXIgdG8gc2NyZWVuXG4gICAgICAgICAgICByZXR1cm4ge2luc3RhbmNlOiBuZXh0aW5zdGFuY2UsIHN0YXRlTWFwOiBzdGF0ZU1hcH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtpbnN0YW5jZTogaW5zdGFuY2VQb2ludGVyLCBzdGF0ZU1hcDogc3RhdGVNYXBQb2ludGVyfSAvLyBhY2N1bXVsYXRvclxuICAgICAgKVxuICAgICAgLyoqKiogZW5kIG1haW4gKi9cbiAgICAgIGN1cnJlbnRTcmMkID0gXG4gICAgICAgIHNvdXJjZTIkXG4gICAgICAgICAgLnN1YnNjcmliZSgpXG4gICAgfVxuICApXG59XG4iLCJpbXBvcnQgeyBjcmVhdGVFbGVtZW50LCBjcmVhdGVIYW5kbGVyIH0gZnJvbSBcIi4vZWxlbWVudFwiO1xuaW1wb3J0IHsgQ29tcG9uZW50IH0gZnJvbSBcIi4vY29tcG9uZW50XCI7XG5pbXBvcnQgeyByZW5kZXJTdHJlYW0gfSBmcm9tIFwiLi9yZWNvbmNpbGVyXCJcbmltcG9ydCB7IG1vdW50IH0gZnJvbSBcIi4vc2NoZWR1bGVyXCI7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgcmVuZGVyU3RyZWFtLFxuICBjcmVhdGVFbGVtZW50LFxuICBjcmVhdGVIYW5kbGVyLFxuICBDb21wb25lbnQsXG4gIG1vdW50XG59O1xuXG5leHBvcnQgeyBjcmVhdGVFbGVtZW50LCBjcmVhdGVIYW5kbGVyLCBDb21wb25lbnQsIFxuICByZW5kZXJTdHJlYW0sIFxuICBtb3VudCB9O1xuIl0sIm5hbWVzIjpbIlRFWFRfRUxFTUVOVCIsImNyZWF0ZUVsZW1lbnQiLCJ0eXBlIiwiY29uZmlnIiwicHJvcHMiLCJPYmplY3QiLCJhc3NpZ24iLCJhcmdzIiwiaGFzQ2hpbGRyZW4iLCJsZW5ndGgiLCJyYXdDaGlsZHJlbiIsImNvbmNhdCIsImNoaWxkcmVuIiwiZmlsdGVyIiwiYyIsIm1hcCIsImNyZWF0ZVRleHRFbGVtZW50IiwidmFsdWUiLCJub2RlVmFsdWUiLCJjcmVhdGVIYW5kbGVyIiwiX2ZuIiwiZW1pdHRlciIsImNyZWF0ZUNoYW5nZUVtaXR0ZXIiLCJoYW5kbGVyIiwiZW1pdCIsIngiLCIkIiwiT2JzZXJ2YWJsZSIsImxpc3RlbiIsIm5leHQiLCJOT0lOSVQiLCJTeW1ib2wiLCJzY2FuIiwib2JzIiwiY2IiLCJzZWVkIiwic3ViIiwiYWNjIiwiaGFzVmFsdWUiLCJoYXNTZWVkIiwic3Vic2NyaWJlIiwib2JzZXJ2ZXIiLCJjbG9zZWQiLCJmaXJzdCIsImUiLCJlcnJvciIsInN0YXJ0V2l0aCIsInZhbCIsIkNvbXBvbmVudCIsInN0YXRlIiwib2JqIiwic291cmNlcyIsImVudHJpZXMiLCJrIiwiZm4iLCJzdWJSZWR1Y2VyIiwic291cmNlIiwicmVkdWNlciIsIl8iLCJuIiwiaW5pdGlhbFN0YXRlIiwibWVyZ2UiLCJjcmVhdGVQdWJsaWNJbnN0YW5jZSIsImVsZW1lbnQiLCJwdWJsaWNJbnN0YW5jZSIsInJlbmRlclN0cmVhbSIsImluc3RhbmNlIiwic3RhdGVNYXAiLCJpc05ld1N0cmVhbSIsIm9mIiwiYWRkVG9TdHJlYW0iLCJfc291cmNlIiwibWFya05ld1N0cmVhbSIsIm5ld0luc3RhbmNlIiwicmVuZGVyIiwicmVuZGVyV2l0aFN0cmVhbSIsImlzRG9tRWxlbWVudCIsInJlc3QiLCJjaGlsZEluc3RhbmNlcyIsImVsIiwiaSIsIl9jaGlsZEluc3RhbmNlcyIsImNoaWxkSW5zdGFuY2UiLCJjaGlsZERvbXMiLCJkb20iLCJsY2FzZVByb3BzIiwiZm9yRWFjaCIsInYiLCJmb3JtYXRQcm9wcyIsIlZUZXh0IiwiaCIsImxvY2FsU3RhdGUiLCJnZXQiLCJ1bmRlZmluZWQiLCJrZXlzIiwic3JjIiwic3JjJCIsInNldCIsImV2ZW50IiwiY2hpbGRFbGVtZW50Iiwic3RhcnRzV2l0aCIsInRvTG93ZXJDYXNlIiwic3RhdGVNYXBQb2ludGVyIiwiTWFwIiwiVUl0aHJlYWQiLCJtb3VudCIsInJvb3RFbGVtZW50IiwiY29udGFpbmVyIiwiaW5zdGFuY2VQb2ludGVyIiwicm9vdE5vZGUiLCJjb250YWluZXJDaGlsZCIsImZpcnN0RWxlbWVudENoaWxkIiwicmVwbGFjZUNoaWxkIiwiYXBwZW5kQ2hpbGQiLCJjdXJyZW50U3JjJCIsIlNvUyIsImNvbnNvbGUiLCJsb2ciLCJ1bnN1YnNjcmliZSIsInNvdXJjZTIkIiwibmV4dFN0YXRlIiwic3RyZWFtT3V0cHV0IiwibmV4dFNvdXJjZSQiLCJkaWZmIiwibmV4dGluc3RhbmNlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFHTyxJQUFNQSxlQUFlLGNBQXJCOztBQUVQLEFBQU8sU0FBU0MsZUFBVCxDQUF1QkMsSUFBdkIsRUFBNkJDLE1BQTdCLEVBQThDOzs7TUFDN0NDLFFBQVFDLE9BQU9DLE1BQVAsQ0FBYyxFQUFkLEVBQWtCSCxNQUFsQixDQUFkOztvQ0FENkNJLElBQU07UUFBQTs7O01BRTdDQyxjQUFjRCxLQUFLRSxNQUFMLEdBQWMsQ0FBbEM7TUFDTUMsY0FBY0YsY0FBYyxZQUFHRyxNQUFILGFBQWFKLElBQWIsQ0FBZCxHQUFtQyxFQUF2RDtRQUNNSyxRQUFOLEdBQWlCRixZQUNkRyxNQURjLENBQ1A7V0FBS0MsS0FBSyxJQUFMLElBQWFBLE1BQU0sS0FBeEI7R0FETyxFQUVkQyxHQUZjLENBRVY7V0FBS0QsYUFBYVQsTUFBYixHQUFzQlMsQ0FBdEIsR0FBMEJFLGtCQUFrQkYsQ0FBbEIsQ0FBL0I7R0FGVSxDQUFqQjtTQUdPLEVBQUVaLFVBQUYsRUFBUUUsWUFBUixFQUFQOzs7QUFHRixTQUFTWSxpQkFBVCxDQUEyQkMsS0FBM0IsRUFBa0M7U0FDekJoQixnQkFBY0QsWUFBZCxFQUE0QixFQUFFa0IsV0FBV0QsS0FBYixFQUE1QixDQUFQOzs7QUFHRixBQUFPLFNBQVNFLGFBQVQsQ0FBdUJDLEdBQXZCLEVBQTRCO01BQzNCQyxVQUFVQyxxQkFBaEI7TUFDSUMsVUFBVSxTQUFWQSxPQUFVLElBQUs7WUFDVEMsSUFBUixDQUFhQyxDQUFiO0dBREY7VUFHUUMsQ0FBUixHQUFZLElBQUlDLFVBQUosQ0FBZSxvQkFBWTtXQUM5Qk4sUUFBUU8sTUFBUixDQUFlLGlCQUFTO2VBQ3BCQyxJQUFULENBQWNULE1BQU1BLElBQUlILEtBQUosQ0FBTixHQUFtQkEsS0FBakM7S0FESyxDQUFQO0dBRFUsQ0FBWjtTQU1PTSxPQUFQOzs7QUNGRixJQUFNTyxTQUFTQyxPQUFPLGtCQUFQLENBQWY7QUFDQSxBQUFPLFNBQVNDLElBQVQsQ0FBY0MsR0FBZCxFQUFtQkMsRUFBbkIsRUFBc0M7TUFBZkMsSUFBZSx1RUFBUkwsTUFBUTs7TUFDdkNNLFlBQUo7TUFBU0MsTUFBTUYsSUFBZjtNQUFxQkcsV0FBVyxLQUFoQztNQUNNQyxVQUFVRixRQUFRUCxNQUF4QjtTQUNPLElBQUlILFVBQUosQ0FBZSxvQkFBWTtVQUMxQk0sSUFBSU8sU0FBSixDQUFjLGlCQUFTO1VBQ3ZCQyxTQUFTQyxNQUFiLEVBQXFCO1VBQ2pCQyxRQUFRLENBQUNMLFFBQWI7aUJBQ1csSUFBWDtVQUNJLENBQUNLLEtBQUQsSUFBVUosT0FBZCxFQUF3QjtZQUNsQjtnQkFBUUwsR0FBR0csR0FBSCxFQUFRcEIsS0FBUixDQUFOO1NBQU4sQ0FDQSxPQUFPMkIsQ0FBUCxFQUFVO2lCQUFTSCxTQUFTSSxLQUFULENBQWVELENBQWYsQ0FBUDs7aUJBQ0hmLElBQVQsQ0FBY1EsR0FBZDtPQUhGLE1BS0s7Y0FDR3BCLEtBQU47O0tBVkUsQ0FBTjtXQWFPbUIsR0FBUDtHQWRLLENBQVA7Ozs7QUFtQkYsQUFBTzs7QUFtQlAsQUFBTzs7QUFPUCxBQUFPLFNBQVNVLFNBQVQsQ0FBbUJiLEdBQW5CLEVBQXdCYyxHQUF4QixFQUE2QjtTQUMzQixJQUFJcEIsVUFBSixDQUFlLG9CQUFZO2FBQ3ZCRSxJQUFULENBQWNrQixHQUFkLEVBRGdDO1FBRTFCeEIsVUFBVVUsSUFBSU8sU0FBSixDQUFjO2FBQUtDLFNBQVNaLElBQVQsQ0FBY0osQ0FBZCxDQUFMO0tBQWQsQ0FBaEI7V0FDTzthQUFNRixTQUFOO0tBQVA7R0FISyxDQUFQOzs7Ozs7Ozs7Ozs7Ozs7O0FDN0VGLEFBRUEsSUFBYXlCLFNBQWI7cUJBQ2M1QyxLQUFaLEVBQW1COzs7U0FDWkEsS0FBTCxHQUFhQSxLQUFiO1NBQ0s2QyxLQUFMLEdBQWEsS0FBS0EsS0FBTCxJQUFjLEVBQTNCOzs7Ozs7Ozs7Ozs7O21DQVNhQyxHQVpqQixFQVlzQjs7O1VBQ1pDLFVBQVU5QyxPQUFPK0MsT0FBUCxDQUFlRixHQUFmLEVBQW9CbkMsR0FBcEIsQ0FBd0IsZ0JBQVk7O1lBQVZzQyxDQUFVO1lBQVJDLEVBQVE7O1lBQzlDQyxhQUFhRCxHQUFHSixHQUFILENBQWpCOzs7O1lBSUlLLFdBQVdDLE1BQVgsSUFBcUJELFdBQVdFLE9BQXBDLEVBQTZDOzt1QkFDOUJ6QixLQUFLdUIsV0FBV0MsTUFBaEIsRUFDWEQsV0FBV0UsT0FBWCxJQUF1QixVQUFDQyxDQUFELEVBQUlDLENBQUo7bUJBQVVBLENBQVY7V0FEWixFQUVYLE1BQUtDLFlBQUwsQ0FBa0JQLENBQWxCLENBRlcsQ0FBYjs7ZUFLS0UsV0FDSnhDLEdBREksQ0FDQTtxQ0FBUXNDLENBQVIsRUFBWTVCLENBQVo7U0FEQSxDQUFQLENBWGtEO09BQXBDLENBQWhCO1VBY00rQixTQUFTSywwQ0FBU1YsT0FBVCxFQUFmO1VBQ01NLFVBQVUsU0FBVkEsT0FBVSxDQUFDcEIsR0FBRCxFQUFNc0IsQ0FBTjs0QkFBaUJ0QixHQUFqQixFQUF5QnNCLENBQXpCO09BQWhCO2FBQ08sRUFBQ0gsY0FBRCxFQUFTQyxnQkFBVCxFQUFQOzs7Ozs7Ozs7Ozs7O0FBVUosQUFBTyxTQUFTSyxvQkFBVCxDQUE4QkMsT0FBOUIseUJBQTZEO01BQzFEN0QsSUFEMEQsR0FDMUM2RCxPQUQwQyxDQUMxRDdELElBRDBEO01BQ3BERSxLQURvRCxHQUMxQzJELE9BRDBDLENBQ3BEM0QsS0FEb0Q7O01BRTVENEQsaUJBQWlCLElBQUk5RCxJQUFKLENBQVNFLEtBQVQsQ0FBdkI7O1NBRU80RCxjQUFQOzs7Ozs7O0FDOUNGLEFBQ0EsQUFDQTtBQUNBLEFBQ0EsQUFDQSxBQUNBO0FBQ0EsQUFFQTs7OztBQUlBLEFBQU8sU0FBU0MsWUFBVCxDQUFzQkYsT0FBdEIsRUFBK0JHLFFBQS9CLEVBQXlDakIsS0FBekMsRUFBZ0RrQixRQUFoRCxFQUEwRDs7TUFFM0RDLGNBQWMsS0FBbEIsQ0FGK0Q7O01BSTNEWixTQUFTN0IsV0FBVzBDLEVBQVgsQ0FBY3BCLEtBQWQsQ0FBYjtNQUNNcUIsY0FBYyxTQUFkQSxXQUFjLFVBQVc7O1FBRXpCQyxPQUFKLEVBQWEsT0FBT2YsU0FBU0ssTUFBTUwsTUFBTixFQUFjZSxPQUFkLENBQWhCO0dBRmY7TUFJTUMsZ0JBQWdCLFNBQWhCQSxhQUFnQjtXQUFNSixjQUFjLElBQXBCO0dBQXRCO01BQ01LLGNBQWNDLE9BQU9sQixNQUFQLEVBQWVjLFdBQWYsRUFBNEJFLGFBQTVCLEVBQTJDVCxPQUEzQyxFQUFvREcsUUFBcEQsRUFBOERqQixLQUE5RCxFQUFxRWtCLFFBQXJFLENBQXBCO1NBQ08sRUFBQ1gsY0FBRCxFQUFTVSxVQUFVTyxXQUFuQixFQUFnQ0wsd0JBQWhDLEVBQVA7Ozs7QUFJRixBQUFPLFNBQVNNLE1BQVQsQ0FBZ0JsQixNQUFoQixFQUF3QmMsV0FBeEIsRUFBcUNFLGFBQXJDLEVBQW9EOztTQUNsRCxTQUFTRyxnQkFBVCxDQUEwQlosT0FBMUIsRUFBbUNHLFFBQW5DLEVBQTZDakIsS0FBN0MsRUFBb0RrQixRQUFwRCxFQUE4RDs7UUFDL0RNLG9CQUFKO1FBQ1F2RSxJQUYyRCxHQUUzQzZELE9BRjJDLENBRTNEN0QsSUFGMkQ7UUFFckRFLEtBRnFELEdBRTNDMkQsT0FGMkMsQ0FFckQzRCxLQUZxRDs7O1FBSTdEd0UsZUFBZSxPQUFPMUUsSUFBUCxLQUFnQixRQUFyQzs7OzBCQUVpQ0UsS0FOa0MsQ0FNNURRLFFBTjREO1FBTTVEQSxRQU40RCxtQ0FNakQsRUFOaUQ7UUFNMUNpRSxJQU4wQyw0QkFNbEN6RSxLQU5rQzs7UUFPL0R3RSxZQUFKLEVBQWtCO1VBQ1ZFLGlCQUFpQmxFLFNBQVNHLEdBQVQsQ0FDckIsVUFBQ2dFLEVBQUQsRUFBS0MsQ0FBTCxFQUFXOzs7WUFHSEMsa0JBQWtCZixhQUFhQSxTQUFTZ0IsYUFBVCxJQUEwQmhCLFNBQVNZLGNBQVQsQ0FBd0JFLENBQXhCLENBQXZDLENBQXhCO2VBQ09MO1VBQUEsRUFFTE0sZUFGSyxFQUdMaEMsS0FISyxFQUlMa0IsUUFKSyxDQUFQO09BTG1CLENBQXZCO1VBWU1nQixZQUFZTCxlQUFlL0QsR0FBZixDQUFtQjtlQUFpQm1FLGNBQWNFLEdBQS9CO09BQW5CLENBQWxCO1VBQ0lDLGFBQWEsRUFBakI7YUFDT2pDLE9BQVAsQ0FBZXlCLElBQWYsRUFBcUJTLE9BQXJCLENBQTZCOztZQUFFakMsQ0FBRjtZQUFLa0MsQ0FBTDs7ZUFBWUYsV0FBV0csWUFBWW5DLENBQVosQ0FBWCxJQUE2QmtDLENBQXpDO09BQTdCO1VBQ01ILE1BQU1sRixTQUFTRixZQUFULEdBQ1IsSUFBSXlGLEtBQUosQ0FBVXJGLE1BQU1jLFNBQWhCLENBRFEsR0FFUndFLEVBQUV4RixJQUFGLEVBQVFtRixVQUFSLEVBQW9CRixTQUFwQixDQUZKLENBaEJnQjtvQkFtQkYsRUFBRUMsUUFBRixFQUFPckIsZ0JBQVAsRUFBZ0JlLDhCQUFoQixFQUFkO0tBbkJGLE1Bb0JPOztVQUNEZCx1QkFBSjs7VUFFSUUsWUFBWUEsU0FBU0YsY0FBckIsSUFBdUNFLFNBQVNILE9BQVQsS0FBcUJBLE9BQWhFLEVBQXlFOzs7eUJBRXRERyxZQUFZQSxTQUFTRixjQUF0QztPQUZGLE1BR087d0JBQUE7eUJBRVlGLHFCQUFxQkMsT0FBckIsQ0FBakI7O1VBRUU0QixhQUFheEIsU0FBU3lCLEdBQVQsQ0FBYTVCLGNBQWIsQ0FBakI7VUFDSTJCLGVBQWVFLFNBQW5CLEVBQThCRixhQUFhM0IsZUFBZUosWUFBNUI7cUJBQ2ZYLEtBQWYsR0FBdUIwQyxVQUF2QixDQVpLO1VBYUR0RixPQUFPeUYsSUFBUCxDQUFZakIsSUFBWixFQUFrQnBFLE1BQXRCLEVBQThCdUQsZUFBZTVELEtBQWYsR0FBdUJ5RSxJQUF2QixDQWJ6Qjs7VUFlRGIsZUFBZVIsTUFBbkIsRUFBMkI7WUFDbkJ1QyxNQUFNL0IsZUFBZVIsTUFBZixDQUFzQkEsTUFBdEIsQ0FBWjs7WUFFTXdDLE9BQU9ELElBQUl0QyxPQUFKLElBQWVPLGVBQWVKLFlBQWYsS0FBZ0NpQyxTQUEvQzs7YUFFSkUsSUFBSXZDLE1BQVQsRUFBaUJ1QyxJQUFJdEMsT0FBckIsRUFBOEJPLGVBQWVKLFlBQTdDLENBRlM7O1dBQWI7b0JBS1lvQyxLQUNUakYsR0FEUyxDQUNMLGlCQUFTO21CQUNIa0YsR0FBVCxDQUFhakMsY0FBYixFQUE2QmtDLEtBQTdCO2lCQUNPLEVBQUNoQyxVQUFVRixjQUFYLEVBQTJCa0MsWUFBM0I7V0FBUDtTQUhRLENBQVo7O1VBT0lDLGVBQWVuQyxlQUFlVSxNQUFmLEdBQ2pCVixlQUFlVSxNQUFmLENBQXNCaUIsVUFBdEIsRUFBa0N4QixRQUFsQyxDQURpQixHQUVqQkgsY0FGSjs7VUFJTWtCLGdCQUFnQlAsaUJBQWlCd0IsWUFBakIsRUFBK0JqQyxZQUFZQSxTQUFTZ0IsYUFBcEQsRUFBbUVqQyxLQUFuRSxFQUEwRWtCLFFBQTFFLENBQXRCO1VBQ01pQixPQUFNRixjQUFjRSxHQUExQjtvQkFDYyxFQUFFQSxTQUFGLEVBQU9yQixnQkFBUCxFQUFnQm1CLDRCQUFoQixFQUErQmxCLDhCQUEvQixFQUFkOztXQUVLUyxXQUFQO0dBakVGOzs7QUFxRUYsU0FBU2UsV0FBVCxDQUFxQm5DLENBQXJCLEVBQXdCO01BQ2xCQSxFQUFFK0MsVUFBRixDQUFhLElBQWIsQ0FBSixFQUF3QixPQUFPL0MsRUFBRWdELFdBQUYsRUFBUDtTQUNqQmhELENBQVA7OztBQzVGSyxJQUFNaUQsa0JBQWtCLElBQUlDLEdBQUosRUFBeEI7O0FBRVAsQUFFQSxJQUFNbEYsVUFBVUMscUJBQWhCOztBQUVBLElBQU1rRixXQUFXLElBQUk3RSxVQUFKLENBQWUsb0JBQVk7VUFDbENDLE1BQVIsQ0FBZSxhQUFLOzthQUVUQyxJQUFULENBQWNKLENBQWQ7R0FGRjtDQURlLENBQWpCOzs7Ozs7QUFXQSxBQUFPLFNBQVNnRixLQUFULENBQWVDLFdBQWYsRUFBNEJDLFNBQTVCLEVBQXVDOztzQkFFbkIxQyxhQUFheUMsV0FBYixFQUEwQixFQUExQixFQUE4QmIsU0FBOUIsRUFBeUNTLGVBQXpDLENBRm1CO01BRXZDOUMsTUFGdUMsaUJBRXZDQSxNQUZ1QztNQUUvQlUsUUFGK0IsaUJBRS9CQSxRQUYrQjs7TUFHeEMwQyxrQkFBa0IxQyxRQUF0QjtNQUNNMkMsV0FBVzVHLGNBQWNpRSxTQUFTa0IsR0FBdkIsQ0FBakI7TUFDTTBCLGlCQUFpQkgsVUFBVUksaUJBQWpDO01BQ0lELGNBQUosRUFBb0I7Y0FDUkUsWUFBVixDQUF1QkgsUUFBdkIsRUFBZ0NDLGNBQWhDLEVBRGtCO0dBQXBCLE1BRU87Y0FDS0csV0FBVixDQUFzQkosUUFBdEIsRUFESzs7TUFHSEssY0FBYyxJQUFsQjtNQUNJQyxNQUFNckUsVUFBVTBELFFBQVYsRUFBb0JoRCxNQUFwQixDQUFWLENBWjRDO1NBYXJDMkQsSUFBSTNFLFNBQUosQ0FDTCxnQkFBUTs7UUFDRjBFLFdBQUosRUFBaUJFLFFBQVFDLEdBQVIsQ0FBWSxRQUFaLEtBQXlCSCxZQUFZSSxXQUFaLEVBQXpCLENBRFg7O1FBR0FDLFdBQVd2RixLQUNmZ0UsSUFEZSxFQUVmLGdCQUF1QndCLFNBQXZCLEVBQXFDO1VBQW5DdEQsUUFBbUMsUUFBbkNBLFFBQW1DO1VBQXpCQyxRQUF5QixRQUF6QkEsUUFBeUI7O1VBQzdCc0QsZUFBZXhELGFBQWF5QyxXQUFiLEVBQTBCeEMsUUFBMUIsRUFBb0NzRCxTQUFwQyxFQUErQ3JELFFBQS9DLENBQXJCO1VBQ0lzRCxhQUFhckQsV0FBakIsRUFBOEI7O1lBQ3RCc0QsY0FBY0QsYUFBYWpFLE1BQWpDOzswQkFFa0JpRSxhQUFhdkQsUUFBL0I7Y0FDTTJDLFFBQU4sRUFBZ0JjLEtBQUt6RCxTQUFTa0IsR0FBZCxFQUFtQndCLGdCQUFnQnhCLEdBQW5DLENBQWhCLEVBSjRCO2dCQUtwQjVELElBQVIsQ0FBYWtHLFdBQWIsRUFMNEI7T0FBOUIsTUFNTztZQUNDRSxlQUFlSCxhQUFhdkQsUUFBbEM7Y0FDTTJDLFFBQU4sRUFBZ0JjLEtBQUt6RCxTQUFTa0IsR0FBZCxFQUFtQndDLGFBQWF4QyxHQUFoQyxDQUFoQixFQUZLO2VBR0UsRUFBQ2xCLFVBQVUwRCxZQUFYLEVBQXlCekQsVUFBVUEsUUFBbkMsRUFBUDs7S0FiVyxFQWdCZixFQUFDRCxVQUFVMEMsZUFBWCxFQUE0QnpDLFVBQVVtQyxlQUF0QztLQWhCZSxDQUFqQjs7a0JBb0JFaUIsU0FDRy9FLFNBREgsRUFERjtHQXZCRyxDQUFQOzs7QUNqQ0YsWUFBZTs0QkFBQTtnQ0FBQTs4QkFBQTtzQkFBQTs7Q0FBZixDQVFBOzsifQ==
351 |
--------------------------------------------------------------------------------
/build/reactive-react.umd.js:
--------------------------------------------------------------------------------
1 | (function (global, factory) {
2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('zen-observable'), require('change-emitter'), require('zen-observable/extras'), require('virtual-dom/h'), require('virtual-dom/vnode/vtext'), require('virtual-dom/diff'), require('virtual-dom/patch'), require('virtual-dom/create-element')) :
3 | typeof define === 'function' && define.amd ? define(['exports', 'zen-observable', 'change-emitter', 'zen-observable/extras', 'virtual-dom/h', 'virtual-dom/vnode/vtext', 'virtual-dom/diff', 'virtual-dom/patch', 'virtual-dom/create-element'], factory) :
4 | (factory((global['reactive-react'] = global['reactive-react'] || {}),global.Observable,global.changeEmitter,global.zenObservable_extras,global.h,global.VText,global.diff,global.patch,global.createElement));
5 | }(this, (function (exports,Observable,changeEmitter,zenObservable_extras,h,VText,diff,patch,createElement) { 'use strict';
6 |
7 | Observable = 'default' in Observable ? Observable['default'] : Observable;
8 | h = 'default' in h ? h['default'] : h;
9 | VText = 'default' in VText ? VText['default'] : VText;
10 | diff = 'default' in diff ? diff['default'] : diff;
11 | patch = 'default' in patch ? patch['default'] : patch;
12 | createElement = 'default' in createElement ? createElement['default'] : createElement;
13 |
14 | var TEXT_ELEMENT = "TEXT ELEMENT";
15 |
16 | function createElement$1(type, config) {
17 | var _ref;
18 |
19 | var props = Object.assign({}, config);
20 |
21 | for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
22 | args[_key - 2] = arguments[_key];
23 | }
24 |
25 | var hasChildren = args.length > 0;
26 | var rawChildren = hasChildren ? (_ref = []).concat.apply(_ref, args) : [];
27 | props.children = rawChildren.filter(function (c) {
28 | return c != null && c !== false;
29 | }).map(function (c) {
30 | return c instanceof Object ? c : createTextElement(c);
31 | });
32 | return { type: type, props: props };
33 | }
34 |
35 | function createTextElement(value) {
36 | return createElement$1(TEXT_ELEMENT, { nodeValue: value });
37 | }
38 |
39 | function createHandler(_fn) {
40 | var emitter = changeEmitter.createChangeEmitter();
41 | var handler = function handler(x) {
42 | emitter.emit(x);
43 | };
44 | handler.$ = new Observable(function (observer) {
45 | return emitter.listen(function (value) {
46 | observer.next(_fn ? _fn(value) : value);
47 | });
48 | });
49 | return handler;
50 | }
51 |
52 | var NOINIT = Symbol('NO_INITIAL_VALUE');
53 | function scan(obs, cb) {
54 | var seed = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : NOINIT;
55 |
56 | var sub = void 0,
57 | acc = seed,
58 | hasValue = false;
59 | var hasSeed = acc !== NOINIT;
60 | return new Observable(function (observer) {
61 | sub = obs.subscribe(function (value) {
62 | if (observer.closed) return;
63 | var first = !hasValue;
64 | hasValue = true;
65 | if (!first || hasSeed) {
66 | try {
67 | acc = cb(acc, value);
68 | } catch (e) {
69 | return observer.error(e);
70 | }
71 | observer.next(acc);
72 | } else {
73 | acc = value;
74 | }
75 | });
76 | return sub;
77 | });
78 | }
79 |
80 | // Flatten a collection of observables and only output the newest from each
81 |
82 |
83 |
84 |
85 | function startWith(obs, val) {
86 | return new Observable(function (observer) {
87 | observer.next(val); // immediately output this value
88 | var handler = obs.subscribe(function (x) {
89 | return observer.next(x);
90 | });
91 | return function () {
92 | return handler();
93 | };
94 | });
95 | }
96 |
97 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
98 |
99 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
100 |
101 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
102 |
103 | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
104 |
105 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
106 |
107 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
108 |
109 | // import { reconcile } from "./reconciler";
110 | var Component = function () {
111 | function Component(props) {
112 | _classCallCheck(this, Component);
113 |
114 | this.props = props;
115 | this.state = this.state || {};
116 | }
117 |
118 | // setState(partialState) {
119 | // this.state = Object.assign({}, this.state, partialState);
120 | // updateInstance(this.__internalInstance);
121 | // }
122 |
123 | // class method because it feeds in this.initialState
124 |
125 |
126 | _createClass(Component, [{
127 | key: 'combineReducer',
128 | value: function combineReducer(obj) {
129 | var _this = this;
130 |
131 | var sources = Object.entries(obj).map(function (_ref) {
132 | var _ref2 = _slicedToArray(_ref, 2),
133 | k = _ref2[0],
134 | fn = _ref2[1];
135 |
136 | var subReducer = fn(obj);
137 | // there are two forms of return the subreducer can have
138 | // straight stream form
139 | // or object form where we need to scan it into string
140 | if (subReducer.source && subReducer.reducer) {
141 | // object form
142 | subReducer = scan(subReducer.source, subReducer.reducer || function (_, n) {
143 | return n;
144 | }, _this.initialState[k]);
145 | }
146 | return subReducer.map(function (x) {
147 | return _defineProperty({}, k, x);
148 | }); // map to its particular namespace
149 | });
150 | var source = zenObservable_extras.merge.apply(undefined, _toConsumableArray(sources));
151 | var reducer = function reducer(acc, n) {
152 | return _extends({}, acc, n);
153 | };
154 | return { source: source, reducer: reducer };
155 | }
156 | }]);
157 |
158 | return Component;
159 | }();
160 |
161 | // function updateInstance(internalInstance) {
162 | // const parentDom = internalInstance.dom.parentNode;
163 | // const element = internalInstance.element;
164 | // reconcile(parentDom, internalInstance, element);
165 | // }
166 |
167 | function createPublicInstance(element /*, internalInstance*/) {
168 | var type = element.type,
169 | props = element.props;
170 |
171 | var publicInstance = new type(props);
172 | // publicInstance.__internalInstance = internalInstance;
173 | return publicInstance;
174 | }
175 |
176 | var _slicedToArray$1 = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
177 |
178 | function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
179 |
180 | // import { updateDomProperties } from "./updateProperties";
181 | // import VNode from "virtual-dom/vnode/vnode"
182 | // const circuitBreakerflag = false // set true to enable debugger in infinite loops
183 | // let circuitBreaker = -50
184 | // traverse all children and collect a stream of all sources
185 | // AND render. a bit of duplication, but we get persistent instances which is good
186 | function renderStream(element, instance, state, stateMap) {
187 | // this is a separate function because scope gets messy when being recursive
188 | var isNewStream = false; // assume no stream switching by default
189 | // this is the first ping of data throughout the app
190 | var source = Observable.of(state);
191 | var addToStream = function addToStream(_source) {
192 | // visit each source and merge with source
193 | if (_source) return source = zenObservable_extras.merge(source, _source);
194 | };
195 | var markNewStream = function markNewStream() {
196 | return isNewStream = true;
197 | };
198 | var newInstance = render(source, addToStream, markNewStream)(element, instance, state, stateMap);
199 | return { source: source, instance: newInstance, isNewStream: isNewStream };
200 | }
201 |
202 | /** core render logic */
203 | function render(source, addToStream, markNewStream) {
204 | // this is the nonrecursive part
205 | return function renderWithStream(element, instance, state, stateMap) {
206 | // recursive part
207 | var newInstance = void 0;
208 | var type = element.type,
209 | props = element.props;
210 |
211 |
212 | var isDomElement = typeof type === "string";
213 | // if (circuitBreakerflag && circuitBreaker++ > 0) debugger
214 |
215 | var _props$children = props.children,
216 | children = _props$children === undefined ? [] : _props$children,
217 | rest = _objectWithoutProperties(props, ['children']);
218 |
219 | if (isDomElement) {
220 | var childInstances = children.map(function (el, i) {
221 | // ugly but necessary to allow functional children
222 | // mapping element's children to instance's childInstances
223 | var _childInstances = instance && (instance.childInstance || instance.childInstances[i]);
224 | return renderWithStream( // recursion
225 | el, _childInstances, state, stateMap);
226 | });
227 | var childDoms = childInstances.map(function (childInstance) {
228 | return childInstance.dom;
229 | });
230 | var lcaseProps = {};
231 | Object.entries(rest).forEach(function (_ref) {
232 | var _ref2 = _slicedToArray$1(_ref, 2),
233 | k = _ref2[0],
234 | v = _ref2[1];
235 |
236 | return lcaseProps[formatProps(k)] = v;
237 | });
238 | var dom = type === TEXT_ELEMENT ? new VText(props.nodeValue) : h(type, lcaseProps, childDoms); // equivalent of appendchild
239 | newInstance = { dom: dom, element: element, childInstances: childInstances };
240 | } else {
241 | // component element
242 | var publicInstance = void 0;
243 | // debugger
244 | if (instance && instance.publicInstance && instance.element === element) {
245 | // might have to do more diffing of props
246 | // just reuse old instance if it already exists
247 | publicInstance = instance && instance.publicInstance;
248 | } else {
249 | markNewStream(); // mark as dirty in parent scope; will rerender
250 | publicInstance = createPublicInstance(element);
251 | }
252 | var localState = stateMap.get(publicInstance);
253 | if (localState === undefined) localState = publicInstance.initialState;
254 | publicInstance.state = localState; // for access with this.state
255 | if (Object.keys(rest).length) publicInstance.props = rest; // update with new props // TODO: potentially buggy
256 | // console.log({rest})
257 | if (publicInstance.source) {
258 | var src = publicInstance.source(source);
259 | // there are two forms of Component.source
260 | var src$ = src.reducer && publicInstance.initialState !== undefined ?
261 | // 1. the reducer form
262 | scan(src.source, src.reducer, publicInstance.initialState) :
263 | // 2. and raw stream form
264 | src;
265 | addToStream(src$.map(function (event) {
266 | stateMap.set(publicInstance, event);
267 | return { instance: publicInstance, event: event // tag it to the instance
268 | };
269 | }));
270 | }
271 | var childElement = publicInstance.render ? publicInstance.render(localState, stateMap) : publicInstance;
272 |
273 | var childInstance = renderWithStream(childElement, instance && instance.childInstance, state, stateMap);
274 | var _dom = childInstance.dom;
275 | newInstance = { dom: _dom, element: element, childInstance: childInstance, publicInstance: publicInstance };
276 | }
277 | return newInstance;
278 | };
279 | }
280 |
281 | function formatProps(k) {
282 | if (k.startsWith('on')) return k.toLowerCase();
283 | return k;
284 | }
285 |
286 | var stateMapPointer = new Map();
287 |
288 | var emitter = changeEmitter.createChangeEmitter();
289 | // single UI thread; this is the observable that sticks around and swaps out source
290 | var UIthread = new Observable(function (observer) {
291 | emitter.listen(function (x) {
292 | // debugger // success! thread switching!
293 | observer.next(x);
294 | });
295 | });
296 | // mount the vdom on to the dom and
297 | // set up the runtime from sources and
298 | // patch the vdom
299 | // ---
300 | // returns an unsubscribe method you can use to unmount
301 | function mount(rootElement, container) {
302 | // initial, throwaway-ish frame
303 | var _renderStream = renderStream(rootElement, {}, undefined, stateMapPointer),
304 | source = _renderStream.source,
305 | instance = _renderStream.instance;
306 |
307 | var instancePointer = instance;
308 | var rootNode = createElement(instance.dom);
309 | var containerChild = container.firstElementChild;
310 | if (containerChild) {
311 | container.replaceChild(rootNode, containerChild); // hot reloaded mount
312 | } else {
313 | container.appendChild(rootNode); // initial mount
314 | }
315 | var currentSrc$ = null;
316 | var SoS = startWith(UIthread, source); // stream of streams
317 | return SoS.subscribe(function (src$) {
318 | // this is the current sourceStream we are working with
319 | if (currentSrc$) console.log('unsub!') || currentSrc$.unsubscribe(); // unsub from old stream
320 | /**** main */
321 | var source2$ = scan(src$, function (_ref, nextState) {
322 | var instance = _ref.instance,
323 | stateMap = _ref.stateMap;
324 |
325 | var streamOutput = renderStream(rootElement, instance, nextState, stateMap);
326 | if (streamOutput.isNewStream) {
327 | // quick check
328 | var nextSource$ = streamOutput.source;
329 | // debugger
330 | instancePointer = streamOutput.instance;
331 | patch(rootNode, diff(instance.dom, instancePointer.dom)); // render to screen
332 | emitter.emit(nextSource$); // update the UI thread; source will switch
333 | } else {
334 | var nextinstance = streamOutput.instance;
335 | patch(rootNode, diff(instance.dom, nextinstance.dom)); // render to screen
336 | return { instance: nextinstance, stateMap: stateMap };
337 | }
338 | }, { instance: instancePointer, stateMap: stateMapPointer // accumulator
339 | });
340 | /**** end main */
341 | currentSrc$ = source2$.subscribe();
342 | });
343 | }
344 |
345 | var index = {
346 | renderStream: renderStream,
347 | createElement: createElement$1,
348 | createHandler: createHandler,
349 | Component: Component,
350 | mount: mount
351 | };
352 |
353 | exports['default'] = index;
354 | exports.createElement = createElement$1;
355 | exports.createHandler = createHandler;
356 | exports.Component = Component;
357 | exports.renderStream = renderStream;
358 | exports.mount = mount;
359 |
360 | Object.defineProperty(exports, '__esModule', { value: true });
361 |
362 | })));
363 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3RpdmUtcmVhY3QudW1kLmpzIiwic291cmNlcyI6WyIuLi9yZWFjdGl2ZS1yZWFjdC9lbGVtZW50LmpzIiwiLi4vcmVhY3RpdmUtcmVhY3Qvc3d5eGpzLmpzIiwiLi4vcmVhY3RpdmUtcmVhY3QvY29tcG9uZW50LmpzIiwiLi4vcmVhY3RpdmUtcmVhY3QvcmVjb25jaWxlci5qcyIsIi4uL3JlYWN0aXZlLXJlYWN0L3NjaGVkdWxlci5qcyIsIi4uL3JlYWN0aXZlLXJlYWN0L2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBPYnNlcnZhYmxlIGZyb20gJ3plbi1vYnNlcnZhYmxlJ1xuaW1wb3J0IHsgY3JlYXRlQ2hhbmdlRW1pdHRlciB9IGZyb20gJ2NoYW5nZS1lbWl0dGVyJ1xuXG5leHBvcnQgY29uc3QgVEVYVF9FTEVNRU5UID0gXCJURVhUIEVMRU1FTlRcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQodHlwZSwgY29uZmlnLCAuLi5hcmdzKSB7XG4gIGNvbnN0IHByb3BzID0gT2JqZWN0LmFzc2lnbih7fSwgY29uZmlnKTtcbiAgY29uc3QgaGFzQ2hpbGRyZW4gPSBhcmdzLmxlbmd0aCA+IDA7XG4gIGNvbnN0IHJhd0NoaWxkcmVuID0gaGFzQ2hpbGRyZW4gPyBbXS5jb25jYXQoLi4uYXJncykgOiBbXTtcbiAgcHJvcHMuY2hpbGRyZW4gPSByYXdDaGlsZHJlblxuICAgIC5maWx0ZXIoYyA9PiBjICE9IG51bGwgJiYgYyAhPT0gZmFsc2UpXG4gICAgLm1hcChjID0+IGMgaW5zdGFuY2VvZiBPYmplY3QgPyBjIDogY3JlYXRlVGV4dEVsZW1lbnQoYykpO1xuICByZXR1cm4geyB0eXBlLCBwcm9wcyB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUZXh0RWxlbWVudCh2YWx1ZSkge1xuICByZXR1cm4gY3JlYXRlRWxlbWVudChURVhUX0VMRU1FTlQsIHsgbm9kZVZhbHVlOiB2YWx1ZSB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhhbmRsZXIoX2ZuKSB7XG4gIGNvbnN0IGVtaXR0ZXIgPSBjcmVhdGVDaGFuZ2VFbWl0dGVyKClcbiAgbGV0IGhhbmRsZXIgPSB4ID0+IHtcbiAgICBlbWl0dGVyLmVtaXQoeClcbiAgfVxuICBoYW5kbGVyLiQgPSBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XG4gICAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuKHZhbHVlID0+IHtcbiAgICAgIG9ic2VydmVyLm5leHQoX2ZuID8gX2ZuKHZhbHVlKSA6IHZhbHVlKVxuICAgIH1cbiAgICApXG4gIH0pXG4gIHJldHVybiBoYW5kbGVyXG59IiwiaW1wb3J0IE9ic2VydmFibGUgZnJvbSAnemVuLW9ic2VydmFibGUnXG5leHBvcnQgeyBtZXJnZSwgY29tYmluZUxhdGVzdCwgemlwIH0gZnJvbSAnemVuLW9ic2VydmFibGUvZXh0cmFzJ1xuXG5leHBvcnQgZnVuY3Rpb24gSW50ZXJ2YWwodGljayA9IDEwMDAsIHRpY2tEYXRhID0gU3ltYm9sKCd0aWNrJykpIHtcbiAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICBsZXQgdGltZXIgPSAoKSA9PiBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgdGlja0RhdGEgPT09ICdmdW5jdGlvbicpIHRpY2tEYXRhID0gdGlja0RhdGEoKVxuICAgICAgb2JzZXJ2ZXIubmV4dCh0aWNrRGF0YSk7XG4gICAgICB0aW1lcigpXG4gICAgICAvLyBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgIH0sIHRpY2spO1xuICAgIHRpbWVyKClcbiAgXG4gICAgLy8gT24gdW5zdWJzY3JpcHRpb24sIGNhbmNlbCB0aGUgdGltZXJcbiAgICByZXR1cm4gKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVyKTtcblxuICB9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZnJvbUV2ZW50KGVsLCBldmVudFR5cGUpIHtcbiAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICBjb25zdCBoYW5kbGVyID0gZSA9PiBvYnNlcnZlci5uZXh0KGUpXG4gICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGhhbmRsZXIpXG4gICAgLy8gb24gdW5zdWIsIHJlbW92ZSBldmVudCBsaXN0ZW5lclxuICAgIHJldHVybiAoKSA9PiBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgaGFuZGxlcilcbiAgfSlcbn1cblxuY29uc3QgTk9JTklUID0gU3ltYm9sKCdOT19JTklUSUFMX1ZBTFVFJylcbmV4cG9ydCBmdW5jdGlvbiBzY2FuKG9icywgY2IsIHNlZWQgPSBOT0lOSVQpIHtcbiAgbGV0IHN1YiwgYWNjID0gc2VlZCwgaGFzVmFsdWUgPSBmYWxzZVxuICBjb25zdCBoYXNTZWVkID0gYWNjICE9PSBOT0lOSVRcbiAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICBzdWIgPSBvYnMuc3Vic2NyaWJlKHZhbHVlID0+IHtcbiAgICAgIGlmIChvYnNlcnZlci5jbG9zZWQpIHJldHVyblxuICAgICAgbGV0IGZpcnN0ID0gIWhhc1ZhbHVlO1xuICAgICAgaGFzVmFsdWUgPSB0cnVlXG4gICAgICBpZiAoIWZpcnN0IHx8IGhhc1NlZWQgKSB7XG4gICAgICAgIHRyeSB7IGFjYyA9IGNiKGFjYywgdmFsdWUpIH1cbiAgICAgICAgY2F0Y2ggKGUpIHsgcmV0dXJuIG9ic2VydmVyLmVycm9yKGUpIH1cbiAgICAgICAgb2JzZXJ2ZXIubmV4dChhY2MpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGFjYyA9IHZhbHVlXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gc3ViXG4gIH0pXG59XG5cbi8vIEZsYXR0ZW4gYSBjb2xsZWN0aW9uIG9mIG9ic2VydmFibGVzIGFuZCBvbmx5IG91dHB1dCB0aGUgbmV3ZXN0IGZyb20gZWFjaFxuZXhwb3J0IGZ1bmN0aW9uIHN3aXRjaExhdGVzdChoaWdoZXJPYnNlcnZhYmxlKSB7XG4gIHJldHVybiBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XG4gICAgbGV0IGN1cnJlbnRPYnMgPSBudWxsXG4gICAgcmV0dXJuIGhpZ2hlck9ic2VydmFibGUuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQob2JzKSB7XG4gICAgICAgIGlmIChjdXJyZW50T2JzKSBjdXJyZW50T2JzLnVuc3Vic2NyaWJlKCkgLy8gdW5zdWIgYW5kIHN3aXRjaFxuICAgICAgICBjdXJyZW50T2JzID0gb2JzLnN1YnNjcmliZShvYnNlcnZlci5zdWJzY3JpYmUpXG4gICAgICB9LFxuICAgICAgZXJyb3IoZSkge1xuICAgICAgICBvYnNlcnZlci5lcnJvcihlKSAvLyB1bnRlc3RlZFxuICAgICAgfSxcbiAgICAgIGNvbXBsZXRlKCkge1xuICAgICAgICAvLyBpIGRvbnQgdGhpbmsgaXQgc2hvdWxkIGNvbXBsZXRlP1xuICAgICAgICAvLyBvYnNlcnZlci5jb21wbGV0ZSgpXG4gICAgICB9XG4gICAgfSlcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXBUb0NvbnN0YW50KG9icywgdmFsKSB7XG4gIHJldHVybiBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XG4gICAgY29uc3QgaGFuZGxlciA9IG9icy5zdWJzY3JpYmUoKCkgPT4gb2JzZXJ2ZXIubmV4dCh2YWwpKVxuICAgIHJldHVybiBoYW5kbGVyXG4gIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdGFydFdpdGgob2JzLCB2YWwpIHtcbiAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICBvYnNlcnZlci5uZXh0KHZhbCkgLy8gaW1tZWRpYXRlbHkgb3V0cHV0IHRoaXMgdmFsdWVcbiAgICBjb25zdCBoYW5kbGVyID0gb2JzLnN1YnNjcmliZSh4ID0+IG9ic2VydmVyLm5leHQoeCkpXG4gICAgcmV0dXJuICgpID0+IGhhbmRsZXIoKVxuICB9KVxufSIsIi8vIGltcG9ydCB7IHJlY29uY2lsZSB9IGZyb20gXCIuL3JlY29uY2lsZXJcIjtcbmltcG9ydCB7SW50ZXJ2YWwsIHNjYW4sIHN0YXJ0V2l0aCwgbWVyZ2UsIG1hcFRvQ29uc3RhbnR9IGZyb20gJy4vc3d5eGpzJ1xuXG5leHBvcnQgY2xhc3MgQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICB0aGlzLnByb3BzID0gcHJvcHM7XG4gICAgdGhpcy5zdGF0ZSA9IHRoaXMuc3RhdGUgfHwge307XG4gIH1cblxuICAvLyBzZXRTdGF0ZShwYXJ0aWFsU3RhdGUpIHtcbiAgLy8gICB0aGlzLnN0YXRlID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5zdGF0ZSwgcGFydGlhbFN0YXRlKTtcbiAgLy8gICB1cGRhdGVJbnN0YW5jZSh0aGlzLl9faW50ZXJuYWxJbnN0YW5jZSk7XG4gIC8vIH1cblxuICAvLyBjbGFzcyBtZXRob2QgYmVjYXVzZSBpdCBmZWVkcyBpbiB0aGlzLmluaXRpYWxTdGF0ZVxuICBjb21iaW5lUmVkdWNlcihvYmopIHtcbiAgICBjb25zdCBzb3VyY2VzID0gT2JqZWN0LmVudHJpZXMob2JqKS5tYXAoKFtrLGZuXSkgPT4ge1xuICAgICAgbGV0IHN1YlJlZHVjZXIgPSBmbihvYmopXG4gICAgICAvLyB0aGVyZSBhcmUgdHdvIGZvcm1zIG9mIHJldHVybiB0aGUgc3VicmVkdWNlciBjYW4gaGF2ZVxuICAgICAgLy8gc3RyYWlnaHQgc3RyZWFtIGZvcm1cbiAgICAgIC8vIG9yIG9iamVjdCBmb3JtIHdoZXJlIHdlIG5lZWQgdG8gc2NhbiBpdCBpbnRvIHN0cmluZ1xuICAgICAgaWYgKHN1YlJlZHVjZXIuc291cmNlICYmIHN1YlJlZHVjZXIucmVkdWNlcikgeyAvLyBvYmplY3QgZm9ybVxuICAgICAgICBzdWJSZWR1Y2VyID0gc2NhbihzdWJSZWR1Y2VyLnNvdXJjZSwgXG4gICAgICAgICAgc3ViUmVkdWNlci5yZWR1Y2VyIHx8ICgoXywgbikgPT4gbiksIFxuICAgICAgICAgIHRoaXMuaW5pdGlhbFN0YXRlW2tdXG4gICAgICAgIClcbiAgICAgIH1cbiAgICAgIHJldHVybiBzdWJSZWR1Y2VyXG4gICAgICAgIC5tYXAoeCA9PiAoe1trXTogeH0pKSAvLyBtYXAgdG8gaXRzIHBhcnRpY3VsYXIgbmFtZXNwYWNlXG4gICAgfSlcbiAgICBjb25zdCBzb3VyY2UgPSBtZXJnZSguLi5zb3VyY2VzKVxuICAgIGNvbnN0IHJlZHVjZXIgPSAoYWNjLCBuKSA9PiAoey4uLmFjYywgLi4ubn0pXG4gICAgcmV0dXJuIHtzb3VyY2UsIHJlZHVjZXJ9XG4gIH1cbn1cblxuLy8gZnVuY3Rpb24gdXBkYXRlSW5zdGFuY2UoaW50ZXJuYWxJbnN0YW5jZSkge1xuLy8gICBjb25zdCBwYXJlbnREb20gPSBpbnRlcm5hbEluc3RhbmNlLmRvbS5wYXJlbnROb2RlO1xuLy8gICBjb25zdCBlbGVtZW50ID0gaW50ZXJuYWxJbnN0YW5jZS5lbGVtZW50O1xuLy8gICByZWNvbmNpbGUocGFyZW50RG9tLCBpbnRlcm5hbEluc3RhbmNlLCBlbGVtZW50KTtcbi8vIH1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVB1YmxpY0luc3RhbmNlKGVsZW1lbnQvKiwgaW50ZXJuYWxJbnN0YW5jZSovKSB7XG4gIGNvbnN0IHsgdHlwZSwgcHJvcHMgfSA9IGVsZW1lbnQ7XG4gIGNvbnN0IHB1YmxpY0luc3RhbmNlID0gbmV3IHR5cGUocHJvcHMpO1xuICAvLyBwdWJsaWNJbnN0YW5jZS5fX2ludGVybmFsSW5zdGFuY2UgPSBpbnRlcm5hbEluc3RhbmNlO1xuICByZXR1cm4gcHVibGljSW5zdGFuY2U7XG59XG4iLCJpbXBvcnQgT2JzZXJ2YWJsZSBmcm9tICd6ZW4tb2JzZXJ2YWJsZSdcbmltcG9ydCB7ZnJvbUV2ZW50LCBzY2FuLCBtZXJnZSwgc3RhcnRXaXRoLCBzd2l0Y2hMYXRlc3R9IGZyb20gJy4vc3d5eGpzJ1xuLy8gaW1wb3J0IHsgdXBkYXRlRG9tUHJvcGVydGllcyB9IGZyb20gXCIuL3VwZGF0ZVByb3BlcnRpZXNcIjtcbmltcG9ydCB7IFRFWFRfRUxFTUVOVCB9IGZyb20gXCIuL2VsZW1lbnRcIjtcbmltcG9ydCB7IGNyZWF0ZVB1YmxpY0luc3RhbmNlIH0gZnJvbSBcIi4vY29tcG9uZW50XCI7XG5pbXBvcnQgaCBmcm9tICd2aXJ0dWFsLWRvbS9oJ1xuLy8gaW1wb3J0IFZOb2RlIGZyb20gXCJ2aXJ0dWFsLWRvbS92bm9kZS92bm9kZVwiXG5pbXBvcnQgVlRleHQgZnJvbSBcInZpcnR1YWwtZG9tL3Zub2RlL3Z0ZXh0XCJcblxuLy8gY29uc3QgY2lyY3VpdEJyZWFrZXJmbGFnID0gZmFsc2UgLy8gc2V0IHRydWUgdG8gZW5hYmxlIGRlYnVnZ2VyIGluIGluZmluaXRlIGxvb3BzXG4vLyBsZXQgY2lyY3VpdEJyZWFrZXIgPSAtNTBcbi8vIHRyYXZlcnNlIGFsbCBjaGlsZHJlbiBhbmQgY29sbGVjdCBhIHN0cmVhbSBvZiBhbGwgc291cmNlc1xuLy8gQU5EIHJlbmRlci4gYSBiaXQgb2YgZHVwbGljYXRpb24sIGJ1dCB3ZSBnZXQgcGVyc2lzdGVudCBpbnN0YW5jZXMgd2hpY2ggaXMgZ29vZFxuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlclN0cmVhbShlbGVtZW50LCBpbnN0YW5jZSwgc3RhdGUsIHN0YXRlTWFwKSB7XG4gIC8vIHRoaXMgaXMgYSBzZXBhcmF0ZSBmdW5jdGlvbiBiZWNhdXNlIHNjb3BlIGdldHMgbWVzc3kgd2hlbiBiZWluZyByZWN1cnNpdmVcbiAgbGV0IGlzTmV3U3RyZWFtID0gZmFsc2UgLy8gYXNzdW1lIG5vIHN0cmVhbSBzd2l0Y2hpbmcgYnkgZGVmYXVsdFxuICAvLyB0aGlzIGlzIHRoZSBmaXJzdCBwaW5nIG9mIGRhdGEgdGhyb3VnaG91dCB0aGUgYXBwXG4gIGxldCBzb3VyY2UgPSBPYnNlcnZhYmxlLm9mKHN0YXRlKSBcbiAgY29uc3QgYWRkVG9TdHJlYW0gPSBfc291cmNlID0+IHtcbiAgICAvLyB2aXNpdCBlYWNoIHNvdXJjZSBhbmQgbWVyZ2Ugd2l0aCBzb3VyY2VcbiAgICBpZiAoX3NvdXJjZSkgcmV0dXJuIHNvdXJjZSA9IG1lcmdlKHNvdXJjZSwgX3NvdXJjZSlcbiAgfVxuICBjb25zdCBtYXJrTmV3U3RyZWFtID0gKCkgPT4gaXNOZXdTdHJlYW0gPSB0cnVlXG4gIGNvbnN0IG5ld0luc3RhbmNlID0gcmVuZGVyKHNvdXJjZSwgYWRkVG9TdHJlYW0sIG1hcmtOZXdTdHJlYW0pKGVsZW1lbnQsIGluc3RhbmNlLCBzdGF0ZSwgc3RhdGVNYXApXG4gIHJldHVybiB7c291cmNlLCBpbnN0YW5jZTogbmV3SW5zdGFuY2UsIGlzTmV3U3RyZWFtfVxufVxuXG4vKiogY29yZSByZW5kZXIgbG9naWMgKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXIoc291cmNlLCBhZGRUb1N0cmVhbSwgbWFya05ld1N0cmVhbSkgeyAvLyB0aGlzIGlzIHRoZSBub25yZWN1cnNpdmUgcGFydFxuICByZXR1cm4gZnVuY3Rpb24gcmVuZGVyV2l0aFN0cmVhbShlbGVtZW50LCBpbnN0YW5jZSwgc3RhdGUsIHN0YXRlTWFwKSB7IC8vIHJlY3Vyc2l2ZSBwYXJ0XG4gICAgbGV0IG5ld0luc3RhbmNlXG4gICAgY29uc3QgeyB0eXBlLCBwcm9wcyB9ID0gZWxlbWVudFxuICBcbiAgICBjb25zdCBpc0RvbUVsZW1lbnQgPSB0eXBlb2YgdHlwZSA9PT0gXCJzdHJpbmdcIjtcbiAgICAvLyBpZiAoY2lyY3VpdEJyZWFrZXJmbGFnICYmIGNpcmN1aXRCcmVha2VyKysgPiAwKSBkZWJ1Z2dlclxuICAgIGNvbnN0IHtjaGlsZHJlbiA9IFtdLCAuLi5yZXN0fSA9IHByb3BzXG4gICAgaWYgKGlzRG9tRWxlbWVudCkge1xuICAgICAgY29uc3QgY2hpbGRJbnN0YW5jZXMgPSBjaGlsZHJlbi5tYXAoXG4gICAgICAgIChlbCwgaSkgPT4ge1xuICAgICAgICAgIC8vIHVnbHkgYnV0IG5lY2Vzc2FyeSB0byBhbGxvdyBmdW5jdGlvbmFsIGNoaWxkcmVuXG4gICAgICAgICAgLy8gbWFwcGluZyBlbGVtZW50J3MgY2hpbGRyZW4gdG8gaW5zdGFuY2UncyBjaGlsZEluc3RhbmNlc1xuICAgICAgICAgIGNvbnN0IF9jaGlsZEluc3RhbmNlcyA9IGluc3RhbmNlICYmIChpbnN0YW5jZS5jaGlsZEluc3RhbmNlIHx8IGluc3RhbmNlLmNoaWxkSW5zdGFuY2VzW2ldKVxuICAgICAgICAgIHJldHVybiByZW5kZXJXaXRoU3RyZWFtKCAgLy8gcmVjdXJzaW9uXG4gICAgICAgICAgICBlbCwgXG4gICAgICAgICAgICBfY2hpbGRJbnN0YW5jZXMsIFxuICAgICAgICAgICAgc3RhdGUsIFxuICAgICAgICAgICAgc3RhdGVNYXApIFxuICAgICAgICB9XG4gICAgICApO1xuICAgICAgY29uc3QgY2hpbGREb21zID0gY2hpbGRJbnN0YW5jZXMubWFwKGNoaWxkSW5zdGFuY2UgPT4gY2hpbGRJbnN0YW5jZS5kb20pO1xuICAgICAgbGV0IGxjYXNlUHJvcHMgPSB7fVxuICAgICAgT2JqZWN0LmVudHJpZXMocmVzdCkuZm9yRWFjaCgoW2ssIHZdKSA9PiBsY2FzZVByb3BzW2Zvcm1hdFByb3BzKGspXSA9IHYpXG4gICAgICBjb25zdCBkb20gPSB0eXBlID09PSBURVhUX0VMRU1FTlRcbiAgICAgICAgPyBuZXcgVlRleHQocHJvcHMubm9kZVZhbHVlKVxuICAgICAgICA6IGgodHlwZSwgbGNhc2VQcm9wcywgY2hpbGREb21zKTsgLy8gZXF1aXZhbGVudCBvZiBhcHBlbmRjaGlsZFxuICAgICAgbmV3SW5zdGFuY2UgPSB7IGRvbSwgZWxlbWVudCwgY2hpbGRJbnN0YW5jZXMgfTtcbiAgICB9IGVsc2UgeyAvLyBjb21wb25lbnQgZWxlbWVudFxuICAgICAgbGV0IHB1YmxpY0luc3RhbmNlIFxuICAgICAgLy8gZGVidWdnZXJcbiAgICAgIGlmIChpbnN0YW5jZSAmJiBpbnN0YW5jZS5wdWJsaWNJbnN0YW5jZSAmJiBpbnN0YW5jZS5lbGVtZW50ID09PSBlbGVtZW50KSB7IC8vIG1pZ2h0IGhhdmUgdG8gZG8gbW9yZSBkaWZmaW5nIG9mIHByb3BzXG4gICAgICAgIC8vIGp1c3QgcmV1c2Ugb2xkIGluc3RhbmNlIGlmIGl0IGFscmVhZHkgZXhpc3RzXG4gICAgICAgIHB1YmxpY0luc3RhbmNlID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UucHVibGljSW5zdGFuY2VcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hcmtOZXdTdHJlYW0oKSAvLyBtYXJrIGFzIGRpcnR5IGluIHBhcmVudCBzY29wZTsgd2lsbCByZXJlbmRlclxuICAgICAgICBwdWJsaWNJbnN0YW5jZSA9IGNyZWF0ZVB1YmxpY0luc3RhbmNlKGVsZW1lbnQpO1xuICAgICAgfVxuICAgICAgbGV0IGxvY2FsU3RhdGUgPSBzdGF0ZU1hcC5nZXQocHVibGljSW5zdGFuY2UpXG4gICAgICBpZiAobG9jYWxTdGF0ZSA9PT0gdW5kZWZpbmVkKSBsb2NhbFN0YXRlID0gcHVibGljSW5zdGFuY2UuaW5pdGlhbFN0YXRlXG4gICAgICBwdWJsaWNJbnN0YW5jZS5zdGF0ZSA9IGxvY2FsU3RhdGUgLy8gZm9yIGFjY2VzcyB3aXRoIHRoaXMuc3RhdGVcbiAgICAgIGlmIChPYmplY3Qua2V5cyhyZXN0KS5sZW5ndGgpIHB1YmxpY0luc3RhbmNlLnByb3BzID0gcmVzdCAvLyB1cGRhdGUgd2l0aCBuZXcgcHJvcHMgLy8gVE9ETzogcG90ZW50aWFsbHkgYnVnZ3lcbiAgICAgIC8vIGNvbnNvbGUubG9nKHtyZXN0fSlcbiAgICAgIGlmIChwdWJsaWNJbnN0YW5jZS5zb3VyY2UpIHtcbiAgICAgICAgY29uc3Qgc3JjID0gcHVibGljSW5zdGFuY2Uuc291cmNlKHNvdXJjZSlcbiAgICAgICAgLy8gdGhlcmUgYXJlIHR3byBmb3JtcyBvZiBDb21wb25lbnQuc291cmNlXG4gICAgICAgIGNvbnN0IHNyYyQgPSBzcmMucmVkdWNlciAmJiBwdWJsaWNJbnN0YW5jZS5pbml0aWFsU3RhdGUgIT09IHVuZGVmaW5lZCA/IFxuICAgICAgICAgICAgLy8gMS4gdGhlIHJlZHVjZXIgZm9ybVxuICAgICAgICAgICAgc2NhbihzcmMuc291cmNlLCBzcmMucmVkdWNlciwgcHVibGljSW5zdGFuY2UuaW5pdGlhbFN0YXRlKSA6IFxuICAgICAgICAgICAgLy8gMi4gYW5kIHJhdyBzdHJlYW0gZm9ybVxuICAgICAgICAgICAgc3JjXG4gICAgICAgIGFkZFRvU3RyZWFtKHNyYyRcbiAgICAgICAgICAubWFwKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHN0YXRlTWFwLnNldChwdWJsaWNJbnN0YW5jZSwgZXZlbnQpXG4gICAgICAgICAgICByZXR1cm4ge2luc3RhbmNlOiBwdWJsaWNJbnN0YW5jZSwgZXZlbnR9IC8vIHRhZyBpdCB0byB0aGUgaW5zdGFuY2VcbiAgICAgICAgICB9KSBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNoaWxkRWxlbWVudCA9IHB1YmxpY0luc3RhbmNlLnJlbmRlciA/IFxuICAgICAgICAgIHB1YmxpY0luc3RhbmNlLnJlbmRlcihsb2NhbFN0YXRlLCBzdGF0ZU1hcCkgOiBcbiAgICAgICAgICBwdWJsaWNJbnN0YW5jZTtcblxuICAgICAgY29uc3QgY2hpbGRJbnN0YW5jZSA9IHJlbmRlcldpdGhTdHJlYW0oY2hpbGRFbGVtZW50LCBpbnN0YW5jZSAmJiBpbnN0YW5jZS5jaGlsZEluc3RhbmNlLCBzdGF0ZSwgc3RhdGVNYXApXG4gICAgICBjb25zdCBkb20gPSBjaGlsZEluc3RhbmNlLmRvbVxuICAgICAgbmV3SW5zdGFuY2UgPSB7IGRvbSwgZWxlbWVudCwgY2hpbGRJbnN0YW5jZSwgcHVibGljSW5zdGFuY2UgfVxuICAgIH1cbiAgICByZXR1cm4gbmV3SW5zdGFuY2VcbiAgfVxufVxuXG5mdW5jdGlvbiBmb3JtYXRQcm9wcyhrKSB7XG4gIGlmIChrLnN0YXJ0c1dpdGgoJ29uJykpIHJldHVybiBrLnRvTG93ZXJDYXNlKClcbiAgcmV0dXJuIGtcbn0iLCJpbXBvcnQgT2JzZXJ2YWJsZSBmcm9tICd6ZW4tb2JzZXJ2YWJsZSdcbmltcG9ydCB7ZnJvbUV2ZW50LCBzY2FuLCBtZXJnZSwgc3RhcnRXaXRoLCBzd2l0Y2hMYXRlc3R9IGZyb20gJy4vc3d5eGpzJ1xuaW1wb3J0IGRpZmYgZnJvbSAndmlydHVhbC1kb20vZGlmZic7XG5pbXBvcnQgcGF0Y2ggZnJvbSAndmlydHVhbC1kb20vcGF0Y2gnO1xuaW1wb3J0IGNyZWF0ZUVsZW1lbnQgZnJvbSAndmlydHVhbC1kb20vY3JlYXRlLWVsZW1lbnQnO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbmdlRW1pdHRlciB9IGZyb20gJ2NoYW5nZS1lbWl0dGVyJ1xuaW1wb3J0IHsgcmVuZGVyU3RyZWFtIH0gZnJvbSAnLi9yZWNvbmNpbGVyJ1xuXG5leHBvcnQgY29uc3Qgc3RhdGVNYXBQb2ludGVyID0gbmV3IE1hcCgpXG5cbmxldCBjaXJjdWl0QnJlYWtlciA9IC0yMFxuXG5jb25zdCBlbWl0dGVyID0gY3JlYXRlQ2hhbmdlRW1pdHRlcigpXG4vLyBzaW5nbGUgVUkgdGhyZWFkOyB0aGlzIGlzIHRoZSBvYnNlcnZhYmxlIHRoYXQgc3RpY2tzIGFyb3VuZCBhbmQgc3dhcHMgb3V0IHNvdXJjZVxuY29uc3QgVUl0aHJlYWQgPSBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XG4gIGVtaXR0ZXIubGlzdGVuKHggPT4ge1xuICAgIC8vIGRlYnVnZ2VyIC8vIHN1Y2Nlc3MhIHRocmVhZCBzd2l0Y2hpbmchXG4gICAgb2JzZXJ2ZXIubmV4dCh4KVxuICB9KVxufSlcbi8vIG1vdW50IHRoZSB2ZG9tIG9uIHRvIHRoZSBkb20gYW5kIFxuLy8gc2V0IHVwIHRoZSBydW50aW1lIGZyb20gc291cmNlcyBhbmRcbi8vIHBhdGNoIHRoZSB2ZG9tXG4vLyAtLS1cbi8vIHJldHVybnMgYW4gdW5zdWJzY3JpYmUgbWV0aG9kIHlvdSBjYW4gdXNlIHRvIHVubW91bnRcbmV4cG9ydCBmdW5jdGlvbiBtb3VudChyb290RWxlbWVudCwgY29udGFpbmVyKSB7XG4gIC8vIGluaXRpYWwsIHRocm93YXdheS1pc2ggZnJhbWVcbiAgbGV0IHtzb3VyY2UsIGluc3RhbmNlfSA9IHJlbmRlclN0cmVhbShyb290RWxlbWVudCwge30sIHVuZGVmaW5lZCwgc3RhdGVNYXBQb2ludGVyKVxuICBsZXQgaW5zdGFuY2VQb2ludGVyID0gaW5zdGFuY2VcbiAgY29uc3Qgcm9vdE5vZGUgPSBjcmVhdGVFbGVtZW50KGluc3RhbmNlLmRvbSlcbiAgY29uc3QgY29udGFpbmVyQ2hpbGQgPSBjb250YWluZXIuZmlyc3RFbGVtZW50Q2hpbGRcbiAgaWYgKGNvbnRhaW5lckNoaWxkKSB7XG4gICAgY29udGFpbmVyLnJlcGxhY2VDaGlsZChyb290Tm9kZSxjb250YWluZXJDaGlsZCkgLy8gaG90IHJlbG9hZGVkIG1vdW50XG4gIH0gZWxzZSB7XG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHJvb3ROb2RlKSAvLyBpbml0aWFsIG1vdW50XG4gIH1cbiAgbGV0IGN1cnJlbnRTcmMkID0gbnVsbFxuICBsZXQgU29TID0gc3RhcnRXaXRoKFVJdGhyZWFkLCBzb3VyY2UpIC8vIHN0cmVhbSBvZiBzdHJlYW1zXG4gIHJldHVybiBTb1Muc3Vic2NyaWJlKFxuICAgIHNyYyQgPT4geyAvLyB0aGlzIGlzIHRoZSBjdXJyZW50IHNvdXJjZVN0cmVhbSB3ZSBhcmUgd29ya2luZyB3aXRoXG4gICAgICBpZiAoY3VycmVudFNyYyQpIGNvbnNvbGUubG9nKCd1bnN1YiEnKSB8fCBjdXJyZW50U3JjJC51bnN1YnNjcmliZSgpIC8vIHVuc3ViIGZyb20gb2xkIHN0cmVhbVxuICAgICAgLyoqKiogbWFpbiAqL1xuICAgICAgY29uc3Qgc291cmNlMiQgPSBzY2FuKFxuICAgICAgICBzcmMkLCBcbiAgICAgICAgKHtpbnN0YW5jZSwgc3RhdGVNYXB9LCBuZXh0U3RhdGUpID0+IHtcbiAgICAgICAgICBjb25zdCBzdHJlYW1PdXRwdXQgPSByZW5kZXJTdHJlYW0ocm9vdEVsZW1lbnQsIGluc3RhbmNlLCBuZXh0U3RhdGUsIHN0YXRlTWFwKVxuICAgICAgICAgIGlmIChzdHJlYW1PdXRwdXQuaXNOZXdTdHJlYW0pIHsgLy8gcXVpY2sgY2hlY2tcbiAgICAgICAgICAgIGNvbnN0IG5leHRTb3VyY2UkID0gc3RyZWFtT3V0cHV0LnNvdXJjZVxuICAgICAgICAgICAgLy8gZGVidWdnZXJcbiAgICAgICAgICAgIGluc3RhbmNlUG9pbnRlciA9IHN0cmVhbU91dHB1dC5pbnN0YW5jZVxuICAgICAgICAgICAgcGF0Y2gocm9vdE5vZGUsIGRpZmYoaW5zdGFuY2UuZG9tLCBpbnN0YW5jZVBvaW50ZXIuZG9tKSkgLy8gcmVuZGVyIHRvIHNjcmVlblxuICAgICAgICAgICAgZW1pdHRlci5lbWl0KG5leHRTb3VyY2UkKSAvLyB1cGRhdGUgdGhlIFVJIHRocmVhZDsgc291cmNlIHdpbGwgc3dpdGNoXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG5leHRpbnN0YW5jZSA9IHN0cmVhbU91dHB1dC5pbnN0YW5jZVxuICAgICAgICAgICAgcGF0Y2gocm9vdE5vZGUsIGRpZmYoaW5zdGFuY2UuZG9tLCBuZXh0aW5zdGFuY2UuZG9tKSkgLy8gcmVuZGVyIHRvIHNjcmVlblxuICAgICAgICAgICAgcmV0dXJuIHtpbnN0YW5jZTogbmV4dGluc3RhbmNlLCBzdGF0ZU1hcDogc3RhdGVNYXB9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7aW5zdGFuY2U6IGluc3RhbmNlUG9pbnRlciwgc3RhdGVNYXA6IHN0YXRlTWFwUG9pbnRlcn0gLy8gYWNjdW11bGF0b3JcbiAgICAgIClcbiAgICAgIC8qKioqIGVuZCBtYWluICovXG4gICAgICBjdXJyZW50U3JjJCA9IFxuICAgICAgICBzb3VyY2UyJFxuICAgICAgICAgIC5zdWJzY3JpYmUoKVxuICAgIH1cbiAgKVxufVxuIiwiaW1wb3J0IHsgY3JlYXRlRWxlbWVudCwgY3JlYXRlSGFuZGxlciB9IGZyb20gXCIuL2VsZW1lbnRcIjtcbmltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gXCIuL2NvbXBvbmVudFwiO1xuaW1wb3J0IHsgcmVuZGVyU3RyZWFtIH0gZnJvbSBcIi4vcmVjb25jaWxlclwiXG5pbXBvcnQgeyBtb3VudCB9IGZyb20gXCIuL3NjaGVkdWxlclwiO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIHJlbmRlclN0cmVhbSxcbiAgY3JlYXRlRWxlbWVudCxcbiAgY3JlYXRlSGFuZGxlcixcbiAgQ29tcG9uZW50LFxuICBtb3VudFxufTtcblxuZXhwb3J0IHsgY3JlYXRlRWxlbWVudCwgY3JlYXRlSGFuZGxlciwgQ29tcG9uZW50LCBcbiAgcmVuZGVyU3RyZWFtLCBcbiAgbW91bnQgfTtcbiJdLCJuYW1lcyI6WyJURVhUX0VMRU1FTlQiLCJjcmVhdGVFbGVtZW50IiwidHlwZSIsImNvbmZpZyIsInByb3BzIiwiT2JqZWN0IiwiYXNzaWduIiwiYXJncyIsImhhc0NoaWxkcmVuIiwibGVuZ3RoIiwicmF3Q2hpbGRyZW4iLCJjb25jYXQiLCJjaGlsZHJlbiIsImZpbHRlciIsImMiLCJtYXAiLCJjcmVhdGVUZXh0RWxlbWVudCIsInZhbHVlIiwibm9kZVZhbHVlIiwiY3JlYXRlSGFuZGxlciIsIl9mbiIsImVtaXR0ZXIiLCJjcmVhdGVDaGFuZ2VFbWl0dGVyIiwiaGFuZGxlciIsImVtaXQiLCJ4IiwiJCIsIk9ic2VydmFibGUiLCJsaXN0ZW4iLCJuZXh0IiwiTk9JTklUIiwiU3ltYm9sIiwic2NhbiIsIm9icyIsImNiIiwic2VlZCIsInN1YiIsImFjYyIsImhhc1ZhbHVlIiwiaGFzU2VlZCIsInN1YnNjcmliZSIsIm9ic2VydmVyIiwiY2xvc2VkIiwiZmlyc3QiLCJlIiwiZXJyb3IiLCJzdGFydFdpdGgiLCJ2YWwiLCJDb21wb25lbnQiLCJzdGF0ZSIsIm9iaiIsInNvdXJjZXMiLCJlbnRyaWVzIiwiayIsImZuIiwic3ViUmVkdWNlciIsInNvdXJjZSIsInJlZHVjZXIiLCJfIiwibiIsImluaXRpYWxTdGF0ZSIsIm1lcmdlIiwiY3JlYXRlUHVibGljSW5zdGFuY2UiLCJlbGVtZW50IiwicHVibGljSW5zdGFuY2UiLCJyZW5kZXJTdHJlYW0iLCJpbnN0YW5jZSIsInN0YXRlTWFwIiwiaXNOZXdTdHJlYW0iLCJvZiIsImFkZFRvU3RyZWFtIiwiX3NvdXJjZSIsIm1hcmtOZXdTdHJlYW0iLCJuZXdJbnN0YW5jZSIsInJlbmRlciIsInJlbmRlcldpdGhTdHJlYW0iLCJpc0RvbUVsZW1lbnQiLCJyZXN0IiwiY2hpbGRJbnN0YW5jZXMiLCJlbCIsImkiLCJfY2hpbGRJbnN0YW5jZXMiLCJjaGlsZEluc3RhbmNlIiwiY2hpbGREb21zIiwiZG9tIiwibGNhc2VQcm9wcyIsImZvckVhY2giLCJ2IiwiZm9ybWF0UHJvcHMiLCJWVGV4dCIsImgiLCJsb2NhbFN0YXRlIiwiZ2V0IiwidW5kZWZpbmVkIiwia2V5cyIsInNyYyIsInNyYyQiLCJzZXQiLCJldmVudCIsImNoaWxkRWxlbWVudCIsInN0YXJ0c1dpdGgiLCJ0b0xvd2VyQ2FzZSIsInN0YXRlTWFwUG9pbnRlciIsIk1hcCIsIlVJdGhyZWFkIiwibW91bnQiLCJyb290RWxlbWVudCIsImNvbnRhaW5lciIsImluc3RhbmNlUG9pbnRlciIsInJvb3ROb2RlIiwiY29udGFpbmVyQ2hpbGQiLCJmaXJzdEVsZW1lbnRDaGlsZCIsInJlcGxhY2VDaGlsZCIsImFwcGVuZENoaWxkIiwiY3VycmVudFNyYyQiLCJTb1MiLCJjb25zb2xlIiwibG9nIiwidW5zdWJzY3JpYmUiLCJzb3VyY2UyJCIsIm5leHRTdGF0ZSIsInN0cmVhbU91dHB1dCIsIm5leHRTb3VyY2UkIiwiZGlmZiIsIm5leHRpbnN0YW5jZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUdPLElBQU1BLGVBQWUsY0FBckI7O0FBRVAsQUFBTyxTQUFTQyxlQUFULENBQXVCQyxJQUF2QixFQUE2QkMsTUFBN0IsRUFBOEM7OztNQUM3Q0MsUUFBUUMsT0FBT0MsTUFBUCxDQUFjLEVBQWQsRUFBa0JILE1BQWxCLENBQWQ7O29DQUQ2Q0ksSUFBTTtRQUFBOzs7TUFFN0NDLGNBQWNELEtBQUtFLE1BQUwsR0FBYyxDQUFsQztNQUNNQyxjQUFjRixjQUFjLFlBQUdHLE1BQUgsYUFBYUosSUFBYixDQUFkLEdBQW1DLEVBQXZEO1FBQ01LLFFBQU4sR0FBaUJGLFlBQ2RHLE1BRGMsQ0FDUDtX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
364 |
--------------------------------------------------------------------------------
/demos/components/blink.js:
--------------------------------------------------------------------------------
1 | /** @jsx createElement */
2 | import {mount, createElement, Component, createHandler} from '../../reactive-react'
3 | import {Interval, scan, startWith, merge, mapToConstant} from '../../reactive-react/swyxjs'
4 | import Observable from 'zen-observable'
5 |
6 | export default class Blink extends Component {
7 | // more fun time demo
8 | // initialState = true // proper
9 | initialState = 0 // hacky
10 | source($) {
11 | // there is a bug right now where switching sources subscribes to the new source twice
12 | // havent been able to chase it down so i had to do this hacky thing
13 | // i'm sorry :( breaking demos last minute before talk sucks
14 | // const reducer = x => !x // the proper reducer
15 | const reducer = (acc, x) => acc + x // hacky reducer
16 | const source = Interval(500, 1) // tick every second
17 | return {source, reducer}
18 | }
19 | render(state) {
20 | const style = {
21 | visibility: ((state/2 + 1) % 2) ? // hacky
22 | 'visible' :
23 | 'hidden'}
24 | return Bring back the blink tag!
25 | }
26 | }
--------------------------------------------------------------------------------
/demos/components/button.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | /* BonBon Buttons 1.1 by simurai.com
4 |
5 | 1.1 Added unprefixed attributes, :focus style,