/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Copyright (C) 2018 Michael Czechowski * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; version 2. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { ElementRef, Input, Directive } from '@angular/core'; import * as Selection from 'd3-selection'; import * as Shape from 'd3-shape'; import { NlsCanvasService } from './../services/canvas.service'; import { NlsMathService } from './../services/math.service'; import { NlsGraphService } from '../services/graph.service'; export class NlsGuillocheDirective { /** * @param {?} canvasService * @param {?} el * @param {?} math * @param {?} graphService */ constructor(canvasService, el, math, graphService) { this.canvasService = canvasService; this.el = el; this.math = math; this.graphService = graphService; } /** * @return {?} */ ngOnDestroy() { this.group.selectAll('*').remove(); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { this.group = Selection.select(this.el.nativeElement); this.canvas = Selection.select(this.canvasService.get); // @todo modify graph here instead of in graphs.component.ts this.initialNodes = this.graph.nodes.slice(); this.initialCurve = [ this.graph.start.point, this.graph.start.direction, ...this.graph.nodes.slice(), this.graph.end.direction, this.graph.end.point ]; this.medianPoint = this.math.medianOfCurve(this.initialCurve); this.medianIndex = this.math.medianIndex(this.initialCurve); if (this.animation) { this.graph.nodes = this.graph.nodes.slice().map((node, i) => { return { x: node.x, y: node.y, // ascent: Math.round(Math.random() * 100) / 100 ascent: this.medianPoint.ascent + i * 0.5 }; }); this.bounces = this.initialNodes.map(node => { /** @type {?} */ const bounceAmplitude = Math.round(Math.random() * 150); return this.math.bounce(bounceAmplitude, 3); }); /** @type {?} */ let i = 0; this.animationInterval = setInterval(() => { this.animateGraph(i++ % 1000 / 10000); }, this.graph.interval); } else { if (this.animationInterval) { this.bounce = null; clearInterval(this.animationInterval); } } this.group.selectAll('*').remove(); this.pathElements = []; /** @type {?} */ const graphs = this.spreadLines([ this.graph.start.point, this.graph.start.direction, ...this.graph.nodes, this.graph.end.direction, this.graph.end.point, ]).forEach((points, index) => this.drawGraph(points)); } /** * @param {?} x * @return {?} */ animateGraph(x) { /** @type {?} */ const graphs = this.spreadLines([ this.graph.start.point, this.graph.start.direction, ...this.graph.nodes.map((point, i) => { /** @type {?} */ const ascent = point.ascent * Math.sin(Math.PI * x); return this.graphService.shiftPoint(point, ascent, this.bounces[i].next().value); }), this.graph.end.direction, this.graph.end.point, ]); graphs.forEach((points, i) => this.updateGraph(points, i)); } /** * @param {?} points * @return {?} */ spreadLines(points) { /** @type {?} */ const shiftedMedians = []; /** @type {?} */ const genshiftedMedians = this.graphService.spreadOrthogonal(this.medianPoint, this.graph.spread.spacing); for (let i = 0; i < this.graph.spread.amount; i++) { shiftedMedians.push(genshiftedMedians.next().value); } return shiftedMedians.map(median => { /** @type {?} */ const shiftedPoints = points.slice(); shiftedPoints.splice(this.medianIndex, 1, median); return shiftedPoints; }); } /** * @param {?} points * @param {?} index * @return {?} */ updateGraph(points, index) { this.pathElements[index] .attr('d', Shape.line() .x(p => p.x) .y(p => p.y) .curve(Shape.curveBasis)(points)); } /** * @param {?} points * @return {?} */ drawGraph(points) { this.group .attr('stroke', this.graph.color) .attr('stroke-width', this.graph.stroke) .attr('fill', 'none'); this.pathElements.push(this.group.append('path') .attr('d', Shape.line() .x(p => p.x) .y(p => p.y) .curve(Shape.curveBasis)(points))); } /** * @param {?} points * @return {?} */ debugGraph(points) { points.forEach((point, index) => { /** @type {?} */ const circle = this.group.append('g'); circle.append('circle') .attr('cx', point.x) .attr('cy', point.y) .attr('r', 3) .attr('fill-opacity', 0.6) .attr('fill', this.graph.color); circle.append('text') .attr('x', point.x) .attr('y', point.y) .attr('dx', 8) .attr('dy', 15) .attr('fill', this.graph.color) .text(index); }); } } NlsGuillocheDirective.decorators = [ { type: Directive, args: [{ selector: '[nlsGuilloche]' },] }, ]; /** @nocollapse */ NlsGuillocheDirective.ctorParameters = () => [ { type: NlsCanvasService }, { type: ElementRef }, { type: NlsMathService }, { type: NlsGraphService } ]; NlsGuillocheDirective.propDecorators = { graph: [{ type: Input }], animation: [{ type: Input }] }; function NlsGuillocheDirective_tsickle_Closure_declarations() { /** @type {?} */ NlsGuillocheDirective.prototype.canvas; /** @type {?} */ NlsGuillocheDirective.prototype.group; /** @type {?} */ NlsGuillocheDirective.prototype.bounce; /** @type {?} */ NlsGuillocheDirective.prototype.bounces; /** @type {?} */ NlsGuillocheDirective.prototype.initialNodes; /** @type {?} */ NlsGuillocheDirective.prototype.initialCurve; /** @type {?} */ NlsGuillocheDirective.prototype.animationInterval; /** @type {?} */ NlsGuillocheDirective.prototype.medianPoint; /** @type {?} */ NlsGuillocheDirective.prototype.medianIndex; /** @type {?} */ NlsGuillocheDirective.prototype.pathElements; /** @type {?} */ NlsGuillocheDirective.prototype.graph; /** @type {?} */ NlsGuillocheDirective.prototype.animation; /** @type {?} */ NlsGuillocheDirective.prototype.canvasService; /** @type {?} */ NlsGuillocheDirective.prototype.el; /** @type {?} */ NlsGuillocheDirective.prototype.math; /** @type {?} */ NlsGuillocheDirective.prototype.graphService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3VpbGxvY2hlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25scy1ndWlsbG9jaGUvIiwic291cmNlcyI6WyJubHMvZGlyZWN0aXZlcy9ndWlsbG9jaGUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnQkEsT0FBTyxFQUFFLFVBQVUsRUFBZ0IsS0FBSyxFQUFFLFNBQVMsRUFBdUMsTUFBTSxlQUFlLENBQUM7QUFDaEgsT0FBTyxLQUFLLFNBQVMsTUFBTSxjQUFjLENBQUM7QUFDMUMsT0FBTyxLQUFLLEtBQUssTUFBTSxVQUFVLENBQUM7QUFRbEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzVELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUs1RCxNQUFNOzs7Ozs7O0lBZ0JKLFlBQ1UsZUFDQSxJQUNBLE1BQ0E7UUFIQSxrQkFBYSxHQUFiLGFBQWE7UUFDYixPQUFFLEdBQUYsRUFBRTtRQUNGLFNBQUksR0FBSixJQUFJO1FBQ0osaUJBQVksR0FBWixZQUFZO0tBRXJCOzs7O0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0tBQ3BDOzs7OztJQUVELFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7UUFFdkQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxL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RUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQztpQkFDOUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ2hCLENBQUMsQ0FBQzs7OztZQXhKTixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGdCQUFnQjthQUMzQjs7OztZQU5RLGdCQUFnQjtZQVZoQixVQUFVO1lBV1YsY0FBYztZQUNkLGVBQWU7OztvQkFrQnJCLEtBQUs7d0JBQ0wsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChDKSAyMDE4IE1pY2hhZWwgQ3plY2hvd3NraSA8bWFpbEBkYWlseXNoLml0PlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXRcbiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlXG4gKiBTb2Z0d2FyZSBGb3VuZGF0aW9uOyB2ZXJzaW9uIDIuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3JcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvclxuICogbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGhcbiAqIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1MVxuICogRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EuXG4gKi9cblxuaW1wb3J0IHsgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbnB1dCwgRGlyZWN0aXZlLCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgU2VsZWN0aW9uIGZyb20gJ2QzLXNlbGVjdGlvbic7XG5pbXBvcnQgKiBhcyBTaGFwZSBmcm9tICdkMy1zaGFwZSc7XG5pbXBvcnQgKiBhcyBSYW5kb20gZnJvbSAnZDMtcmFuZG9tJztcbmltcG9ydCAqIGFzIERyYWcgZnJvbSAnZDMtZHJhZyc7XG5pbXBvcnQgKiBhcyBFYXNlIGZyb20gJ2QzLWVhc2UnO1xuaW1wb3J0ICogYXMgVGltZXIgZnJvbSAnZDMtdGltZXInO1xuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vLi4vbW9kZWxzL2dyYXBoLm1vZGVsJztcbmltcG9ydCB7IFBvaW50IH0gZnJvbSAnLi8uLi9tb2RlbHMvcG9pbnQubW9kZWwnO1xuaW1wb3J0IHsgTmxzQ2FudmFzU2VydmljZSB9IGZyb20gJy4vLi4vc2VydmljZXMvY2FudmFzLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmxzTWF0aFNlcnZpY2UgfSBmcm9tICcuLy4uL3NlcnZpY2VzL21hdGguc2VydmljZSc7XG5pbXBvcnQgeyBObHNHcmFwaFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9ncmFwaC5zZXJ2aWNlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW25sc0d1aWxsb2NoZV0nXG59KVxuZXhwb3J0IGNsYXNzIE5sc0d1aWxsb2NoZURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcblxuICBwcml2YXRlIGNhbnZhczogYW55O1xuICBwcml2YXRlIGdyb3VwOiBhbnk7XG4gIHByaXZhdGUgYm91bmNlOiBhbnkgfCBudWxsO1xuICBwcml2YXRlIGJvdW5jZXM6IGFueSB8IG51bGw7XG4gIHByaXZhdGUgaW5pdGlhbE5vZGVzOiBhbnk7XG4gIHByaXZhdGUgaW5pdGlhbEN1cnZlOiBhbnk7XG4gIHByaXZhdGUgYW5pbWF0aW9uSW50ZXJ2YWw6IGFueTtcbiAgcHJpdmF0ZSBtZWRpYW5Qb2ludDogUG9pbnQ7XG4gIHByaXZhdGUgbWVkaWFuSW5kZXg6IG51bWJlcjtcbiAgcHJpdmF0ZSBwYXRoRWxlbWVudHM6IGFueTtcblxuICBASW5wdXQoKSBncmFwaDogR3JhcGg7XG4gIEBJbnB1dCgpIGFuaW1hdGlvbjogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNhbnZhc1NlcnZpY2U6IE5sc0NhbnZhc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIG1hdGg6IE5sc01hdGhTZXJ2aWNlLFxuICAgIHByaXZhdGUgZ3JhcGhTZXJ2aWNlOiBObHNHcmFwaFNlcnZpY2VcbiAgKSB7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmdyb3VwLnNlbGVjdEFsbCgnKicpLnJlbW92ZSgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIHRoaXMuZ3JvdXAgPSBTZWxlY3Rpb24uc2VsZWN0KHRoaXMuZWwubmF0aXZlRWxlbWVudCk7XG4gICAgdGhpcy5jYW52YXMgPSBTZWxlY3Rpb24uc2VsZWN0KHRoaXMuY2FudmFzU2VydmljZS5nZXQpO1xuICAgIC8vIEB0b2RvIG1vZGlmeSBncmFwaCBoZXJlIGluc3RlYWQgb2YgaW4gZ3JhcGhzLmNvbXBvbmVudC50c1xuICAgIHRoaXMuaW5pdGlhbE5vZGVzID0gdGhpcy5ncmFwaC5ub2Rlcy5zbGljZSgpO1xuICAgIHRoaXMuaW5pdGlhbEN1cnZlID0gW1xuICAgICAgdGhpcy5ncmFwaC5zdGFydC5wb2ludCxcbiAgICAgIHRoaXMuZ3JhcGguc3RhcnQuZGlyZWN0aW9uLFxuICAgICAgLi4udGhpcy5ncmFwaC5ub2Rlcy5zbGljZSgpLFxuICAgICAgdGhpcy5ncmFwaC5lbmQuZGlyZWN0aW9uLFxuICAgICAgdGhpcy5ncmFwaC5lbmQucG9pbnRcbiAgICBdO1xuICAgIHRoaXMubWVkaWFuUG9pbnQgPSB0aGlzLm1hdGgubWVkaWFuT2ZDdXJ2ZSh0aGlzLmluaXRpYWxDdXJ2ZSk7XG4gICAgdGhpcy5tZWRpYW5JbmRleCA9IHRoaXMubWF0aC5tZWRpYW5JbmRleCh0aGlzLmluaXRpYWxDdXJ2ZSk7XG5cbiAgICBpZiAodGhpcy5hbmltYXRpb24pIHtcbiAgICAgIHRoaXMuZ3JhcGgubm9kZXMgPSB0aGlzLmdyYXBoLm5vZGVzLnNsaWNlKCkubWFwKChub2RlLCBpKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgeDogbm9kZS54LFxuICAgICAgICAgIHk6IG5vZGUueSxcbiAgICAgICAgICAvLyBhc2NlbnQ6IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIDEwMCkgLyAxMDBcbiAgICAgICAgICBhc2NlbnQ6IHRoaXMubWVkaWFuUG9pbnQuYXNjZW50ICsgaSAqIDAuNVxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICB0aGlzLmJvdW5jZXMgPSB0aGlzLmluaXRpYWxOb2Rlcy5tYXAobm9kZSA9PiB7XG4gICAgICAgIGNvbnN0IGJvdW5jZUFtcGxpdHVkZSA9IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIDE1MCk7XG4gICAgICAgIHJldHVybiB0aGlzLm1hdGguYm91bmNlKGJvdW5jZUFtcGxpdHVkZSwgMyk7XG4gICAgICB9KTtcbiAgICAgIGxldCBpID0gMDtcbiAgICAgIHRoaXMuYW5pbWF0aW9uSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYW5pbWF0ZUdyYXBoKGkrKyAlIDEwMDAgLyAxMDAwMCk7XG4gICAgICB9LCB0aGlzLmdyYXBoLmludGVydmFsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuYW5pbWF0aW9uSW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5ib3VuY2UgPSBudWxsO1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuYW5pbWF0aW9uSW50ZXJ2YWwpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZ3JvdXAuc2VsZWN0QWxsKCcqJykucmVtb3ZlKCk7XG4gICAgdGhpcy5wYXRoRWxlbWVudHMgPSBbXTtcblxuICAgIGNvbnN0IGdyYXBocyA9IHRoaXMuc3ByZWFkTGluZXMoW1xuICAgICAgdGhpcy5ncmFwaC5zdGFydC5wb2ludCxcbiAgICAgIHRoaXMuZ3JhcGguc3RhcnQuZGlyZWN0aW9uLFxuICAgICAgLi4udGhpcy5ncmFwaC5ub2RlcyxcbiAgICAgIHRoaXMuZ3JhcGguZW5kLmRpcmVjdGlvbixcbiAgICAgIHRoaXMuZ3JhcGguZW5kLnBvaW50LFxuICAgIF0pLmZvckVhY2goKHBvaW50cywgaW5kZXgpID0+IHRoaXMuZHJhd0dyYXBoKHBvaW50cykpO1xuICB9XG5cbiAgcHJpdmF0ZSBhbmltYXRlR3JhcGgoeCkge1xuICAgIGNvbnN0IGdyYXBocyA9IHRoaXMuc3ByZWFkTGluZXMoW1xuICAgICAgdGhpcy5ncmFwaC5zdGFydC5wb2ludCxcbiAgICAgIHRoaXMuZ3JhcGguc3RhcnQuZGlyZWN0aW9uLFxuICAgICAgLi4udGhpcy5ncmFwaC5ub2Rlcy5tYXAoKHBvaW50LCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGFzY2VudCA9IHBvaW50LmFzY2VudCAqIE1hdGguc2luKE1hdGguUEkgKiB4KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JhcGhTZXJ2aWNlLnNoaWZ0UG9pbnQocG9pbnQsIGFzY2VudCwgdGhpcy5ib3VuY2VzW2ldLm5leHQoKS52YWx1ZSk7XG4gICAgICB9KSxcbiAgICAgIHRoaXMuZ3JhcGguZW5kLmRpcmVjdGlvbixcbiAgICAgIHRoaXMuZ3JhcGguZW5kLnBvaW50LFxuICAgIF0pO1xuXG4gICAgZ3JhcGhzLmZvckVhY2goKHBvaW50cywgaSkgPT4gdGhpcy51cGRhdGVHcmFwaChwb2ludHMsIGkpKTtcbiAgfVxuXG4gIHByaXZhdGUgc3ByZWFkTGluZXMocG9pbnRzOiBQb2ludFtdKSB7XG4gICAgY29uc3Qgc2hpZnRlZE1lZGlhbnMgPSBbXTtcbiAgICBjb25zdCBnZW5zaGlmdGVkTWVkaWFucyA9IHRoaXMuZ3JhcGhTZXJ2aWNlLnNwcmVhZE9ydGhvZ29uYWwodGhpcy5tZWRpYW5Qb2ludCwgdGhpcy5ncmFwaC5zcHJlYWQuc3BhY2luZyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZ3JhcGguc3ByZWFkLmFtb3VudDsgaSsrKSB7XG4gICAgICBzaGlmdGVkTWVkaWFucy5wdXNoKGdlbnNoaWZ0ZWRNZWRpYW5zLm5leHQoKS52YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNoaWZ0ZWRNZWRpYW5zLm1hcChtZWRpYW4gPT4ge1xuICAgICAgY29uc3Qgc2hpZnRlZFBvaW50cyA9IHBvaW50cy5zbGljZSgpO1xuICAgICAgc2hpZnRlZFBvaW50cy5zcGxpY2UodGhpcy5tZWRpYW5JbmRleCwgMSwgbWVkaWFuKTtcbiAgICAgIHJldHVybiBzaGlmdGVkUG9pbnRzO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVHcmFwaChwb2ludHM6IFBvaW50W10sIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnBhdGhFbGVtZW50c1tpbmRleF1cbiAgICAgIC5hdHRyKCdkJywgU2hhcGUubGluZSgpXG4gICAgICAgIC54KHAgPT4gcC54KVxuICAgICAgICAueShwID0+IHAueSlcbiAgICAgICAgLmN1cnZlKFNoYXBlLmN1cnZlQmFzaXMpKHBvaW50cykpO1xuICB9XG5cbiAgcHJpdmF0ZSBkcmF3R3JhcGgocG9pbnRzOiBQb2ludFtdKTogdm9pZCB7XG4gICAgdGhpcy5ncm91cFxuICAgICAgLmF0dHIoJ3N0cm9rZScsIHRoaXMuZ3JhcGguY29sb3IpXG4gICAgICAuYXR0cignc3Ryb2tlLXdpZHRoJywgdGhpcy5ncmFwaC5zdHJva2UpXG4gICAgICAuYXR0cignZmlsbCcsICdub25lJyk7XG5cbiAgICB0aGlzLnBhdGhFbGVtZW50cy5wdXNoKFxuICAgICAgdGhpcy5ncm91cC5hcHBlbmQoJ3BhdGgnKVxuICAgICAgICAuYXR0cignZCcsIFNoYXBlLmxpbmUoKVxuICAgICAgICAgIC54KHAgPT4gcC54KVxuICAgICAgICAgIC55KHAgPT4gcC55KVxuICAgICAgICAgIC5jdXJ2ZShTaGFwZS5jdXJ2ZUJhc2lzKShwb2ludHMpKSk7XG4gIH1cblxuICBwcml2YXRlIGRlYnVnR3JhcGgocG9pbnRzOiBQb2ludFtdKSB7XG4gICAgcG9pbnRzLmZvckVhY2goKHBvaW50LCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgY2lyY2xlID0gdGhpcy5ncm91cC5hcHBlbmQoJ2cnKTtcblxuICAgICAgY2lyY2xlLmFwcGVuZCgnY2lyY2xlJylcbiAgICAgICAgLmF0dHIoJ2N4JywgcG9pbnQueClcbiAgICAgICAgLmF0dHIoJ2N5JywgcG9pbnQueSlcbiAgICAgICAgLmF0dHIoJ3InLCAzKVxuICAgICAgICAuYXR0cignZmlsbC1vcGFjaXR5JywgMC42KVxuICAgICAgICAuYXR0cignZmlsbCcsIHRoaXMuZ3JhcGguY29sb3IpO1xuXG4gICAgICBjaXJjbGUuYXBwZW5kKCd0ZXh0JylcbiAgICAgICAgLmF0dHIoJ3gnLCBwb2ludC54KVxuICAgICAgICAuYXR0cigneScsIHBvaW50LnkpXG4gICAgICAgIC5hdHRyKCdkeCcsIDgpXG4gICAgICAgIC5hdHRyKCdkeScsIDE1KVxuICAgICAgICAuYXR0cignZmlsbCcsIHRoaXMuZ3JhcGguY29sb3IpXG4gICAgICAgIC50ZXh0KGluZGV4KTtcbiAgICB9KTtcbiAgfVxufVxuIl19