UNPKG

ngx-antv-f2

Version:

Functional Antvis/F2 wrapper for Angular.

918 lines (893 loc) 86.1 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@antv/f2/lib/core'), require('@angular/common'), require('@antv/f2/lib/geom/'), require('@antv/f2/lib/coord/polar'), require('@antv/f2/lib/component/axis/circle'), require('@antv/f2/lib/geom/adjust/'), require('@antv/f2/lib/scale/time-cat'), require('@antv/f2/lib/plugin/tooltip'), require('@antv/f2/lib/plugin/legend'), require('@antv/f2/lib/component/guide'), require('@antv/f2/lib/plugin/guide'), require('@antv/f2/lib/animation/detail'), require('@antv/f2/lib/interaction/'), require('@antv/f2/lib/plugin/scroll-bar')) : typeof define === 'function' && define.amd ? define('ngx-antv-f2', ['exports', '@angular/core', '@antv/f2/lib/core', '@angular/common', '@antv/f2/lib/geom/', '@antv/f2/lib/coord/polar', '@antv/f2/lib/component/axis/circle', '@antv/f2/lib/geom/adjust/', '@antv/f2/lib/scale/time-cat', '@antv/f2/lib/plugin/tooltip', '@antv/f2/lib/plugin/legend', '@antv/f2/lib/component/guide', '@antv/f2/lib/plugin/guide', '@antv/f2/lib/animation/detail', '@antv/f2/lib/interaction/', '@antv/f2/lib/plugin/scroll-bar'], factory) : (factory((global['ngx-antv-f2'] = {}),global.ng.core,null,global.ng.common,null,null,null,null,null,null,null,null,null,null,null,null)); }(this, (function (exports,core,F2,common,Geom,CoordPolar,AxisCircle,Adjust,ScaleTimeCat,Tooltip,Legend,GuideComponent,GuidePlugin,Animation,Interaction,ScrollBar) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/13 * \@Description: 配置坐标轴 */ var F2Axis = (function () { function F2Axis() { } /** * @param {?} chart * @return {?} */ F2Axis.prototype.setChartAxis = /** * @param {?} chart * @return {?} */ function (chart) { if (this.disabled === true) { chart.axis(false); } else { chart.axis(this.option[0], this.option[1]); } }; F2Axis.decorators = [ { type: core.Component, args: [{ selector: 'f2-axis', template: '' },] }, ]; F2Axis.propDecorators = { disabled: [{ type: core.Input }], option: [{ type: core.Input }] }; return F2Axis; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/13 * \@Description: 装载数据 */ var F2Source = (function () { function F2Source() { this.dataChange = new core.EventEmitter(); } /** * @param {?} changes * @return {?} */ F2Source.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { if (changes["data"]) { this.dataChange.next(true); } }; /** * @param {?} chart * @return {?} */ F2Source.prototype.setChartSource = /** * @param {?} chart * @return {?} */ function (chart) { chart.source(this.data, this.colDefs); }; F2Source.decorators = [ { type: core.Component, args: [{ selector: 'f2-source', template: '' },] }, ]; F2Source.propDecorators = { data: [{ type: core.Input }], colDefs: [{ type: core.Input }], dataChange: [{ type: core.Output }] }; return F2Source; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/13 * \@Description: */ var F2Geometry = (function () { function F2Geometry() { } /** * @param {?} chart * @return {?} */ F2Geometry.prototype.setChartGeometry = /** * @param {?} chart * @return {?} */ function (chart) { /** @type {?} */ var geom; /** @type {?} */ var geomType = this.type; if (geomType === 'point') { geom = chart.point(); } else if (geomType === 'path') { geom = chart.path(); } else if (geomType === 'line') { geom = chart.line(); } else if (geomType === 'area') { geom = chart.area(); } else if (geomType === 'interval') { geom = chart.interval(); } else if (geomType === 'polygon') { geom = chart.polygon(); } else if (geomType === 'schema') { geom = chart.schema(); } if (this.position) { geom.position(this.position); } if (this.color) { if (Array.isArray(this.color)) { geom.color(this.color[0], this.color[1]); } else { geom.color(this.color); } } if (this.shape) { geom.shape(this.shape); } if (this.size) { geom.size(this.size); } if (this.adjust) { geom.adjust(this.adjust); } if (this.style) { geom.style(this.style); } if (this.animate !== undefined) { geom.animate(this.animate); } }; F2Geometry.decorators = [ { type: core.Component, args: [{ selector: 'f2-geometry', template: '' },] }, ]; F2Geometry.propDecorators = { type: [{ type: core.Input }], config: [{ type: core.Input }], position: [{ type: core.Input }], color: [{ type: core.Input }], shape: [{ type: core.Input }], size: [{ type: core.Input }], adjust: [{ type: core.Input }], style: [{ type: core.Input }], animate: [{ type: core.Input }] }; return F2Geometry; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/13 * \@Description: 极坐标系 */ var F2CoordPolar = (function () { function F2CoordPolar() { } /** * @param {?} chart * @return {?} */ F2CoordPolar.prototype.setChartCoord = /** * @param {?} chart * @return {?} */ function (chart) { if (this.config) { chart.coord('polar', this.config); } else { chart.coord('polar'); } }; F2CoordPolar.decorators = [ { type: core.Component, args: [{ selector: 'f2-coord-polar', template: '' },] }, ]; F2CoordPolar.propDecorators = { config: [{ type: core.Input }] }; return F2CoordPolar; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/13 * \@Description: 配置图例 */ var F2Legend = (function () { function F2Legend() { } /** * @param {?} chart * @return {?} */ F2Legend.prototype.setChartLegend = /** * @param {?} chart * @return {?} */ function (chart) { chart.legend(this.config); }; F2Legend.decorators = [ { type: core.Component, args: [{ selector: 'f2-legend', template: '' },] }, ]; F2Legend.propDecorators = { config: [{ type: core.Input }] }; return F2Legend; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/13 * \@Description: 笛卡尔坐标系 */ var F2CoordRect = (function () { function F2CoordRect() { } /** * @param {?} chart * @return {?} */ F2CoordRect.prototype.setChartCoord = /** * @param {?} chart * @return {?} */ function (chart) { if (this.config) { chart.coord('rect', this.config); } else { chart.coord('rect'); } }; F2CoordRect.decorators = [ { type: core.Component, args: [{ selector: 'f2-coord-rect', template: '' },] }, ]; F2CoordRect.propDecorators = { config: [{ type: core.Input }] }; return F2CoordRect; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/13 * \@Description: * 1.chart.tooltip(false); * 2.chart.tooltip({...}); */ var F2Tooltip = (function () { function F2Tooltip() { } /** * @param {?} chart * @return {?} */ F2Tooltip.prototype.setChartTooltip = /** * @param {?} chart * @return {?} */ function (chart) { if (this.disabled === true) { chart.tooltip(false); } else { chart.tooltip(this.config); } return chart; }; F2Tooltip.decorators = [ { type: core.Component, args: [{ selector: 'f2-tooltip', template: '' },] }, ]; F2Tooltip.propDecorators = { disabled: [{ type: core.Input }], config: [{ type: core.Input }] }; return F2Tooltip; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/17 * \@Description: 绘制图表的辅助元素 */ var F2Guide = (function () { function F2Guide() { } /** * @param {?} chart * @return {?} */ F2Guide.prototype.setChartGuide = /** * @param {?} chart * @return {?} */ function (chart) { if (this.type === 'line') { chart.guide().line(this.config); } else if (this.type === 'text') { chart.guide().text(this.config); } else if (this.type === 'point') { chart.guide().point(this.config); } else if (this.type === 'tag') { chart.guide().tag(this.config); } else if (this.type === 'rect') { chart.guide().rect(this.config); } else if (this.type === 'html') { chart.guide().html(this.config); } else if (this.type === 'arc') { chart.guide().arc(this.config); } else if (this.type === 'regionFilter') { chart.guide().regionFilter(this.config); } }; F2Guide.decorators = [ { type: core.Component, args: [{ selector: 'f2-guide', template: '' },] }, ]; F2Guide.propDecorators = { type: [{ type: core.Input }], config: [{ type: core.Input }] }; return F2Guide; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/17 * \@Description: */ var F2Animate = (function () { function F2Animate() { } /** * @param {?} chart * @return {?} */ F2Animate.prototype.setChartAnimate = /** * @param {?} chart * @return {?} */ function (chart) { if (this.disabled === true) { chart.animate(false); } else { chart.animate(this.config); } }; F2Animate.decorators = [ { type: core.Component, args: [{ selector: 'f2-animate', template: "" },] }, ]; F2Animate.propDecorators = { disabled: [{ type: core.Input }], config: [{ type: core.Input }] }; return F2Animate; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/17 * \@Description: 交互机制 */ var F2Interaction = (function () { function F2Interaction() { } /** * @param {?} chart * @return {?} */ F2Interaction.prototype.setChartInteraction = /** * @param {?} chart * @return {?} */ function (chart) { chart.interaction(this.option[0], this.option[1]); }; F2Interaction.decorators = [ { type: core.Component, args: [{ selector: 'f2-interaction', template: "" },] }, ]; F2Interaction.propDecorators = { option: [{ type: core.Input }] }; return F2Interaction; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/17 * \@Description: */ var F2PieLabel = (function () { function F2PieLabel() { } /** * @param {?} chart * @return {?} */ F2PieLabel.prototype.setChartPieLabel = /** * @param {?} chart * @return {?} */ function (chart) { chart.pieLabel(this.config); }; F2PieLabel.decorators = [ { type: core.Component, args: [{ selector: 'f2-pie-label', template: '' },] }, ]; F2PieLabel.propDecorators = { config: [{ type: core.Input }] }; return F2PieLabel; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/17 * \@Description: */ var F2ScrollBar = (function () { function F2ScrollBar() { } /** * @param {?} chart * @return {?} */ F2ScrollBar.prototype.setChartScrollBar = /** * @param {?} chart * @return {?} */ function (chart) { chart.scrollBar(this.config); }; F2ScrollBar.decorators = [ { type: core.Component, args: [{ selector: 'f2-scroll-bar', template: '' },] }, ]; F2ScrollBar.propDecorators = { config: [{ type: core.Input }] }; return F2ScrollBar; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var F2Chart = (function () { function F2Chart() { this.config = {}; /** * 自定义渲染事件 */ this.customRender = new core.EventEmitter(); } /** * @param {?} event * @return {?} */ F2Chart.prototype.onResize = /** * @param {?} event * @return {?} */ function (event) { // this.render(); }; /** * @return {?} */ F2Chart.prototype.ngAfterViewInit = /** * @return {?} */ function () { this.render(); if (this.source) { this.source.dataChange.subscribe(function (changes) { console.log(changes); }); } }; /** * @return {?} */ F2Chart.prototype.ngOnDestroy = /** * @return {?} */ function () { this.destroy(); }; /** * @return {?} */ F2Chart.prototype.render = /** * @return {?} */ function () { var _this = this; this.chart = new F2.Chart(Object.assign({ el: this.canvas.nativeElement, width: window.innerWidth, height: window.innerWidth > window.innerHeight ? (window.innerHeight - 54) : window.innerWidth * 0.707, pixelRatio: window.devicePixelRatio }, this.config)); // 回传chart,自定义渲染 if (this.preventRender === true) { this.customRender.emit(this.chart); return; } if (this.source && this.source.data) { this.source.setChartSource(this.chart); } else { return; } if (this.legend) { this.legend.setChartLegend(this.chart); } // Coordinate if (this.coordRect) { this.coordRect.setChartCoord(this.chart); } if (this.coordPolar) { this.coordPolar.setChartCoord(this.chart); } // axis if (this.axisList && this.axisList.length > 0) { this.axisList.forEach(function (axis) { axis.setChartAxis(_this.chart); }); } // tooltip if (this.tooltip) { this.tooltip.setChartTooltip(this.chart); } // geometry if (this.geometryList && this.geometryList.length > 0) { this.geometryList.forEach(function (geometry) { geometry.setChartGeometry(_this.chart); }); } // guide if (this.guide) { this.guide.setChartGuide(this.chart); } // animate if (this.animate) { this.animate.setChartAnimate(this.chart); } // pieLabel if (this.pieLabel) { this.pieLabel.setChartPieLabel(this.chart); } // scrollBar if (this.scrollBar) { this.scrollBar.setChartScrollBar(this.chart); } this.chart.render(); // interaction if (this.interaction) { this.interaction.setChartInteraction(this.chart); } }; /** * @return {?} */ F2Chart.prototype.repaint = /** * @return {?} */ function () { this.chart.repaint(); }; /** * @return {?} */ F2Chart.prototype.rerender = /** * @return {?} */ function () { this.destroy(); this.render(); }; /** * @return {?} */ F2Chart.prototype.destroy = /** * @return {?} */ function () { if (this.chart) { this.chart.destroy(); } }; F2Chart.decorators = [ { type: core.Component, args: [{ selector: 'f2-chart', template: "\n <div>\n <canvas #canvas></canvas>\n </div>\n <ng-content></ng-content>\n ", },] }, ]; /** @nocollapse */ F2Chart.ctorParameters = function () { return []; }; F2Chart.propDecorators = { config: [{ type: core.Input }], preventRender: [{ type: core.Input }], customRender: [{ type: core.Output }], canvas: [{ type: core.ViewChild, args: ['canvas',] }], source: [{ type: core.ContentChild, args: [F2Source,] }], geometryList: [{ type: core.ContentChildren, args: [F2Geometry,] }], axisList: [{ type: core.ContentChildren, args: [F2Axis,] }], coordRect: [{ type: core.ContentChild, args: [F2CoordRect,] }], coordPolar: [{ type: core.ContentChild, args: [F2CoordPolar,] }], legend: [{ type: core.ContentChild, args: [F2Legend,] }], tooltip: [{ type: core.ContentChild, args: [F2Tooltip,] }], guide: [{ type: core.ContentChild, args: [F2Guide,] }], animate: [{ type: core.ContentChild, args: [F2Animate,] }], interaction: [{ type: core.ContentChild, args: [F2Interaction,] }], pieLabel: [{ type: core.ContentChild, args: [F2PieLabel,] }], scrollBar: [{ type: core.ContentChild, args: [F2ScrollBar,] }], onResize: [{ type: core.HostListener, args: ['window:resize', ['$event'],] }] }; return F2Chart; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/13 * \@Description: 为数据字段进行列定义 */ var F2Scale = (function () { function F2Scale() { } F2Scale.decorators = [ { type: core.Component, args: [{ selector: 'f2-scale', template: "" },] }, ]; F2Scale.propDecorators = { field: [{ type: core.Input }], colDef: [{ type: core.Input }] }; return F2Scale; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @author CK * \@date 2019/1/16 * \@Description: */ var F2GeomPoint = (function () { function F2GeomPoint() { } F2GeomPoint.decorators = [ { type: core.Component, args: [{ selector: 'f2-geom-point', template: '' },] }, ]; F2GeomPoint.propDecorators = { config: [{ type: core.Input }], position: [{ type: core.Input }], color: [{ type: core.Input }], shape: [{ type: core.Input }], size: [{ type: core.Input }], adjust: [{ type: core.Input }], style: [{ type: core.Input }], animate: [{ type: core.Input }] }; return F2GeomPoint; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ F2.Chart.plugins.register([ Geom, CoordPolar, AxisCircle, Adjust, ScaleTimeCat, Animation, GuideComponent, GuidePlugin, Tooltip, Legend, Interaction, ScrollBar ]); /** @type {?} */ var F2Component = [ F2Chart, F2Source, F2Geometry, F2GeomPoint, F2Scale, F2CoordPolar, F2CoordRect, F2Legend, F2Axis, F2Tooltip, F2Guide, F2Animate, F2Interaction, F2PieLabel, F2ScrollBar, ]; /** * // \@dynamic */ var F2Module = (function () { function F2Module() { } F2Module.decorators = [ { type: core.NgModule, args: [{ imports: [common.CommonModule], declarations: __spread(F2Component), exports: __spread(F2Component), },] }, ]; return F2Module; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ exports.F2Module = F2Module; exports.F2Axis = F2Axis; exports.F2Chart = F2Chart; exports.F2CoordPolar = F2CoordPolar; exports.F2CoordRect = F2CoordRect; exports.F2Geometry = F2Geometry; exports.F2Legend = F2Legend; exports.F2Scale = F2Scale; exports.F2Source = F2Source; exports.F2Tooltip = F2Tooltip; exports.F2GeomPoint = F2GeomPoint; exports.F2Guide = F2Guide; exports.F2Animate = F2Animate; exports.F2Interaction = F2Interaction; exports.F2PieLabel = F2PieLabel; exports.F2ScrollBar = F2ScrollBar; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWFudHYtZjIudW1kLmpzLm1hcCIsInNvdXJjZXMiOltudWxsLCJuZzovL25neC1hbnR2LWYyL2xpYi9iYXNpYy9mMi1heGlzLnRzIiwibmc6Ly9uZ3gtYW50di1mMi9saWIvYmFzaWMvZjItc291cmNlLnRzIiwibmc6Ly9uZ3gtYW50di1mMi9saWIvYmFzaWMvZjItZ2VvbWV0cnkudHMiLCJuZzovL25neC1hbnR2LWYyL2xpYi9iYXNpYy9mMi1jb29yZC1wb2xhci50cyIsIm5nOi8vbmd4LWFudHYtZjIvbGliL2Jhc2ljL2YyLWxlZ2VuZC50cyIsIm5nOi8vbmd4LWFudHYtZjIvbGliL2Jhc2ljL2YyLWNvb3JkLXJlY3QudHMiLCJuZzovL25neC1hbnR2LWYyL2xpYi9iYXNpYy9mMi10b29sdGlwLnRzIiwibmc6Ly9uZ3gtYW50di1mMi9saWIvYmFzaWMvZjItZ3VpZGUudHMiLCJuZzovL25neC1hbnR2LWYyL2xpYi9iYXNpYy9mMi1hbmltYXRlLnRzIiwibmc6Ly9uZ3gtYW50di1mMi9saWIvYmFzaWMvZjItaW50ZXJhY3Rpb24udHMiLCJuZzovL25neC1hbnR2LWYyL2xpYi9iYXNpYy9mMi1waWUtbGFiZWwudHMiLCJuZzovL25neC1hbnR2LWYyL2xpYi9iYXNpYy9mMi1zY3JvbGwtYmFyLnRzIiwibmc6Ly9uZ3gtYW50di1mMi9saWIvYmFzaWMvZjItY2hhcnQudHMiLCJuZzovL25neC1hbnR2LWYyL2xpYi9iYXNpYy9mMi1zY2FsZS50cyIsIm5nOi8vbmd4LWFudHYtZjIvbGliL2Jhc2ljL2YyLWdlb20tcG9pbnQudHMiLCJuZzovL25neC1hbnR2LWYyL2xpYi9iYXNpYy9mMi5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2VcclxudGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGVcclxuTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuXHJcblRISVMgQ09ERSBJUyBQUk9WSURFRCBPTiBBTiAqQVMgSVMqIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBBTlkgSU1QTElFRFxyXG5XQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLFxyXG5NRVJDSEFOVEFCTElUWSBPUiBOT04tSU5GUklOR0VNRU5ULlxyXG5cclxuU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXHJcbmFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIGlmIChlLmluZGV4T2YocFtpXSkgPCAwKVxyXG4gICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHJlc3VsdC52YWx1ZSk7IH0pLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIGV4cG9ydHMpIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKCFleHBvcnRzLmhhc093blByb3BlcnR5KHApKSBleHBvcnRzW3BdID0gbVtwXTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgcmVzdWx0W2tdID0gbW9kW2tdO1xyXG4gICAgcmVzdWx0LmRlZmF1bHQgPSBtb2Q7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnREZWZhdWx0KG1vZCkge1xyXG4gICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcclxufVxyXG4iLCJpbXBvcnQge0NvbXBvbmVudCwgSW5wdXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vKipcbiAqIEBhdXRob3IgQ0tcbiAqIEBkYXRlIDIwMTkvMS8xM1xuICogQERlc2NyaXB0aW9uOiDDqcKFwo3Dp8K9wq7DpcKdwpDDpsKgwofDqMK9wrRcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZjItYXhpcycsXG4gIHRlbXBsYXRlOiAnJ1xufSlcbmV4cG9ydCBjbGFzcyBGMkF4aXMge1xuXG4gIC8qKlxuICAgKiBjaGFydC5heGlzKGZhbHNlKVxuICAgKi9cbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW47XG5cblxuICAvKipcbiAgICogY2hhcnQuYXhpcyhmaWVsZCwgZmFsc2UpXG4gICAqIGNoYXJ0LmF4aXMoZmllbGQsIGNvbmZpZylcbiAgICovXG4gIEBJbnB1dCgpIG9wdGlvbjogW3N0cmluZywgb2JqZWN0XTtcblxuXG4gIHNldENoYXJ0QXhpcyhjaGFydDogYW55KSB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQgPT09IHRydWUpIHtcbiAgICAgIGNoYXJ0LmF4aXMoZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjaGFydC5heGlzKHRoaXMub3B0aW9uWzBdLCB0aGlzLm9wdGlvblsxXSk7XG4gICAgfVxuICB9XG5cbn1cbiIsImltcG9ydCB7Q29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCwgU2ltcGxlQ2hhbmdlc30gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogQGF1dGhvciBDS1xuICogQGRhdGUgMjAxOS8xLzEzXG4gKiBARGVzY3JpcHRpb246IMOowqPChcOowr3CvcOmwpXCsMOmwo3CrlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdmMi1zb3VyY2UnLFxuICB0ZW1wbGF0ZTogJydcbn0pXG5leHBvcnQgY2xhc3MgRjJTb3VyY2UgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuXG4gIC8qKlxuICAgKiDDpcKPwq/DqMKnwobDpcKMwpbDpsKVwrDDpsKNwq5cbiAgICovXG4gIEBJbnB1dCgpIGRhdGE6IGFueVtdO1xuXG4gIC8qKlxuICAgKiDDpcKPwq/DqcKAwonDr8K8wozDpcKIwpfDpcKuwprDpMK5wonDqcKFwo3Dp8K9wq7Dr8K8wojDpcKQwoTDpMK4wqrDpcKtwpfDpsKuwrXDp8KawoTDpcK6wqbDqcKHwo/DqcKFwo3Dp8K9wq7Dr8K8wolcbiAgICovXG4gIEBJbnB1dCgpIGNvbERlZnM6IG9iamVjdDtcblxuICBAT3V0cHV0KCkgZGF0YUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlcy5kYXRhKSB7XG4gICAgICB0aGlzLmRhdGFDaGFuZ2UubmV4dCh0cnVlKTtcbiAgICB9XG4gIH1cblxuICBzZXRDaGFydFNvdXJjZShjaGFydDogYW55KSB7XG4gICAgY2hhcnQuc291cmNlKHRoaXMuZGF0YSwgdGhpcy5jb2xEZWZzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtDb21wb25lbnQsIElucHV0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLyoqXG4gKiBAYXV0aG9yIENLXG4gKiBAZGF0ZSAyMDE5LzEvMTNcbiAqIEBEZXNjcmlwdGlvbjpcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZjItZ2VvbWV0cnknLFxuICB0ZW1wbGF0ZTogJydcbn0pXG5leHBvcnQgY2xhc3MgRjJHZW9tZXRyeSB7XG5cbiAgLyoqXG4gICAqIMOlwofCoMOkwr3ClcOnwrHCu8Olwp7Ci1xuICAgKlxuICAgKiAncG9pbnQnLCAncGF0aCcsICdsaW5lJywgJ2FyZWEnLCAnaW50ZXJ2YWwnLCAncG9seWdvbicsICdzY2hlbWEnLFxuICAgKi9cbiAgQElucHV0KCkgdHlwZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiB7XG4gICAqICAgZ2VuZXJhdGVQb2ludHM6IHtCb29sZWFufSxcbiAgICogICBzb3J0YWJsZToge0Jvb2xlYW59LFxuICAgKiAgIHN0YXJ0T25aZXJvOiB7Qm9vbGVhbn0sXG4gICAqICAgY29ubmVjdE51bGxzOiB7Qm9vbGVhbn1cbiAgICogIH1cbiAgICovXG4gIEBJbnB1dCgpIGNvbmZpZzogb2JqZWN0O1xuXG4gIC8qKlxuICAgKiDDpcKwwobDpsKVwrDDpsKNwq7DpcKAwrzDpsKYwqDDpcKwwoTDpcKIwrDDpcKbwr7DpcK9wqLDp8KawoTDpMK9wo3Dp8K9wq7DpMK4wopcbiAgICovXG4gIEBJbnB1dCgpIHBvc2l0aW9uOiBzdHJpbmcgfCBzdHJpbmdbXTtcblxuICAvKipcbiAgICogw6XCsMKGw6bClcKww6bCjcKuw6XCgMK8w6bCmMKgw6XCsMKEw6XCiMKww6XCm8K+w6XCvcKiw6fCmsKEw6nCosKcw6jCicKyw6TCuMKKXG4gICAqL1xuICBASW5wdXQoKSBjb2xvcjogc3RyaW5nIHwgW3N0cmluZywgc3RyaW5nIHwgYW55W10gfCBGdW5jdGlvbl07XG5cbiAgQElucHV0KCkgc2hhcGU6IGFueTtcblxuICBASW5wdXQoKSBzaXplOiBhbnk7XG5cbiAgQElucHV0KCkgYWRqdXN0OiBhbnk7XG5cbiAgQElucHV0KCkgc3R5bGU6IGFueTtcblxuICBASW5wdXQoKSBhbmltYXRlOiBhbnk7XG5cbiAgc2V0Q2hhcnRHZW9tZXRyeShjaGFydDogYW55KSB7XG4gICAgbGV0IGdlb207XG4gICAgY29uc3QgZ2VvbVR5cGUgPSB0aGlzLnR5cGU7XG4gICAgaWYgKGdlb21UeXBlID09PSAncG9pbnQnKSB7XG4gICAgICBnZW9tID0gY2hhcnQucG9pbnQoKTtcbiAgICB9IGVsc2UgaWYgKGdlb21UeXBlID09PSAncGF0aCcpIHtcbiAgICAgIGdlb20gPSBjaGFydC5wYXRoKCk7XG4gICAgfSBlbHNlIGlmIChnZW9tVHlwZSA9PT0gJ2xpbmUnKSB7XG4gICAgICBnZW9tID0gY2hhcnQubGluZSgpO1xuICAgIH0gZWxzZSBpZiAoZ2VvbVR5cGUgPT09ICdhcmVhJykge1xuICAgICAgZ2VvbSA9IGNoYXJ0LmFyZWEoKTtcbiAgICB9IGVsc2UgaWYgKGdlb21UeXBlID09PSAnaW50ZXJ2YWwnKSB7XG4gICAgICBnZW9tID0gY2hhcnQuaW50ZXJ2YWwoKTtcbiAgICB9IGVsc2UgaWYgKGdlb21UeXBlID09PSAncG9seWdvbicpIHtcbiAgICAgIGdlb20gPSBjaGFydC5wb2x5Z29uKCk7XG4gICAgfSBlbHNlIGlmIChnZW9tVHlwZSA9PT0gJ3NjaGVtYScpIHtcbiAgICAgIGdlb20gPSBjaGFydC5zY2hlbWEoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucG9zaXRpb24pIHtcbiAgICAgIGdlb20ucG9zaXRpb24odGhpcy5wb3NpdGlvbik7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbG9yKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmNvbG9yKSkge1xuICAgICAgICBnZW9tLmNvbG9yKHRoaXMuY29sb3JbMF0sIHRoaXMuY29sb3JbMV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZ2VvbS5jb2xvcih0aGlzLmNvbG9yKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRoaXMuc2hhcGUpIHtcbiAgICAgIGdlb20uc2hhcGUodGhpcy5zaGFwZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2l6ZSkge1xuICAgICAgZ2VvbS5zaXplKHRoaXMuc2l6ZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWRqdXN0KSB7XG4gICAgICBnZW9tLmFkanVzdCh0aGlzLmFkanVzdCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3R5bGUpIHtcbiAgICAgIGdlb20uc3R5bGUodGhpcy5zdHlsZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYW5pbWF0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBnZW9tLmFuaW1hdGUodGhpcy5hbmltYXRlKTtcbiAgICB9XG4gIH1cblxufVxuIiwiaW1wb3J0IHtDb21wb25lbnQsIElucHV0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBQb2xhckNvbmZpZyB7XG5cbiAgLyoqXG4gICAqIMOmwp7CgcOlwp3CkMOmwqDCh8OnwprChMOowrXCt8OlwqfCi8OowqfCksOlwrrCpsOvwrzCjMOlwrzCp8OlwrrCpsOlwojCtlxuICAgKi9cbiAgc3RhcnRBbmdsZT86IG51bWJlcjtcblxuICAvKipcbiAgICogw6bCnsKBw6XCncKQw6bCoMKHw6fCmsKEw6fCu8KTw6bCncKfw6jCp8KSw6XCusKmw6/CvMKMw6XCvMKnw6XCusKmw6XCiMK2XG4gICAqL1xuICBlbmRBbmdsZT86IG51bWJlcjtcblxuICAvKipcbiAgICogw6fCu8KYw6XCiMK2w6fCjsKvw6XCm8K+w6bCl8K2w6/CvMKMw6jCrsK+w6fCvcKuw6XChsKFw6nCg8Kow6fCqcK6w6XCv8KDw6XCjcKKw6XCvsKEw6/CvMKMw6fCm8K4w6XCr8K5w6XCgMK8w6/CvMKMMCDDqMKHwrMgMSDDqMKMwoPDpcKbwrRcbiAgICovXG4gIGlubmVyUmFkaXVzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiDDqMKuwr7Dp8K9wq7DpcKcwobDp8KawoTDpcKNworDpcK+woTDr8K8wozDp8KbwrjDpcKvwrnDpcKAwrzDr8K8wowwIMOowofCsyAxIMOowozCg8OlwpvCtFxuICAgKi9cbiAgcmFkaXVzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiDDpcKIwqTDpsKWwq3DpsKYwq/DpcKQwqbDpsKYwq/DpsKewoHDpcKdwpDDpsKgwofDr8K8wozDpsKewoHDpcKdwpDDpsKgwofDpMK4wovDpMK4wrogdHJ1ZVxuICAgKi9cbiAgaXNQb2xhcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIMOmwpjCr8OlwpDCpsOlwo/CkcOnwpTCn8Oowr3CrMOnwr3CrsOvwrzCjHRydWUgw6jCocKow6fCpMK6w6XCj8KRw6fClMKfw6TCusKGw6jCvcKsw6fCvcKuXG4gICAqL1xuICB0cmFuc3Bvc2VkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogw6bCnsKBw6XCncKQw6bCoMKHw6fCmsKEw6XCnMKGw6XCv8KDw6bCicKAw6XCnMKow6fCmsKEw6fClMK7w6XCuMKDw6XCncKQw6bCoMKHXG4gICAqL1xuICBjZW50ZXI/OiBhbnk7XG5cbiAgLyoqXG4gICAqIMOmwp7CgcOlwp3CkMOmwqDCh8OnwprChMOlwo3CisOlwr7ChMOlwoDCvFxuICAgKi9cbiAgY2lyY2xlUmFkaXVzPzogbnVtYmVyO1xuXG59XG5cbi8qKlxuICogQGF1dGhvciBDS1xuICogQGRhdGUgMjAxOS8xLzEzXG4gKiBARGVzY3JpcHRpb246IMOmwp7CgcOlwp3CkMOmwqDCh8OnwrPCu1xuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdmMi1jb29yZC1wb2xhcicsXG4gIHRlbXBsYXRlOiAnJ1xufSlcbmV4cG9ydCBjbGFzcyBGMkNvb3JkUG9sYXIge1xuXG4gIEBJbnB1dCgpIGNvbmZpZzogUG9sYXJDb25maWc7XG5cblxuICBzZXRDaGFydENvb3JkKGNoYXJ0OiBhbnkpIHtcbiAgICBpZiAodGhpcy5jb25maWcpIHtcbiAgICAgIGNoYXJ0LmNvb3JkKCdwb2xhcicsIHRoaXMuY29uZmlnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2hhcnQuY29vcmQoJ3BvbGFyJyk7XG4gICAgfVxuICB9XG5cbn1cbiIsImltcG9ydCB7Q29tcG9uZW50LCBJbnB1dH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogQGF1dGhvciBDS1xuICogQGRhdGUgMjAxOS8xLzEzXG4gKiBARGVzY3JpcHRpb246IMOpwoXCjcOnwr3CrsOlwpvCvsOkwr7Ci1xuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdmMi1sZWdlbmQnLFxuICB0ZW1wbGF0ZTogJydcbn0pXG5leHBvcnQgY2xhc3MgRjJMZWdlbmQge1xuXG4gIEBJbnB1dCgpIGNvbmZpZzogYm9vbGVhbiB8IG9iamVjdCB8IFtzdHJpbmcsIGFueV07XG5cblxuICBzZXRDaGFydExlZ2VuZChjaGFydDogYW55KSB7XG4gICAgY2hhcnQubGVnZW5kKHRoaXMuY29uZmlnKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtDb21wb25lbnQsIElucHV0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY3RDb25maWcge1xuICAvKipcbiAgICogw6XCncKQw6bCoMKHw6fCs8K7w6fCmsKEw6jCtcK3w6XCp8KLw6fCgsK5w6/CvMKMRjIgw6XCm8K+w6jCocKow6fCmsKEw6XCncKQw6bCoMKHw6fCs8K7w6XCjsKfw6fCgsK5w6TCvcKNw6TCusKOw6XCt8Kmw6TCuMKLw6jCp8KSXG4gICAqL1xuICBzdGFydD86IGFueTtcblxuICAvKipcbiAgICogw6XCncKQw6bCoMKHw6fCs8K7w6XCj8Kzw6TCuMKKw6jCp8KSw6fCmsKEw6fClMK7w6XCuMKDw6XCncKQw6bCoMKHXG4gICAqL1xuICBlbmQ/OiBhbnk7XG5cbiAgLyoqXG4gICAqIMOmwpjCr8OlwpDCpsOlwo/CkcOnwpTCn8Oowr3CrMOnwr3CrsOvwrzCjHRydWUgw6jCocKow6fCpMK6w6XCj8KRw6fClMKfw6TCusKGw6jCvcKsw6fCvcKuXG4gICAqL1xuICB0c