UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

202 lines 19.5 kB
import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, HostBinding, HostListener, Input, Output } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import * as i0 from "@angular/core"; import * as i1 from "@angular/platform-browser"; /** * Displays a CSS grid which is customizable by the customer. You can set * `c8y-dashboard-child`-components on it or position any element on it by * setting the grid CSS properties. On change (resize, or rearrange) the * component emits an change event. * * ```html * <c8y-title>Hello from outlet</c8y-title> * * <c8y-action-bar-item [placement]="'right'"> * <button class="btn btn-link" (click)="addRandom()"><i c8yIcon="plus-circle"></i> Add random</button> * </c8y-action-bar-item> * <c8y-action-bar-item [placement]="'right'"> * <button class="btn btn-link" (click)="isFrozen = !isFrozen"> * <i [c8yIcon]="isFrozen ? 'lock' : 'unlock'"></i> Toggle freeze * </button> * </c8y-action-bar-item> * * <c8y-dashboard (dashboardChange)="dashboardChange($event)"> * <c8y-dashboard-child * [isFrozen]="isFrozen" * title="dynamic" * *ngFor="let widget of widgets" * #current * > * x: {{ current.x }}<br /> * y: {{ current.y }}<br /> * width: {{ current.width }}<br /> * height: {{ current.height }}<br /> * </c8y-dashboard-child> * <c8y-dashboard-child * #cpWidget * [isFrozen]="isFrozen" * [x]="0" * [y]="1" * [width]="3" * [height]="2" * [data]="widget" * [class]="'card card-dashboard panel-title-regular panel-content-branded panel-title-overlay'" * > * <c8y-dashboard-child-title> * <span>World!</span> * </c8y-dashboard-child-title> * x: {{ cpWidget.x }}<br /> * y: {{ cpWidget.y }}<br /> * width: {{ cpWidget.width }}<br /> * height: {{ cpWidget.height }}<br /> * </c8y-dashboard-child> * <c8y-dashboard-child * #cpWidget2 * [isFrozen]="isFrozen" * [x]="8" * [y]="1" * [width]="4" * [height]="4" * [class]="'card card-dashboard panel-content-dark'" * > * <c8y-dashboard-child-title> * <span>Hello!</span> * </c8y-dashboard-child-title> * <c8y-dashboard-child-action> * <a href="" (click)="cpWidget2.isFrozen = !cpWidget2.isFrozen; (false)"> * <i [c8yIcon]="cpWidget2.isFrozen ? 'lock' : 'unlock'"></i> Toggle freeze * </a> * </c8y-dashboard-child-action> * x: {{ cpWidget2.x }}<br /> * y: {{ cpWidget2.y }}<br /> * width: {{ cpWidget2.width }}<br /> * height: {{ cpWidget2.height }}<br /> * </c8y-dashboard-child> * * <c8y-dashboard-child * #cpWidget3 * [isFrozen]="isFrozen" * [x]="0" * [y]="3" * [width]="4" * [height]="4" * [class]="'card-dashboard panel-content-transparent'" * > * <c8y-dashboard-child-title *ngIf="showTitle"> * <span>Transparent!</span> * </c8y-dashboard-child-title> * <c8y-dashboard-child-action> * <a href="" (click)="showTitle = !showTitle; (false)"> * <i [c8yIcon]="'heading'"></i> Hide/show title * </a> * </c8y-dashboard-child-action> * <c8y-dashboard-child-action> * <a href="" (click)="cpWidget3.isFrozen = !cpWidget3.isFrozen; (false)"> * <i [c8yIcon]="cpWidget3.isFrozen ? 'lock' : 'unlock'"></i> Toggle freeze * </a> * </c8y-dashboard-child-action> * x: {{ cpWidget3.x }}<br /> * y: {{ cpWidget3.y }}<br /> * width: {{ cpWidget3.width }}<br /> * height: {{ cpWidget3.height }}<br /> * </c8y-dashboard-child> * </c8y-dashboard> * ``` */ export class DashboardComponent { /** * The current column size. */ get columnSize() { return this.dashboardRect.width / this.columns; } /** * The current row size. */ get rowSize() { return this.rows === 'auto' ? this.DEFAULT_ROW_SIZE : this.calculateRowSize(); } /** * Returns all positioning styles. Nasty workaround for that issue: * https://github.com/angular/angular/issues/9343 */ get inlineStyle() { return this.sanitizer.bypassSecurityTrustStyle(` -ms-grid-columns: (1fr)[${this.columns}]; grid-template-columns: repeat(${this.columns}, 1fr); ${this.rows !== 'auto' ? `grid-template-rows: repeat(${this.rows}, 1fr);` : ''} grid-auto-rows: ${this.rowSize + this.gap}px; -ms-grid-rows: (${this.rowSize + this.gap}px)[${this.rows === 'auto' ? this.lastRow : this.rows}]; margin: -${this.gap}px -${this.gap}px 0; `); } constructor(element, sanitizer) { this.element = element; this.sanitizer = sanitizer; /** * All children in that dashboard. */ this.children = []; /** * The amount of columns on that dashboard. */ this.columns = 12; /** * The spacing between each children in pixel. */ this.gap = 12; /** * The amount of rows to dusplay. Set to auto to * auto extend the rows. */ this.rows = 'auto'; /** * An event fired if the dashboard was changed. */ this.dashboardChange = new EventEmitter(); this.lastRow = 1; this.DEFAULT_ROW_SIZE = 68; } ngAfterContentInit() { this.onResize(); } onResize() { this.updateRectSize(); } /** * Updates the current rect size of the dashboard. */ updateRectSize() { const ele = this.element.nativeElement; this.dashboardRect = ele.getBoundingClientRect(); } emitChange(widget) { this.dashboardChange.emit({ source: widget, children: this.children }); } calculateRowSize() { return this.dashboardRect.height / this.rows; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DashboardComponent, deps: [{ token: i0.ElementRef }, { token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DashboardComponent, selector: "c8y-dashboard", inputs: { columns: "columns", gap: "gap", rows: "rows" }, outputs: { dashboardChange: "dashboardChange" }, host: { listeners: { "window:resize": "onResize()" }, properties: { "attr.style": "this.inlineStyle" }, classAttribute: "c8y-grid-dashboard dashboard-grid" }, ngImport: i0, template: "<ng-content></ng-content>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DashboardComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-dashboard', host: { class: 'c8y-grid-dashboard dashboard-grid' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n" }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.DomSanitizer }], propDecorators: { columns: [{ type: Input }], gap: [{ type: Input }], rows: [{ type: Input }], dashboardChange: [{ type: Output }], inlineStyle: [{ type: HostBinding, args: ['attr.style'] }], onResize: [{ type: HostListener, args: ['window:resize'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2NvcmUvZGFzaGJvYXJkL2Rhc2hib2FyZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9jb3JlL2Rhc2hib2FyZC9kYXNoYm9hcmQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFDTCxNQUFNLEVBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDOzs7QUFJekQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvR0c7QUFTSCxNQUFNLE9BQU8sa0JBQWtCO0lBK0I3Qjs7T0FFRztJQUNILElBQUksVUFBVTtRQUNaLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUNqRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQ2hGLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUNJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsd0JBQXdCLENBQzVDO2tDQUM0QixJQUFJLENBQUMsT0FBTzt3Q0FDTixJQUFJLENBQUMsT0FBTztVQUMxQyxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsOEJBQThCLElBQUksQ0FBQyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTswQkFDNUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRzswQkFDdkIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxPQUN2QyxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQzdDO21CQUNXLElBQUksQ0FBQyxHQUFHLE9BQU8sSUFBSSxDQUFDLEdBQUc7T0FDbkMsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELFlBQ1UsT0FBbUIsRUFDbkIsU0FBdUI7UUFEdkIsWUFBTyxHQUFQLE9BQU8sQ0FBWTtRQUNuQixjQUFTLEdBQVQsU0FBUyxDQUFjO1FBbEVqQzs7V0FFRztRQUNILGFBQVEsR0FBOEIsRUFBRSxDQUFDO1FBRXpDOztXQUVHO1FBQ00sWUFBTyxHQUFHLEVBQUUsQ0FBQztRQUV0Qjs7V0FFRztRQUNNLFFBQUcsR0FBRyxFQUFFLENBQUM7UUFFbEI7OztXQUdHO1FBQ00sU0FBSSxHQUFvQixNQUFNLENBQUM7UUFFeEM7O1dBRUc7UUFDTyxvQkFBZSxHQUFHLElBQUksWUFBWSxFQUFtQixDQUFDO1FBR3hELFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDSCxxQkFBZ0IsR0FBRyxFQUFFLENBQUM7SUF1Q3BDLENBQUM7SUFFSixrQkFBa0I7UUFDaEIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFHRCxRQUFRO1FBQ04sSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7T0FFRztJQUNILGNBQWM7UUFDWixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQTRCLENBQUM7UUFDdEQsSUFBSSxDQUFDLGFBQWEsR0FBRyxHQUFHLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUNuRCxDQUFDO0lBRUQsVUFBVSxDQUFDLE1BQStCO1FBQ3hDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVPLGdCQUFnQjtRQUN0QixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFJLElBQUksQ0FBQyxJQUFlLENBQUM7SUFDM0QsQ0FBQzsrR0E3RlUsa0JBQWtCO21HQUFsQixrQkFBa0IsK1RDNUgvQiw2QkFDQTs7NEZEMkhhLGtCQUFrQjtrQkFSOUIsU0FBUzsrQkFDRSxlQUFlLFFBRW5CO3dCQUNKLEtBQUssRUFBRSxtQ0FBbUM7cUJBQzNDLG1CQUNnQix1QkFBdUIsQ0FBQyxNQUFNOzBHQVd0QyxPQUFPO3NCQUFmLEtBQUs7Z0JBS0csR0FBRztzQkFBWCxLQUFLO2dCQU1HLElBQUk7c0JBQVosS0FBSztnQkFLSSxlQUFlO3NCQUF4QixNQUFNO2dCQXlCSCxXQUFXO3NCQURkLFdBQVc7dUJBQUMsWUFBWTtnQkEwQnpCLFFBQVE7c0JBRFAsWUFBWTt1QkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0QmluZGluZyxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT3V0cHV0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBEYXNoYm9hcmRDaGlsZENvbXBvbmVudCB9IGZyb20gJy4vZGFzaGJvYXJkLWNoaWxkLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEYXNoYm9hcmRDaGFuZ2UgfSBmcm9tICcuL2Rhc2hib2FyZC5tb2RlbCc7XG5cbi8qKlxuICogRGlzcGxheXMgYSBDU1MgZ3JpZCB3aGljaCBpcyBjdXN0b21pemFibGUgYnkgdGhlIGN1c3RvbWVyLiBZb3UgY2FuIHNldFxuICogYGM4eS1kYXNoYm9hcmQtY2hpbGRgLWNvbXBvbmVudHMgb24gaXQgb3IgcG9zaXRpb24gYW55IGVsZW1lbnQgb24gaXQgYnlcbiAqIHNldHRpbmcgdGhlIGdyaWQgQ1NTIHByb3BlcnRpZXMuIE9uIGNoYW5nZSAocmVzaXplLCBvciByZWFycmFuZ2UpIHRoZVxuICogY29tcG9uZW50IGVtaXRzIGFuIGNoYW5nZSBldmVudC5cbiAqXG4gKiBgYGBodG1sXG4gKiA8Yzh5LXRpdGxlPkhlbGxvIGZyb20gb3V0bGV0PC9jOHktdGl0bGU+XG4gKlxuICogPGM4eS1hY3Rpb24tYmFyLWl0ZW0gW3BsYWNlbWVudF09XCIncmlnaHQnXCI+XG4gKiAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxpbmtcIiAoY2xpY2spPVwiYWRkUmFuZG9tKClcIj48aSBjOHlJY29uPVwicGx1cy1jaXJjbGVcIj48L2k+IEFkZCByYW5kb208L2J1dHRvbj5cbiAqIDwvYzh5LWFjdGlvbi1iYXItaXRlbT5cbiAqIDxjOHktYWN0aW9uLWJhci1pdGVtIFtwbGFjZW1lbnRdPVwiJ3JpZ2h0J1wiPlxuICogICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1saW5rXCIgKGNsaWNrKT1cImlzRnJvemVuID0gIWlzRnJvemVuXCI+XG4gKiAgICAgPGkgW2M4eUljb25dPVwiaXNGcm96ZW4gPyAnbG9jaycgOiAndW5sb2NrJ1wiPjwvaT4gVG9nZ2xlIGZyZWV6ZVxuICogICA8L2J1dHRvbj5cbiAqIDwvYzh5LWFjdGlvbi1iYXItaXRlbT5cbiAqXG4gKiA8Yzh5LWRhc2hib2FyZCAoZGFzaGJvYXJkQ2hhbmdlKT1cImRhc2hib2FyZENoYW5nZSgkZXZlbnQpXCI+XG4gKiAgIDxjOHktZGFzaGJvYXJkLWNoaWxkXG4gKiAgICAgW2lzRnJvemVuXT1cImlzRnJvemVuXCJcbiAqICAgICB0aXRsZT1cImR5bmFtaWNcIlxuICogICAgICpuZ0Zvcj1cImxldCB3aWRnZXQgb2Ygd2lkZ2V0c1wiXG4gKiAgICAgI2N1cnJlbnRcbiAqICAgPlxuICogICAgIHg6IHt7IGN1cnJlbnQueCB9fTxiciAvPlxuICogICAgIHk6IHt7IGN1cnJlbnQueSB9fTxiciAvPlxuICogICAgIHdpZHRoOiB7eyBjdXJyZW50LndpZHRoIH19PGJyIC8+XG4gKiAgICAgaGVpZ2h0OiB7eyBjdXJyZW50LmhlaWdodCB9fTxiciAvPlxuICogICA8L2M4eS1kYXNoYm9hcmQtY2hpbGQ+XG4gKiAgIDxjOHktZGFzaGJvYXJkLWNoaWxkXG4gKiAgICAgI2NwV2lkZ2V0XG4gKiAgICAgW2lzRnJvemVuXT1cImlzRnJvemVuXCJcbiAqICAgICBbeF09XCIwXCJcbiAqICAgICBbeV09XCIxXCJcbiAqICAgICBbd2lkdGhdPVwiM1wiXG4gKiAgICAgW2hlaWdodF09XCIyXCJcbiAqICAgICBbZGF0YV09XCJ3aWRnZXRcIlxuICogICAgIFtjbGFzc109XCInY2FyZCBjYXJkLWRhc2hib2FyZCBwYW5lbC10aXRsZS1yZWd1bGFyIHBhbmVsLWNvbnRlbnQtYnJhbmRlZCBwYW5lbC10aXRsZS1vdmVybGF5J1wiXG4gKiAgID5cbiAqICAgICA8Yzh5LWRhc2hib2FyZC1jaGlsZC10aXRsZT5cbiAqICAgICAgIDxzcGFuPldvcmxkITwvc3Bhbj5cbiAqICAgICA8L2M4eS1kYXNoYm9hcmQtY2hpbGQtdGl0bGU+XG4gKiAgICAgeDoge3sgY3BXaWRnZXQueCB9fTxiciAvPlxuICogICAgIHk6IHt7IGNwV2lkZ2V0LnkgfX08YnIgLz5cbiAqICAgICB3aWR0aDoge3sgY3BXaWRnZXQud2lkdGggfX08YnIgLz5cbiAqICAgICBoZWlnaHQ6IHt7IGNwV2lkZ2V0LmhlaWdodCB9fTxiciAvPlxuICogICA8L2M4eS1kYXNoYm9hcmQtY2hpbGQ+XG4gKiAgIDxjOHktZGFzaGJvYXJkLWNoaWxkXG4gKiAgICAgI2NwV2lkZ2V0MlxuICogICAgIFtpc0Zyb3plbl09XCJpc0Zyb3plblwiXG4gKiAgICAgW3hdPVwiOFwiXG4gKiAgICAgW3ldPVwiMVwiXG4gKiAgICAgW3dpZHRoXT1cIjRcIlxuICogICAgIFtoZWlnaHRdPVwiNFwiXG4gKiAgICAgW2NsYXNzXT1cIidjYXJkIGNhcmQtZGFzaGJvYXJkIHBhbmVsLWNvbnRlbnQtZGFyaydcIlxuICogICA+XG4gKiAgICAgPGM4eS1kYXNoYm9hcmQtY2hpbGQtdGl0bGU+XG4gKiAgICAgICA8c3Bhbj5IZWxsbyE8L3NwYW4+XG4gKiAgICAgPC9jOHktZGFzaGJvYXJkLWNoaWxkLXRpdGxlPlxuICogICAgIDxjOHktZGFzaGJvYXJkLWNoaWxkLWFjdGlvbj5cbiAqICAgICAgIDxhIGhyZWY9XCJcIiAoY2xpY2spPVwiY3BXaWRnZXQyLmlzRnJvemVuID0gIWNwV2lkZ2V0Mi5pc0Zyb3plbjsgKGZhbHNlKVwiPlxuICogICAgICAgICA8aSBbYzh5SWNvbl09XCJjcFdpZGdldDIuaXNGcm96ZW4gPyAnbG9jaycgOiAndW5sb2NrJ1wiPjwvaT4gVG9nZ2xlIGZyZWV6ZVxuICogICAgICAgPC9hPlxuICogICAgIDwvYzh5LWRhc2hib2FyZC1jaGlsZC1hY3Rpb24+XG4gKiAgICAgeDoge3sgY3BXaWRnZXQyLnggfX08YnIgLz5cbiAqICAgICB5OiB7eyBjcFdpZGdldDIueSB9fTxiciAvPlxuICogICAgIHdpZHRoOiB7eyBjcFdpZGdldDIud2lkdGggfX08YnIgLz5cbiAqICAgICBoZWlnaHQ6IHt7IGNwV2lkZ2V0Mi5oZWlnaHQgfX08YnIgLz5cbiAqICAgPC9jOHktZGFzaGJvYXJkLWNoaWxkPlxuICpcbiAqICAgPGM4eS1kYXNoYm9hcmQtY2hpbGRcbiAqICAgICAjY3BXaWRnZXQzXG4gKiAgICAgW2lzRnJvemVuXT1cImlzRnJvemVuXCJcbiAqICAgICBbeF09XCIwXCJcbiAqICAgICBbeV09XCIzXCJcbiAqICAgICBbd2lkdGhdPVwiNFwiXG4gKiAgICAgW2hlaWdodF09XCI0XCJcbiAqICAgICBbY2xhc3NdPVwiJ2NhcmQtZGFzaGJvYXJkIHBhbmVsLWNvbnRlbnQtdHJhbnNwYXJlbnQnXCJcbiAqICAgPlxuICogICAgIDxjOHktZGFzaGJvYXJkLWNoaWxkLXRpdGxlICpuZ0lmPVwic2hvd1RpdGxlXCI+XG4gKiAgICAgICA8c3Bhbj5UcmFuc3BhcmVudCE8L3NwYW4+XG4gKiAgICAgPC9jOHktZGFzaGJvYXJkLWNoaWxkLXRpdGxlPlxuICogICAgIDxjOHktZGFzaGJvYXJkLWNoaWxkLWFjdGlvbj5cbiAqICAgICAgIDxhIGhyZWY9XCJcIiAoY2xpY2spPVwic2hvd1RpdGxlID0gIXNob3dUaXRsZTsgKGZhbHNlKVwiPlxuICogICAgICAgICA8aSBbYzh5SWNvbl09XCInaGVhZGluZydcIj48L2k+IEhpZGUvc2hvdyB0aXRsZVxuICogICAgICAgPC9hPlxuICogICAgIDwvYzh5LWRhc2hib2FyZC1jaGlsZC1hY3Rpb24+XG4gKiAgICAgPGM4eS1kYXNoYm9hcmQtY2hpbGQtYWN0aW9uPlxuICogICAgICAgPGEgaHJlZj1cIlwiIChjbGljayk9XCJjcFdpZGdldDMuaXNGcm96ZW4gPSAhY3BXaWRnZXQzLmlzRnJvemVuOyAoZmFsc2UpXCI+XG4gKiAgICAgICAgIDxpIFtjOHlJY29uXT1cImNwV2lkZ2V0My5pc0Zyb3plbiA/ICdsb2NrJyA6ICd1bmxvY2snXCI+PC9pPiBUb2dnbGUgZnJlZXplXG4gKiAgICAgICA8L2E+XG4gKiAgICAgPC9jOHktZGFzaGJvYXJkLWNoaWxkLWFjdGlvbj5cbiAqICAgICB4OiB7eyBjcFdpZGdldDMueCB9fTxiciAvPlxuICogICAgIHk6IHt7IGNwV2lkZ2V0My55IH19PGJyIC8+XG4gKiAgICAgd2lkdGg6IHt7IGNwV2lkZ2V0My53aWR0aCB9fTxiciAvPlxuICogICAgIGhlaWdodDoge3sgY3BXaWRnZXQzLmhlaWdodCB9fTxiciAvPlxuICogICA8L2M4eS1kYXNoYm9hcmQtY2hpbGQ+XG4gKiA8L2M4eS1kYXNoYm9hcmQ+XG4gKiBgYGBcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYzh5LWRhc2hib2FyZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXNoYm9hcmQuY29tcG9uZW50Lmh0bWwnLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdjOHktZ3JpZC1kYXNoYm9hcmQgZGFzaGJvYXJkLWdyaWQnXG4gIH0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIERhc2hib2FyZENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQge1xuICAvKipcbiAgICogQWxsIGNoaWxkcmVuIGluIHRoYXQgZGFzaGJvYXJkLlxuICAgKi9cbiAgY2hpbGRyZW46IERhc2hib2FyZENoaWxkQ29tcG9uZW50W10gPSBbXTtcblxuICAvKipcbiAgICogVGhlIGFtb3VudCBvZiBjb2x1bW5zIG9uIHRoYXQgZGFzaGJvYXJkLlxuICAgKi9cbiAgQElucHV0KCkgY29sdW1ucyA9IDEyO1xuXG4gIC8qKlxuICAgKiBUaGUgc3BhY2luZyBiZXR3ZWVuIGVhY2ggY2hpbGRyZW4gaW4gcGl4ZWwuXG4gICAqL1xuICBASW5wdXQoKSBnYXAgPSAxMjtcblxuICAvKipcbiAgICogVGhlIGFtb3VudCBvZiByb3dzIHRvIGR1c3BsYXkuIFNldCB0byBhdXRvIHRvXG4gICAqIGF1dG8gZXh0ZW5kIHRoZSByb3dzLlxuICAgKi9cbiAgQElucHV0KCkgcm93czogbnVtYmVyIHwgJ2F1dG8nID0gJ2F1dG8nO1xuXG4gIC8qKlxuICAgKiBBbiBldmVudCBmaXJlZCBpZiB0aGUgZGFzaGJvYXJkIHdhcyBjaGFuZ2VkLlxuICAgKi9cbiAgQE91dHB1dCgpIGRhc2hib2FyZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8RGFzaGJvYXJkQ2hhbmdlPigpO1xuXG4gIGRhc2hib2FyZFJlY3Q7XG4gIHByaXZhdGUgbGFzdFJvdyA9IDE7XG4gIHByaXZhdGUgcmVhZG9ubHkgREVGQVVMVF9ST1dfU0laRSA9IDY4O1xuXG4gIC8qKlxuICAgKiBUaGUgY3VycmVudCBjb2x1bW4gc2l6ZS5cbiAgICovXG4gIGdldCBjb2x1bW5TaXplKCkge1xuICAgIHJldHVybiB0aGlzLmRhc2hib2FyZFJlY3Qud2lkdGggLyB0aGlzLmNvbHVtbnM7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgcm93IHNpemUuXG4gICAqL1xuICBnZXQgcm93U2l6ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5yb3dzID09PSAnYXV0bycgPyB0aGlzLkRFRkFVTFRfUk9XX1NJWkUgOiB0aGlzLmNhbGN1bGF0ZVJvd1NpemUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCBwb3NpdGlvbmluZyBzdHlsZXMuIE5hc3R5IHdvcmthcm91bmQgZm9yIHRoYXQgaXNzdWU6XG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzkzNDNcbiAgICovXG4gIEBIb3N0QmluZGluZygnYXR0ci5zdHlsZScpXG4gIGdldCBpbmxpbmVTdHlsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFN0eWxlKFxuICAgICAgYFxuICAgICAgICAtbXMtZ3JpZC1jb2x1bW5zOiAoMWZyKVske3RoaXMuY29sdW1uc31dO1xuICAgICAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IHJlcGVhdCgke3RoaXMuY29sdW1uc30sIDFmcik7XG4gICAgICAgICR7dGhpcy5yb3dzICE9PSAnYXV0bycgPyBgZ3JpZC10ZW1wbGF0ZS1yb3dzOiByZXBlYXQoJHt0aGlzLnJvd3N9LCAxZnIpO2AgOiAnJ31cbiAgICAgICAgZ3JpZC1hdXRvLXJvd3M6ICR7dGhpcy5yb3dTaXplICsgdGhpcy5nYXB9cHg7XG4gICAgICAgIC1tcy1ncmlkLXJvd3M6ICgke3RoaXMucm93U2l6ZSArIHRoaXMuZ2FwfXB4KVske1xuICAgICAgICAgIHRoaXMucm93cyA9PT0gJ2F1dG8nID8gdGhpcy5sYXN0Um93IDogdGhpcy5yb3dzXG4gICAgICAgIH1dO1xuICAgICAgICBtYXJnaW46IC0ke3RoaXMuZ2FwfXB4IC0ke3RoaXMuZ2FwfXB4IDA7XG4gICAgICBgXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZWxlbWVudDogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIHNhbml0aXplcjogRG9tU2FuaXRpemVyXG4gICkge31cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5vblJlc2l6ZSgpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScpXG4gIG9uUmVzaXplKCkge1xuICAgIHRoaXMudXBkYXRlUmVjdFNpemUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBjdXJyZW50IHJlY3Qgc2l6ZSBvZiB0aGUgZGFzaGJvYXJkLlxuICAgKi9cbiAgdXBkYXRlUmVjdFNpemUoKSB7XG4gICAgY29uc3QgZWxlID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgdGhpcy5kYXNoYm9hcmRSZWN0ID0gZWxlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB9XG5cbiAgZW1pdENoYW5nZSh3aWRnZXQ6IERhc2hib2FyZENoaWxkQ29tcG9uZW50KSB7XG4gICAgdGhpcy5kYXNoYm9hcmRDaGFuZ2UuZW1pdCh7IHNvdXJjZTogd2lkZ2V0LCBjaGlsZHJlbjogdGhpcy5jaGlsZHJlbiB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY2FsY3VsYXRlUm93U2l6ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5kYXNoYm9hcmRSZWN0LmhlaWdodCAvICh0aGlzLnJvd3MgYXMgbnVtYmVyKTtcbiAgfVxufVxuIiwiPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuIl19