@worktile/gantt 15.0.0 → 15.1.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/class/event.d.ts +13 -0
- package/class/item.d.ts +7 -1
- package/components/bar/bar-drag.d.ts +10 -0
- package/components/bar/bar.component.d.ts +2 -1
- package/components/bar/bar.component.scss +22 -0
- package/components/calendar/calendar.scss +91 -0
- package/components/calendar/grid/calendar-grid.component.d.ts +24 -0
- package/components/calendar/header/calendar-header.component.d.ts +21 -0
- package/components/icon/icons.d.ts +1 -0
- package/components/links/links.component.d.ts +5 -5
- package/components/loader/loader.component.d.ts +5 -0
- package/components/loader/loader.component.scss +90 -0
- package/components/main/gantt-main.component.d.ts +3 -3
- package/components/table/body/gantt-table-body.component.d.ts +58 -0
- package/components/table/gantt-table.component.scss +169 -85
- package/components/table/gantt-table.scss +271 -0
- package/components/table/header/gantt-table-header.component.d.ts +31 -0
- package/esm2020/class/event.mjs +5 -1
- package/esm2020/class/item.mjs +9 -4
- package/esm2020/components/bar/bar-drag.mjs +106 -42
- package/esm2020/components/bar/bar.component.mjs +8 -2
- package/esm2020/components/calendar/grid/calendar-grid.component.mjs +71 -0
- package/esm2020/components/calendar/header/calendar-header.component.mjs +67 -0
- package/esm2020/components/icon/icons.mjs +4 -2
- package/esm2020/components/links/links.component.mjs +72 -54
- package/esm2020/components/loader/loader.component.mjs +29 -0
- package/esm2020/components/main/gantt-main.component.mjs +5 -5
- package/esm2020/components/table/body/gantt-table-body.component.mjs +298 -0
- package/esm2020/components/table/header/gantt-table-header.component.mjs +140 -0
- package/esm2020/gantt-dom.service.mjs +8 -12
- package/esm2020/gantt-item-upper.mjs +15 -6
- package/esm2020/gantt-print.service.mjs +2 -2
- package/esm2020/gantt-upper.mjs +18 -15
- package/esm2020/gantt.component.mjs +143 -25
- package/esm2020/gantt.module.mjs +28 -10
- package/esm2020/public-api.mjs +2 -1
- package/esm2020/root.component.mjs +10 -8
- package/esm2020/table/gantt-table.component.mjs +12 -4
- package/esm2020/utils/helpers.mjs +11 -1
- package/fesm2015/worktile-gantt.mjs +969 -378
- package/fesm2015/worktile-gantt.mjs.map +1 -1
- package/fesm2020/worktile-gantt.mjs +959 -380
- package/fesm2020/worktile-gantt.mjs.map +1 -1
- package/gantt-dom.service.d.ts +1 -0
- package/gantt-item-upper.d.ts +3 -2
- package/gantt-upper.d.ts +4 -1
- package/gantt.component.d.ts +26 -8
- package/gantt.component.scss +39 -0
- package/gantt.module.d.ts +19 -15
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/root.component.d.ts +1 -1
- package/styles/index.scss +5 -2
- package/styles/variables.scss +12 -7
- package/table/gantt-table.component.d.ts +5 -2
- package/components/calendar/calendar.component.d.ts +0 -26
- package/components/table/gantt-table.component.d.ts +0 -42
- package/esm2020/components/calendar/calendar.component.mjs +0 -88
- package/esm2020/components/table/gantt-table.component.mjs +0 -166
|
@@ -20,16 +20,16 @@ export class GanttMainComponent {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
GanttMainComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttMainComponent, deps: [{ token: GANTT_UPPER_TOKEN }], target: i0.ɵɵFactoryTarget.Component });
|
|
23
|
-
GanttMainComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttMainComponent, selector: "gantt-main", inputs: {
|
|
23
|
+
GanttMainComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttMainComponent, selector: "gantt-main", inputs: { renderData: "renderData", flatData: "flatData", groupHeaderTemplate: "groupHeaderTemplate", itemTemplate: "itemTemplate", barTemplate: "barTemplate", rangeTemplate: "rangeTemplate" }, outputs: { barClick: "barClick", lineClick: "lineClick" }, host: { properties: { "class.gantt-main-container": "this.ganttMainClass" } }, ngImport: i0, template: "<!-- <gantt-links-overlay [groups]=\"groups\" [items]=\"items\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay> -->\n<!-- groups -->\n<!-- <div class=\"gantt-main-groups\" *ngIf=\"groups && groups.length > 0; else itemsTemplate\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"group.class\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: group }\"></ng-template>\n </div>\n <div *ngIf=\"group.expanded\" class=\"gantt-items\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: group.items }\"></ng-template>\n </div>\n </ng-container>\n</div> -->\n\n<!-- items -->\n<!-- <ng-template #itemsTemplate>\n <div class=\"gantt-main-items\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items }\"></ng-template>\n </div>\n</ng-template>\n\n<ng-template #ganttItems let-items=\"items\">\n <ng-container *ngFor=\"let item of items\">\n <div\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-container *ngIf=\"item.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: item.origin,\n refs: item.refs,\n baseline: ganttUpper.baselineItemsMap[item.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[item.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(item.type | isGanttRangeItem) || (item.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"item.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"item\"></gantt-range>\n <gantt-bar *ngIf=\"item.type | isGanttBarItem\" [item]=\"item\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[item.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[item.id]\"></gantt-baseline>\n </ng-container>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children }\"\n ></ng-template>\n </ng-container>\n</ng-template> -->\n\n<gantt-links-overlay [flatData]=\"flatData\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay>\n<div class=\"gantt-main-groups\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let data of renderData; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"data.class\" *ngIf=\"data.items\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: data }\"></ng-template>\n </div>\n <div\n *ngIf=\"!data.items\"\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(data.id)\"\n >\n <ng-container *ngIf=\"data.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: data.origin,\n refs: data.refs,\n baseline: ganttUpper.baselineItemsMap[data.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[data.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(data.type | isGanttRangeItem) || (data.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"data.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"data\"></gantt-range>\n <gantt-bar *ngIf=\"data.type | isGanttBarItem\" [item]=\"data\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[data.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[data.id]\"></gantt-baseline>\n </ng-container>\n </div>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.GanttLinksComponent, selector: "gantt-links-overlay", inputs: ["flatData"], outputs: ["lineClick"] }, { kind: "component", type: i3.NgxGanttBarComponent, selector: "ngx-gantt-bar,gantt-bar", outputs: ["barClick"] }, { kind: "component", type: i4.NgxGanttRangeComponent, selector: "ngx-gantt-range,gantt-range" }, { kind: "component", type: i5.NgxGanttBaselineComponent, selector: "ngx-gantt-baseline,gantt-baseline", inputs: ["baselineItem"] }, { kind: "pipe", type: i6.IsGanttRangeItemPipe, name: "isGanttRangeItem" }, { kind: "pipe", type: i6.IsGanttBarItemPipe, name: "isGanttBarItem" }, { kind: "pipe", type: i6.IsGanttCustomItemPipe, name: "isGanttCustomItem" }] });
|
|
24
24
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttMainComponent, decorators: [{
|
|
25
25
|
type: Component,
|
|
26
|
-
args: [{ selector: 'gantt-main', template: "<gantt-links-overlay [groups]=\"groups\" [items]=\"items\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay
|
|
26
|
+
args: [{ selector: 'gantt-main', template: "<!-- <gantt-links-overlay [groups]=\"groups\" [items]=\"items\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay> -->\n<!-- groups -->\n<!-- <div class=\"gantt-main-groups\" *ngIf=\"groups && groups.length > 0; else itemsTemplate\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"group.class\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: group }\"></ng-template>\n </div>\n <div *ngIf=\"group.expanded\" class=\"gantt-items\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: group.items }\"></ng-template>\n </div>\n </ng-container>\n</div> -->\n\n<!-- items -->\n<!-- <ng-template #itemsTemplate>\n <div class=\"gantt-main-items\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items }\"></ng-template>\n </div>\n</ng-template>\n\n<ng-template #ganttItems let-items=\"items\">\n <ng-container *ngFor=\"let item of items\">\n <div\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-container *ngIf=\"item.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: item.origin,\n refs: item.refs,\n baseline: ganttUpper.baselineItemsMap[item.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[item.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(item.type | isGanttRangeItem) || (item.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"item.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"item\"></gantt-range>\n <gantt-bar *ngIf=\"item.type | isGanttBarItem\" [item]=\"item\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[item.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[item.id]\"></gantt-baseline>\n </ng-container>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children }\"\n ></ng-template>\n </ng-container>\n</ng-template> -->\n\n<gantt-links-overlay [flatData]=\"flatData\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay>\n<div class=\"gantt-main-groups\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let data of renderData; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"data.class\" *ngIf=\"data.items\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: data }\"></ng-template>\n </div>\n <div\n *ngIf=\"!data.items\"\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(data.id)\"\n >\n <ng-container *ngIf=\"data.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: data.origin,\n refs: data.refs,\n baseline: ganttUpper.baselineItemsMap[data.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[data.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(data.type | isGanttRangeItem) || (data.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"data.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"data\"></gantt-range>\n <gantt-bar *ngIf=\"data.type | isGanttBarItem\" [item]=\"data\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[data.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[data.id]\"></gantt-baseline>\n </ng-container>\n </div>\n </ng-container>\n</div>\n" }]
|
|
27
27
|
}], ctorParameters: function () { return [{ type: i7.GanttUpper, decorators: [{
|
|
28
28
|
type: Inject,
|
|
29
29
|
args: [GANTT_UPPER_TOKEN]
|
|
30
|
-
}] }]; }, propDecorators: {
|
|
30
|
+
}] }]; }, propDecorators: { renderData: [{
|
|
31
31
|
type: Input
|
|
32
|
-
}],
|
|
32
|
+
}], flatData: [{
|
|
33
33
|
type: Input
|
|
34
34
|
}], groupHeaderTemplate: [{
|
|
35
35
|
type: Input
|
|
@@ -47,4 +47,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
|
|
|
47
47
|
type: HostBinding,
|
|
48
48
|
args: ['class.gantt-main-container']
|
|
49
49
|
}] } });
|
|
50
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FudHQtbWFpbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9nYW50dC9zcmMvY29tcG9uZW50cy9tYWluL2dhbnR0LW1haW4uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvZ2FudHQvc3JjL2NvbXBvbmVudHMvbWFpbi9nYW50dC1tYWluLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQWUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV6RyxPQUFPLEVBQUUsaUJBQWlCLEVBQWMsTUFBTSxtQkFBbUIsQ0FBQzs7Ozs7Ozs7O0FBTWxFLE1BQU0sT0FBTyxrQkFBa0I7SUFzQjNCLFlBQThDLFVBQXNCO1FBQXRCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFOMUQsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFzQixDQUFDO1FBRWxELGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBdUIsQ0FBQztRQUVuQixtQkFBYyxHQUFHLElBQUksQ0FBQztJQUVNLENBQUM7SUFFeEUsT0FBTyxDQUFDLEtBQWEsRUFBRSxJQUE0QztRQUMvRCxPQUFPLElBQUksQ0FBQyxFQUFFLElBQUksS0FBSyxDQUFDO0lBQzVCLENBQUM7OytHQTFCUSxrQkFBa0Isa0JBc0JQLGlCQUFpQjttR0F0QjVCLGtCQUFrQiw4WENSL0IscXBJQXVGQTsyRkQvRWEsa0JBQWtCO2tCQUo5QixTQUFTOytCQUNJLFlBQVk7OzBCQXlCVCxNQUFNOzJCQUFDLGlCQUFpQjs0Q0FsQjVCLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBRUcsWUFBWTtzQkFBcEIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBRUksUUFBUTtzQkFBakIsTUFBTTtnQkFFRyxTQUFTO3NCQUFsQixNQUFNO2dCQUVvQyxjQUFjO3NCQUF4RCxXQUFXO3VCQUFDLDRCQUE0QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSG9zdEJpbmRpbmcsIEluamVjdCwgSW5wdXQsIFRlbXBsYXRlUmVmLCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR2FudHRHcm91cEludGVybmFsLCBHYW50dEl0ZW1JbnRlcm5hbCwgR2FudHRCYXJDbGlja0V2ZW50LCBHYW50dExpbmVDbGlja0V2ZW50IH0gZnJvbSAnLi4vLi4vY2xhc3MnO1xuaW1wb3J0IHsgR0FOVFRfVVBQRVJfVE9LRU4sIEdhbnR0VXBwZXIgfSBmcm9tICcuLi8uLi9nYW50dC11cHBlcic7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnZ2FudHQtbWFpbicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2dhbnR0LW1haW4uY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIEdhbnR0TWFpbkNvbXBvbmVudCB7XG4gICAgLy8gQElucHV0KCkgZ3JvdXBzOiBHYW50dEdyb3VwSW50ZXJuYWxbXTtcblxuICAgIC8vIEBJbnB1dCgpIGl0ZW1zOiBHYW50dEl0ZW1JbnRlcm5hbFtdO1xuICAgIEBJbnB1dCgpIHJlbmRlckRhdGE6IChHYW50dEdyb3VwSW50ZXJuYWwgfCBHYW50dEl0ZW1JbnRlcm5hbClbXTtcblxuICAgIEBJbnB1dCgpIGZsYXREYXRhOiAoR2FudHRHcm91cEludGVybmFsIHwgR2FudHRJdGVtSW50ZXJuYWwpW107XG5cbiAgICBASW5wdXQoKSBncm91cEhlYWRlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgQElucHV0KCkgaXRlbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgQElucHV0KCkgYmFyVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICBASW5wdXQoKSByYW5nZVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgQE91dHB1dCgpIGJhckNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxHYW50dEJhckNsaWNrRXZlbnQ+KCk7XG5cbiAgICBAT3V0cHV0KCkgbGluZUNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxHYW50dExpbmVDbGlja0V2ZW50PigpO1xuXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5nYW50dC1tYWluLWNvbnRhaW5lcicpIGdhbnR0TWFpbkNsYXNzID0gdHJ1ZTtcblxuICAgIGNvbnN0cnVjdG9yKEBJbmplY3QoR0FOVFRfVVBQRVJfVE9LRU4pIHB1YmxpYyBnYW50dFVwcGVyOiBHYW50dFVwcGVyKSB7fVxuXG4gICAgdHJhY2tCeShpbmRleDogbnVtYmVyLCBpdGVtOiBHYW50dEdyb3VwSW50ZXJuYWwgfCBHYW50dEl0ZW1JbnRlcm5hbCkge1xuICAgICAgICByZXR1cm4gaXRlbS5pZCB8fCBpbmRleDtcbiAgICB9XG59XG4iLCI8IS0tIDxnYW50dC1saW5rcy1vdmVybGF5IFtncm91cHNdPVwiZ3JvdXBzXCIgW2l0ZW1zXT1cIml0ZW1zXCIgKGxpbmVDbGljayk9XCJsaW5lQ2xpY2suZW1pdCgkZXZlbnQpXCI+PC9nYW50dC1saW5rcy1vdmVybGF5PiAtLT5cbjwhLS0gZ3JvdXBzIC0tPlxuPCEtLSA8ZGl2IGNsYXNzPVwiZ2FudHQtbWFpbi1ncm91cHNcIiAqbmdJZj1cImdyb3VwcyAmJiBncm91cHMubGVuZ3RoID4gMDsgZWxzZSBpdGVtc1RlbXBsYXRlXCIgW3N0eWxlLndpZHRoLnB4XT1cImdhbnR0VXBwZXIudmlldy53aWR0aFwiPlxuICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBncm91cCBvZiBncm91cHM7IHRyYWNrQnk6IHRyYWNrQnlcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZ2FudHQtZ3JvdXBcIiBbbmdDbGFzc109XCJncm91cC5jbGFzc1wiPlxuICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImdyb3VwSGVhZGVyVGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBncm91cDogZ3JvdXAgfVwiPjwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdJZj1cImdyb3VwLmV4cGFuZGVkXCIgY2xhc3M9XCJnYW50dC1pdGVtc1wiPlxuICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImdhbnR0SXRlbXNcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBpdGVtczogZ3JvdXAuaXRlbXMgfVwiPjwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuPC9kaXY+IC0tPlxuXG48IS0tIGl0ZW1zIC0tPlxuPCEtLSA8bmctdGVtcGxhdGUgI2l0ZW1zVGVtcGxhdGU+XG4gIDxkaXYgY2xhc3M9XCJnYW50dC1tYWluLWl0ZW1zXCIgW3N0eWxlLndpZHRoLnB4XT1cImdhbnR0VXBwZXIudmlldy53aWR0aFwiPlxuICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJnYW50dEl0ZW1zXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgaXRlbXM6IGl0ZW1zIH1cIj48L25nLXRlbXBsYXRlPlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjZ2FudHRJdGVtcyBsZXQtaXRlbXM9XCJpdGVtc1wiPlxuICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zXCI+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJnYW50dC1pdGVtXCJcbiAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwiZ2FudHRVcHBlci5zdHlsZXMubGluZUhlaWdodFwiXG4gICAgICBbY2xhc3MuZ2FudHQtbWFpbi1pdGVtLWFjdGl2ZV09XCJnYW50dFVwcGVyLmlzU2VsZWN0ZWQoaXRlbS5pZClcIlxuICAgID5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnR5cGUgfCBpc0dhbnR0Q3VzdG9tSXRlbVwiPlxuICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJpdGVtVGVtcGxhdGVcIlxuICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7XG4gICAgICAgICAgICBpdGVtOiBpdGVtLm9yaWdpbixcbiAgICAgICAgICAgIHJlZnM6IGl0ZW0ucmVmcyxcbiAgICAgICAgICAgIGJhc2VsaW5lOiBnYW50dFVwcGVyLmJhc2VsaW5lSXRlbXNNYXBbaXRlbS5pZF0/Lm9yaWdpbixcbiAgICAgICAgICAgIGJhc2VsaW5lUmVmczogZ2FudHRVcHBlci5iYXNlbGluZUl0ZW1zTWFwW2l0ZW0uaWRdPy5yZWZzXG4gICAgICAgICAgfVwiXG4gICAgICAgID5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiKGl0ZW0udHlwZSB8IGlzR2FudHRSYW5nZUl0ZW0pIHx8IChpdGVtLnR5cGUgfCBpc0dhbnR0QmFySXRlbSlcIj5cbiAgICAgICAgPGdhbnR0LXJhbmdlICpuZ0lmPVwiaXRlbS50eXBlIHwgaXNHYW50dFJhbmdlSXRlbVwiIFt0ZW1wbGF0ZV09XCJyYW5nZVRlbXBsYXRlXCIgW2l0ZW1dPVwiaXRlbVwiPjwvZ2FudHQtcmFuZ2U+XG4gICAgICAgIDxnYW50dC1iYXIgKm5nSWY9XCJpdGVtLnR5cGUgfCBpc0dhbnR0QmFySXRlbVwiIFtpdGVtXT1cIml0ZW1cIiBbdGVtcGxhdGVdPVwiYmFyVGVtcGxhdGVcIiAoYmFyQ2xpY2spPVwiYmFyQ2xpY2suZW1pdCgkZXZlbnQpXCI+PC9nYW50dC1iYXI+XG4gICAgICAgIDxnYW50dC1iYXNlbGluZSAqbmdJZj1cImdhbnR0VXBwZXIuYmFzZWxpbmVJdGVtc01hcFtpdGVtLmlkXVwiIFtiYXNlbGluZUl0ZW1dPVwiZ2FudHRVcHBlci5iYXNlbGluZUl0ZW1zTWFwW2l0ZW0uaWRdXCI+PC9nYW50dC1iYXNlbGluZT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgKm5nSWY9XCJpdGVtLmNoaWxkcmVuICYmIGl0ZW0uZXhwYW5kZWRcIlxuICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiZ2FudHRJdGVtc1wiXG4gICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBpdGVtczogaXRlbS5jaGlsZHJlbiB9XCJcbiAgICA+PC9uZy10ZW1wbGF0ZT5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPiAtLT5cblxuPGdhbnR0LWxpbmtzLW92ZXJsYXkgW2ZsYXREYXRhXT1cImZsYXREYXRhXCIgKGxpbmVDbGljayk9XCJsaW5lQ2xpY2suZW1pdCgkZXZlbnQpXCI+PC9nYW50dC1saW5rcy1vdmVybGF5PlxuPGRpdiBjbGFzcz1cImdhbnR0LW1haW4tZ3JvdXBzXCIgW3N0eWxlLndpZHRoLnB4XT1cImdhbnR0VXBwZXIudmlldy53aWR0aFwiPlxuICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBkYXRhIG9mIHJlbmRlckRhdGE7IHRyYWNrQnk6IHRyYWNrQnlcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZ2FudHQtZ3JvdXBcIiBbbmdDbGFzc109XCJkYXRhLmNsYXNzXCIgKm5nSWY9XCJkYXRhLml0ZW1zXCI+XG4gICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiZ3JvdXBIZWFkZXJUZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IGdyb3VwOiBkYXRhIH1cIj48L25nLXRlbXBsYXRlPlxuICAgIDwvZGl2PlxuICAgIDxkaXZcbiAgICAgICpuZ0lmPVwiIWRhdGEuaXRlbXNcIlxuICAgICAgY2xhc3M9XCJnYW50dC1pdGVtXCJcbiAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwiZ2FudHRVcHBlci5zdHlsZXMubGluZUhlaWdodFwiXG4gICAgICBbY2xhc3MuZ2FudHQtbWFpbi1pdGVtLWFjdGl2ZV09XCJnYW50dFVwcGVyLmlzU2VsZWN0ZWQoZGF0YS5pZClcIlxuICAgID5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJkYXRhLnR5cGUgfCBpc0dhbnR0Q3VzdG9tSXRlbVwiPlxuICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJpdGVtVGVtcGxhdGVcIlxuICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7XG4gICAgICAgICAgICBpdGVtOiBkYXRhLm9yaWdpbixcbiAgICAgICAgICAgIHJlZnM6IGRhdGEucmVmcyxcbiAgICAgICAgICAgIGJhc2VsaW5lOiBnYW50dFVwcGVyLmJhc2VsaW5lSXRlbXNNYXBbZGF0YS5pZF0/Lm9yaWdpbixcbiAgICAgICAgICAgIGJhc2VsaW5lUmVmczogZ2FudHRVcHBlci5iYXNlbGluZUl0ZW1zTWFwW2RhdGEuaWRdPy5yZWZzXG4gICAgICAgICAgfVwiXG4gICAgICAgID5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiKGRhdGEudHlwZSB8IGlzR2FudHRSYW5nZUl0ZW0pIHx8IChkYXRhLnR5cGUgfCBpc0dhbnR0QmFySXRlbSlcIj5cbiAgICAgICAgPGdhbnR0LXJhbmdlICpuZ0lmPVwiZGF0YS50eXBlIHwgaXNHYW50dFJhbmdlSXRlbVwiIFt0ZW1wbGF0ZV09XCJyYW5nZVRlbXBsYXRlXCIgW2l0ZW1dPVwiZGF0YVwiPjwvZ2FudHQtcmFuZ2U+XG4gICAgICAgIDxnYW50dC1iYXIgKm5nSWY9XCJkYXRhLnR5cGUgfCBpc0dhbnR0QmFySXRlbVwiIFtpdGVtXT1cImRhdGFcIiBbdGVtcGxhdGVdPVwiYmFyVGVtcGxhdGVcIiAoYmFyQ2xpY2spPVwiYmFyQ2xpY2suZW1pdCgkZXZlbnQpXCI+PC9nYW50dC1iYXI+XG4gICAgICAgIDxnYW50dC1iYXNlbGluZSAqbmdJZj1cImdhbnR0VXBwZXIuYmFzZWxpbmVJdGVtc01hcFtkYXRhLmlkXVwiIFtiYXNlbGluZUl0ZW1dPVwiZ2FudHRVcHBlci5iYXNlbGluZUl0ZW1zTWFwW2RhdGEuaWRdXCI+PC9nYW50dC1iYXNlbGluZT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuIl19
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { debounceTime, filter, startWith, Subject, takeUntil } from 'rxjs';
|
|
2
|
+
import { Component, HostBinding, Input, Inject, Output, EventEmitter, ViewChildren } from '@angular/core';
|
|
3
|
+
import { coerceCssPixelValue } from '@angular/cdk/coercion';
|
|
4
|
+
import { GANTT_ABSTRACT_TOKEN } from '../../../gantt-abstract';
|
|
5
|
+
import { defaultColumnWidth } from '../header/gantt-table-header.component';
|
|
6
|
+
import { GANTT_UPPER_TOKEN } from '../../../gantt-upper';
|
|
7
|
+
import { CdkDrag } from '@angular/cdk/drag-drop';
|
|
8
|
+
import { DOCUMENT } from '@angular/common';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
import * as i1 from "@angular/common";
|
|
11
|
+
import * as i2 from "@angular/cdk/drag-drop";
|
|
12
|
+
import * as i3 from "../../icon/icon.component";
|
|
13
|
+
import * as i4 from "../../../gantt.pipe";
|
|
14
|
+
import * as i5 from "../../../gantt-upper";
|
|
15
|
+
export class GanttTableBodyComponent {
|
|
16
|
+
set renderData(data) {
|
|
17
|
+
const firstData = data[0];
|
|
18
|
+
if (firstData && firstData.hasOwnProperty('items')) {
|
|
19
|
+
this.hasGroup = true;
|
|
20
|
+
}
|
|
21
|
+
this.ganttTableEmptyClass = data?.length ? false : true;
|
|
22
|
+
this._renderData = data;
|
|
23
|
+
}
|
|
24
|
+
get renderData() {
|
|
25
|
+
return this._renderData;
|
|
26
|
+
}
|
|
27
|
+
constructor(gantt, ganttUpper, cdr, document) {
|
|
28
|
+
this.gantt = gantt;
|
|
29
|
+
this.ganttUpper = ganttUpper;
|
|
30
|
+
this.cdr = cdr;
|
|
31
|
+
this.document = document;
|
|
32
|
+
this.draggable = false;
|
|
33
|
+
this.dragDropped = new EventEmitter();
|
|
34
|
+
this.itemClick = new EventEmitter();
|
|
35
|
+
this.ganttTableClass = true;
|
|
36
|
+
this.ganttTableEmptyClass = false;
|
|
37
|
+
this.ganttTableDragging = false;
|
|
38
|
+
this.hasExpandIcon = false;
|
|
39
|
+
// 缓存 Element 和 DragRef 的关系,方便在 Item 拖动时查找
|
|
40
|
+
this.itemDragRefMap = new Map();
|
|
41
|
+
this.itemDragMoved = new Subject();
|
|
42
|
+
this.destroy$ = new Subject();
|
|
43
|
+
}
|
|
44
|
+
ngOnInit() {
|
|
45
|
+
this.columns.changes.pipe(startWith(this.columns), takeUntil(this.destroy$)).subscribe(() => {
|
|
46
|
+
this.hasExpandIcon = false;
|
|
47
|
+
this.columns.forEach((column) => {
|
|
48
|
+
if (!column.columnWidth) {
|
|
49
|
+
column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
|
|
50
|
+
}
|
|
51
|
+
if (column.showExpandIcon) {
|
|
52
|
+
this.hasExpandIcon = true;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
this.cdr.detectChanges();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
ngAfterViewInit() {
|
|
59
|
+
this.cdkDrags.changes
|
|
60
|
+
.pipe(startWith(this.cdkDrags), takeUntil(this.destroy$))
|
|
61
|
+
.subscribe((drags) => {
|
|
62
|
+
this.itemDragRefMap.clear();
|
|
63
|
+
drags.forEach((drag) => {
|
|
64
|
+
if (drag.data) {
|
|
65
|
+
// cdkDrag 变化时,缓存 Element 与 DragRef 的关系,方便 Drag Move 时查找
|
|
66
|
+
this.itemDragRefMap.set(drag.element.nativeElement, drag);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
this.itemDragMoved
|
|
71
|
+
.pipe(debounceTime(30),
|
|
72
|
+
// debounce 可能会导致拖动结束后仍然执行 moved ,所以通过判断 dragging 状态来过滤无效 moved
|
|
73
|
+
filter((event) => event.source._dragRef.isDragging()), takeUntil(this.destroy$))
|
|
74
|
+
.subscribe((event) => {
|
|
75
|
+
this.onItemDragMoved(event);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
expandGroup(group) {
|
|
79
|
+
this.gantt.expandGroup(group);
|
|
80
|
+
}
|
|
81
|
+
expandChildren(event, item) {
|
|
82
|
+
event.stopPropagation();
|
|
83
|
+
this.gantt.expandChildren(item);
|
|
84
|
+
}
|
|
85
|
+
onItemDragStarted(event) {
|
|
86
|
+
this.ganttTableDragging = true;
|
|
87
|
+
// 拖动开始时隐藏所有的子项
|
|
88
|
+
const children = this.getChildrenElementsByElement(event.source.getPlaceholderElement());
|
|
89
|
+
children.forEach((element) => {
|
|
90
|
+
element.classList.add('drag-item-hide');
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
emitItemDragMoved(event) {
|
|
94
|
+
this.itemDragMoved.next(event);
|
|
95
|
+
}
|
|
96
|
+
onItemDragMoved(event) {
|
|
97
|
+
// 通过鼠标位置查找对应的目标 Item 元素
|
|
98
|
+
let currentPointElement = this.document.elementFromPoint(event.pointerPosition.x, event.pointerPosition.y);
|
|
99
|
+
if (!currentPointElement) {
|
|
100
|
+
this.cleanupDragArtifacts();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
let targetElement = currentPointElement.classList.contains('gantt-table-item')
|
|
104
|
+
? currentPointElement
|
|
105
|
+
: currentPointElement.closest('.gantt-table-item');
|
|
106
|
+
if (!targetElement) {
|
|
107
|
+
this.cleanupDragArtifacts();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// 缓存放置目标Id 并计算鼠标相对应的位置
|
|
111
|
+
this.itemDropTarget = {
|
|
112
|
+
id: this.itemDragRefMap.get(targetElement)?.data.id,
|
|
113
|
+
position: this.getTargetPosition(targetElement, event)
|
|
114
|
+
};
|
|
115
|
+
// 执行外部传入的 dropEnterPredicate 判断是否允许拖入目标项
|
|
116
|
+
if (this.dropEnterPredicate) {
|
|
117
|
+
const targetDragRef = this.itemDragRefMap.get(targetElement);
|
|
118
|
+
if (this.dropEnterPredicate({
|
|
119
|
+
source: event.source.data.origin,
|
|
120
|
+
target: targetDragRef.data.origin,
|
|
121
|
+
dropPosition: this.itemDropTarget.position
|
|
122
|
+
})) {
|
|
123
|
+
this.showDropPositionPlaceholder(targetElement);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.itemDropTarget = null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.showDropPositionPlaceholder(targetElement);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
onItemDragEnded(event) {
|
|
134
|
+
this.ganttTableDragging = false;
|
|
135
|
+
}
|
|
136
|
+
onListDropped(event) {
|
|
137
|
+
if (!this.itemDropTarget) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const targetDragRef = this.cdkDrags.find((item) => item.data?.id === this.itemDropTarget.id);
|
|
141
|
+
const sourceItem = event.item.data;
|
|
142
|
+
const targetItem = targetDragRef?.data;
|
|
143
|
+
this.removeItem(sourceItem);
|
|
144
|
+
switch (this.itemDropTarget.position) {
|
|
145
|
+
case 'before':
|
|
146
|
+
case 'after':
|
|
147
|
+
this.insertItem(targetItem, sourceItem, this.itemDropTarget.position);
|
|
148
|
+
sourceItem.updateLevel(targetItem.level);
|
|
149
|
+
break;
|
|
150
|
+
case 'inside':
|
|
151
|
+
this.insertChildrenItem(targetItem, sourceItem);
|
|
152
|
+
sourceItem.updateLevel(targetItem.level + 1);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
this.dragDropped.emit({
|
|
156
|
+
source: sourceItem.origin,
|
|
157
|
+
sourceParent: this.getParentByItem(sourceItem)?.origin,
|
|
158
|
+
target: targetItem.origin,
|
|
159
|
+
targetParent: this.getParentByItem(targetItem)?.origin,
|
|
160
|
+
dropPosition: this.itemDropTarget.position
|
|
161
|
+
});
|
|
162
|
+
this.cleanupDragArtifacts(true);
|
|
163
|
+
}
|
|
164
|
+
trackBy(index, item) {
|
|
165
|
+
return item.id || index;
|
|
166
|
+
}
|
|
167
|
+
ngOnDestroy() {
|
|
168
|
+
this.destroy$.next();
|
|
169
|
+
this.destroy$.complete();
|
|
170
|
+
}
|
|
171
|
+
removeItem(item) {
|
|
172
|
+
this.renderData.splice(this.renderData.indexOf(item), 1);
|
|
173
|
+
this.flatData.splice(this.flatData.indexOf(item), 1);
|
|
174
|
+
}
|
|
175
|
+
insertItem(target, inserted, position) {
|
|
176
|
+
if (position === 'before') {
|
|
177
|
+
this.renderData.splice(this.renderData.indexOf(target), 0, inserted);
|
|
178
|
+
this.flatData.splice(this.flatData.indexOf(target), 0, inserted);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
const dragRef = this.cdkDrags.find((drag) => drag.data === target);
|
|
182
|
+
// 如果目标项是展开的,插入的 index 位置需要考虑子项的数量
|
|
183
|
+
let childrenCount = 0;
|
|
184
|
+
if (target.expanded) {
|
|
185
|
+
childrenCount = this.getChildrenElementsByElement(dragRef.element.nativeElement)?.length || 0;
|
|
186
|
+
}
|
|
187
|
+
this.renderData.splice(this.renderData.indexOf(target) + 1 + childrenCount, 0, inserted);
|
|
188
|
+
this.flatData.splice(this.flatData.indexOf(target) + 1 + childrenCount, 0, inserted);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
insertChildrenItem(target, inserted) {
|
|
192
|
+
if (target.expanded) {
|
|
193
|
+
this.renderData.splice(this.renderData.indexOf(target) + target.children.length + 1, 0, inserted);
|
|
194
|
+
this.flatData.splice(this.flatData.indexOf(target) + target.children.length + 1, 0, inserted);
|
|
195
|
+
}
|
|
196
|
+
target.children.push(inserted);
|
|
197
|
+
}
|
|
198
|
+
getParentByItem(item) {
|
|
199
|
+
return (this.flatData || []).find((n) => {
|
|
200
|
+
return n.children?.includes(item);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
getChildrenElementsByElement(element) {
|
|
204
|
+
// 通过循环持续查找 next element,如果 element 的 level 小于当前 item 的 level,则为它的 children
|
|
205
|
+
const children = [];
|
|
206
|
+
const dragRef = this.itemDragRefMap.get(element);
|
|
207
|
+
let nextElement = element.nextElementSibling;
|
|
208
|
+
let nextDragRef = this.itemDragRefMap.get(nextElement);
|
|
209
|
+
while (nextDragRef && nextDragRef.data.level > dragRef.data.level) {
|
|
210
|
+
children.push(nextElement);
|
|
211
|
+
nextElement = nextElement.nextElementSibling;
|
|
212
|
+
nextDragRef = this.itemDragRefMap.get(nextElement);
|
|
213
|
+
}
|
|
214
|
+
return children;
|
|
215
|
+
}
|
|
216
|
+
getTargetPosition(target, event) {
|
|
217
|
+
const targetRect = target.getBoundingClientRect();
|
|
218
|
+
const beforeOrAfterGap = targetRect.height * 0.3;
|
|
219
|
+
// 将 Item 高度分为上中下三段,其中上下的 Gap 为 height 的 30%,通过判断鼠标位置在哪一段 gap 来计算对应的位置
|
|
220
|
+
if (event.pointerPosition.y - targetRect.top < beforeOrAfterGap) {
|
|
221
|
+
return 'before';
|
|
222
|
+
}
|
|
223
|
+
else if (event.pointerPosition.y >= targetRect.bottom - beforeOrAfterGap) {
|
|
224
|
+
return 'after';
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
return 'inside';
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
showDropPositionPlaceholder(targetElement) {
|
|
231
|
+
this.cleanupDragArtifacts();
|
|
232
|
+
if (this.itemDropTarget && targetElement) {
|
|
233
|
+
targetElement.classList.add(`drop-position-${this.itemDropTarget.position}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
cleanupDragArtifacts(dropped = false) {
|
|
237
|
+
if (dropped) {
|
|
238
|
+
this.itemDropTarget = null;
|
|
239
|
+
}
|
|
240
|
+
this.document.querySelectorAll('.drop-position-before').forEach((element) => element.classList.remove('drop-position-before'));
|
|
241
|
+
this.document.querySelectorAll('.drop-position-after').forEach((element) => element.classList.remove('drop-position-after'));
|
|
242
|
+
this.document.querySelectorAll('.drop-position-inside').forEach((element) => element.classList.remove('drop-position-inside'));
|
|
243
|
+
this.document.querySelectorAll('.drag-item-hide').forEach((element) => element.classList.remove('drop-item-hide'));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
GanttTableBodyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableBodyComponent, deps: [{ token: GANTT_ABSTRACT_TOKEN }, { token: GANTT_UPPER_TOKEN }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component });
|
|
247
|
+
GanttTableBodyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttTableBodyComponent, selector: "gantt-table-body", inputs: { renderData: "renderData", flatData: "flatData", columns: "columns", groupTemplate: "groupTemplate", emptyTemplate: "emptyTemplate", rowBeforeTemplate: "rowBeforeTemplate", rowAfterTemplate: "rowAfterTemplate", draggable: "draggable", dropEnterPredicate: "dropEnterPredicate" }, outputs: { dragDropped: "dragDropped", itemClick: "itemClick" }, host: { properties: { "class.gantt-table-draggable": "this.draggable", "class.gantt-table-body": "this.ganttTableClass", "class.gantt-table-empty": "this.ganttTableEmptyClass", "class.gantt-table-dragging": "this.ganttTableDragging" } }, viewQueries: [{ propertyName: "cdkDrags", predicate: (CdkDrag), descendants: true }], ngImport: i0, template: "<div\n class=\"gantt-table-body-container\"\n cdkDropList\n [cdkDropListAutoScrollStep]=\"6\"\n [cdkDropListData]=\"renderData\"\n [cdkDropListSortingDisabled]=\"true\"\n (cdkDropListDropped)=\"onListDropped($event)\"\n>\n <ng-container *ngIf=\"!renderData?.length\">\n <ng-container *ngIf=\"!emptyTemplate\">\n <gantt-icon class=\"empty-icon\" iconName=\"empty\"></gantt-icon>\n <div class=\"empty-text\">\u6CA1\u6709\u6570\u636E</div>\n </ng-container>\n <ng-template [ngTemplateOutlet]=\"emptyTemplate\"></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"renderData && renderData.length > 0\">\n <ng-container *ngFor=\"let item of renderData; trackBy: trackBy\">\n <div class=\"gantt-table-group\" [ngClass]=\"item.class\" *ngIf=\"item.items\">\n <div class=\"gantt-table-group-title\" [class.expanded]=\"item.expanded\" (click)=\"expandGroup(item)\">\n <gantt-icon class=\"expand-icon\" [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"></gantt-icon>\n <ng-container *ngIf=\"groupTemplate; else default\">\n <ng-template\n [ngTemplateOutlet]=\"groupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, group: item.origin }\"\n ></ng-template>\n </ng-container>\n <ng-template #default>\n <span class=\"group-title\">{{ item.title }}</span>\n </ng-template>\n </div>\n </div>\n\n <div\n *ngIf=\"!item.items\"\n (click)=\"itemClick.emit({ event: $event, selectedValue: item.origin })\"\n cdkDrag\n [cdkDragData]=\"item\"\n [cdkDragDisabled]=\"(draggable && item.itemDraggable === false) || !draggable\"\n (cdkDragStarted)=\"onItemDragStarted($event)\"\n (cdkDragEnded)=\"onItemDragEnded($event)\"\n (cdkDragMoved)=\"emitItemDragMoved($event)\"\n class=\"gantt-table-item\"\n [class.gantt-table-item-with-group]=\"hasGroup\"\n [class.gantt-table-item-first-level-group]=\"item.level === 0 && (item.type | isGanttRangeItem)\"\n [style.height.px]=\"gantt.styles.lineHeight\"\n [style.lineHeight.px]=\"gantt.styles.lineHeight\"\n [class.gantt-table-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-template\n [ngTemplateOutlet]=\"rowBeforeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n\n <div class=\"gantt-table-column\" *ngFor=\"let column of columns; let first = first\" [style.width]=\"column.columnWidth\">\n <!-- drag icon -->\n <gantt-icon\n *ngIf=\"first && draggable\"\n class=\"gantt-drag-handle\"\n iconName=\"drag\"\n cdkDragHandle\n [cdkDragHandleDisabled]=\"(draggable && item.itemDraggable === false) || !draggable\"\n ></gantt-icon>\n <!-- expand icon -->\n <div\n *ngIf=\"column?.showExpandIcon || (!hasExpandIcon && first)\"\n class=\"gantt-expand-icon\"\n [style.marginLeft.px]=\"item.level * 20\"\n >\n <ng-container *ngIf=\"item.level < gantt.maxLevel - 1 && item.expandable\">\n <gantt-icon\n *ngIf=\"!item.loading\"\n class=\"expand-icon\"\n [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"\n (click)=\"expandChildren($event, item)\"\n >\n </gantt-icon>\n <gantt-icon *ngIf=\"item.loading\" [iconName]=\"'loading'\"></gantt-icon>\n </ng-container>\n </div>\n <!-- column content -->\n <div class=\"gantt-table-column-content\">\n <ng-template\n [ngTemplateOutlet]=\"column.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </div>\n <ng-template\n [ngTemplateOutlet]=\"rowAfterTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </ng-container>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: i3.GanttIconComponent, selector: "gantt-icon", inputs: ["iconName"] }, { kind: "pipe", type: i4.IsGanttRangeItemPipe, name: "isGanttRangeItem" }] });
|
|
248
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableBodyComponent, decorators: [{
|
|
249
|
+
type: Component,
|
|
250
|
+
args: [{ selector: 'gantt-table-body', template: "<div\n class=\"gantt-table-body-container\"\n cdkDropList\n [cdkDropListAutoScrollStep]=\"6\"\n [cdkDropListData]=\"renderData\"\n [cdkDropListSortingDisabled]=\"true\"\n (cdkDropListDropped)=\"onListDropped($event)\"\n>\n <ng-container *ngIf=\"!renderData?.length\">\n <ng-container *ngIf=\"!emptyTemplate\">\n <gantt-icon class=\"empty-icon\" iconName=\"empty\"></gantt-icon>\n <div class=\"empty-text\">\u6CA1\u6709\u6570\u636E</div>\n </ng-container>\n <ng-template [ngTemplateOutlet]=\"emptyTemplate\"></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"renderData && renderData.length > 0\">\n <ng-container *ngFor=\"let item of renderData; trackBy: trackBy\">\n <div class=\"gantt-table-group\" [ngClass]=\"item.class\" *ngIf=\"item.items\">\n <div class=\"gantt-table-group-title\" [class.expanded]=\"item.expanded\" (click)=\"expandGroup(item)\">\n <gantt-icon class=\"expand-icon\" [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"></gantt-icon>\n <ng-container *ngIf=\"groupTemplate; else default\">\n <ng-template\n [ngTemplateOutlet]=\"groupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, group: item.origin }\"\n ></ng-template>\n </ng-container>\n <ng-template #default>\n <span class=\"group-title\">{{ item.title }}</span>\n </ng-template>\n </div>\n </div>\n\n <div\n *ngIf=\"!item.items\"\n (click)=\"itemClick.emit({ event: $event, selectedValue: item.origin })\"\n cdkDrag\n [cdkDragData]=\"item\"\n [cdkDragDisabled]=\"(draggable && item.itemDraggable === false) || !draggable\"\n (cdkDragStarted)=\"onItemDragStarted($event)\"\n (cdkDragEnded)=\"onItemDragEnded($event)\"\n (cdkDragMoved)=\"emitItemDragMoved($event)\"\n class=\"gantt-table-item\"\n [class.gantt-table-item-with-group]=\"hasGroup\"\n [class.gantt-table-item-first-level-group]=\"item.level === 0 && (item.type | isGanttRangeItem)\"\n [style.height.px]=\"gantt.styles.lineHeight\"\n [style.lineHeight.px]=\"gantt.styles.lineHeight\"\n [class.gantt-table-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-template\n [ngTemplateOutlet]=\"rowBeforeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n\n <div class=\"gantt-table-column\" *ngFor=\"let column of columns; let first = first\" [style.width]=\"column.columnWidth\">\n <!-- drag icon -->\n <gantt-icon\n *ngIf=\"first && draggable\"\n class=\"gantt-drag-handle\"\n iconName=\"drag\"\n cdkDragHandle\n [cdkDragHandleDisabled]=\"(draggable && item.itemDraggable === false) || !draggable\"\n ></gantt-icon>\n <!-- expand icon -->\n <div\n *ngIf=\"column?.showExpandIcon || (!hasExpandIcon && first)\"\n class=\"gantt-expand-icon\"\n [style.marginLeft.px]=\"item.level * 20\"\n >\n <ng-container *ngIf=\"item.level < gantt.maxLevel - 1 && item.expandable\">\n <gantt-icon\n *ngIf=\"!item.loading\"\n class=\"expand-icon\"\n [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"\n (click)=\"expandChildren($event, item)\"\n >\n </gantt-icon>\n <gantt-icon *ngIf=\"item.loading\" [iconName]=\"'loading'\"></gantt-icon>\n </ng-container>\n </div>\n <!-- column content -->\n <div class=\"gantt-table-column-content\">\n <ng-template\n [ngTemplateOutlet]=\"column.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </div>\n <ng-template\n [ngTemplateOutlet]=\"rowAfterTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </ng-container>\n </ng-container>\n</div>\n" }]
|
|
251
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
252
|
+
type: Inject,
|
|
253
|
+
args: [GANTT_ABSTRACT_TOKEN]
|
|
254
|
+
}] }, { type: i5.GanttUpper, decorators: [{
|
|
255
|
+
type: Inject,
|
|
256
|
+
args: [GANTT_UPPER_TOKEN]
|
|
257
|
+
}] }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
|
|
258
|
+
type: Inject,
|
|
259
|
+
args: [DOCUMENT]
|
|
260
|
+
}] }]; }, propDecorators: { renderData: [{
|
|
261
|
+
type: Input
|
|
262
|
+
}], flatData: [{
|
|
263
|
+
type: Input
|
|
264
|
+
}], columns: [{
|
|
265
|
+
type: Input
|
|
266
|
+
}], groupTemplate: [{
|
|
267
|
+
type: Input
|
|
268
|
+
}], emptyTemplate: [{
|
|
269
|
+
type: Input
|
|
270
|
+
}], rowBeforeTemplate: [{
|
|
271
|
+
type: Input
|
|
272
|
+
}], rowAfterTemplate: [{
|
|
273
|
+
type: Input
|
|
274
|
+
}], draggable: [{
|
|
275
|
+
type: HostBinding,
|
|
276
|
+
args: ['class.gantt-table-draggable']
|
|
277
|
+
}, {
|
|
278
|
+
type: Input
|
|
279
|
+
}], dropEnterPredicate: [{
|
|
280
|
+
type: Input
|
|
281
|
+
}], dragDropped: [{
|
|
282
|
+
type: Output
|
|
283
|
+
}], itemClick: [{
|
|
284
|
+
type: Output
|
|
285
|
+
}], ganttTableClass: [{
|
|
286
|
+
type: HostBinding,
|
|
287
|
+
args: ['class.gantt-table-body']
|
|
288
|
+
}], ganttTableEmptyClass: [{
|
|
289
|
+
type: HostBinding,
|
|
290
|
+
args: ['class.gantt-table-empty']
|
|
291
|
+
}], ganttTableDragging: [{
|
|
292
|
+
type: HostBinding,
|
|
293
|
+
args: ['class.gantt-table-dragging']
|
|
294
|
+
}], cdkDrags: [{
|
|
295
|
+
type: ViewChildren,
|
|
296
|
+
args: [(CdkDrag)]
|
|
297
|
+
}] } });
|
|
298
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FudHQtdGFibGUtYm9keS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9nYW50dC9zcmMvY29tcG9uZW50cy90YWJsZS9ib2R5L2dhbnR0LXRhYmxlLWJvZHkuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvZ2FudHQvc3JjL2NvbXBvbmVudHMvdGFibGUvYm9keS9nYW50dC10YWJsZS1ib2R5LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNFLE9BQU8sRUFDSCxTQUFTLEVBQ1QsV0FBVyxFQUdYLEtBQUssRUFFTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFlBQVksRUFHWixZQUFZLEVBRWYsTUFBTSxlQUFlLENBQUM7QUFVdkIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUEwQixvQkFBb0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQzVFLE9BQU8sRUFBYyxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxPQUFPLEVBQXNELE1BQU0sd0JBQXdCLENBQUM7QUFDckcsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7Ozs7O0FBSzNDLE1BQU0sT0FBTyx1QkFBdUI7SUFFaEMsSUFBYSxVQUFVLENBQUMsSUFBZ0Q7UUFDcEUsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFCLElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDaEQs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QUFRO3NCQUF0QyxZQUFZO3VCQUFDLENBQUEsT0FBZSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBmaWx0ZXIsIHN0YXJ0V2l0aCwgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICAgIENvbXBvbmVudCxcbiAgICBIb3N0QmluZGluZyxcbiAgICBUZW1wbGF0ZVJlZixcbiAgICBRdWVyeUxpc3QsXG4gICAgSW5wdXQsXG4gICAgT25Jbml0LFxuICAgIEluamVjdCxcbiAgICBPdXRwdXQsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIE9uRGVzdHJveSxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBWaWV3Q2hpbGRyZW4sXG4gICAgQWZ0ZXJWaWV3SW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gICAgR2FudHRJdGVtSW50ZXJuYWwsXG4gICAgR2FudHRHcm91cEludGVybmFsLFxuICAgIEdhbnR0U2VsZWN0ZWRFdmVudCxcbiAgICBHYW50dFRhYmxlRHJvcFBvc2l0aW9uLFxuICAgIEdhbnR0VGFibGVEcmFnRW50ZXJQcmVkaWNhdGVDb250ZXh0LFxuICAgIEdhbnR0VGFibGVEcmFnRHJvcHBlZEV2ZW50XG59IGZyb20gJy4uLy4uLy4uL2NsYXNzJztcbmltcG9ydCB7IE5neEdhbnR0VGFibGVDb2x1bW5Db21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi90YWJsZS9nYW50dC1jb2x1bW4uY29tcG9uZW50JztcbmltcG9ydCB7IGNvZXJjZUNzc1BpeGVsVmFsdWUgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHsgR2FudHRBYnN0cmFjdENvbXBvbmVudCwgR0FOVFRfQUJTVFJBQ1RfVE9LRU4gfSBmcm9tICcuLi8uLi8uLi9nYW50dC1hYnN0cmFjdCc7XG5pbXBvcnQgeyBkZWZhdWx0Q29sdW1uV2lkdGggfSBmcm9tICcuLi9oZWFkZXIvZ2FudHQtdGFibGUtaGVhZGVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBHYW50dFVwcGVyLCBHQU5UVF9VUFBFUl9UT0tFTiB9IGZyb20gJy4uLy4uLy4uL2dhbnR0LXVwcGVyJztcbmltcG9ydCB7IENka0RyYWcsIENka0RyYWdEcm9wLCBDZGtEcmFnRW5kLCBDZGtEcmFnTW92ZSwgQ2RrRHJhZ1N0YXJ0IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2dhbnR0LXRhYmxlLWJvZHknLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9nYW50dC10YWJsZS1ib2R5LmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBHYW50dFRhYmxlQm9keUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcbiAgICBwcml2YXRlIF9yZW5kZXJEYXRhOiAoR2FudHRHcm91cEludGVybmFsIHwgR2FudHRJdGVtSW50ZXJuYWwpW107XG4gICAgQElucHV0KCkgc2V0IHJlbmRlckRhdGEoZGF0YTogKEdhbnR0R3JvdXBJbnRlcm5hbCB8IEdhbnR0SXRlbUludGVybmFsKVtdKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0RGF0YSA9IGRhdGFbMF07XG4gICAgICAgIGlmIChmaXJzdERhdGEgJiYgZmlyc3REYXRhLmhhc093blByb3BlcnR5KCdpdGVtcycpKSB7XG4gICAgICAgICAgICB0aGlzLmhhc0dyb3VwID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmdhbnR0VGFibGVFbXB0eUNsYXNzID0gZGF0YT8ubGVuZ3RoID8gZmFsc2UgOiB0cnVlO1xuICAgICAgICB0aGlzLl9yZW5kZXJEYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICBnZXQgcmVuZGVyRGF0YSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlbmRlckRhdGE7XG4gICAgfVxuXG4gICAgQElucHV0KCkgZmxhdERhdGE6IChHYW50dEdyb3VwSW50ZXJuYWwgfCBHYW50dEl0ZW1JbnRlcm5hbClbXTtcblxuICAgIEBJbnB1dCgpIGNvbHVtbnM6IFF1ZXJ5TGlzdDxOZ3hHYW50dFRhYmxlQ29sdW1uQ29tcG9uZW50PjtcblxuICAgIEBJbnB1dCgpIGdyb3VwVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICBASW5wdXQoKSBlbXB0eVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgQElucHV0KCkgcm93QmVmb3JlVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICBASW5wdXQoKSByb3dBZnRlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5nYW50dC10YWJsZS1kcmFnZ2FibGUnKVxuICAgIEBJbnB1dCgpXG4gICAgZHJhZ2dhYmxlID0gZmFsc2U7XG5cbiAgICBASW5wdXQoKSBkcm9wRW50ZXJQcmVkaWNhdGU/OiAoY29udGV4dDogR2FudHRUYWJsZURyYWdFbnRlclByZWRpY2F0ZUNvbnRleHQpID0+IGJvb2xlYW47XG5cbiAgICBAT3V0cHV0KCkgZHJhZ0Ryb3BwZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEdhbnR0VGFibGVEcmFnRHJvcHBlZEV2ZW50PigpO1xuXG4gICAgQE91dHB1dCgpIGl0ZW1DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8R2FudHRTZWxlY3RlZEV2ZW50PigpO1xuXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5nYW50dC10YWJsZS1ib2R5JykgZ2FudHRUYWJsZUNsYXNzID0gdHJ1ZTtcblxuICAgIEBIb3N0QmluZGluZygnY2xhc3MuZ2FudHQtdGFibGUtZW1wdHknKSBnYW50dFRhYmxlRW1wdHlDbGFzcyA9IGZhbHNlO1xuXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5nYW50dC10YWJsZS1kcmFnZ2luZycpIGdhbnR0VGFibGVEcmFnZ2luZyA9IGZhbHNlO1xuXG4gICAgQFZpZXdDaGlsZHJlbihDZGtEcmFnPHN0cmluZz4pIGNka0RyYWdzOiBRdWVyeUxpc3Q8Q2RrRHJhZzxHYW50dEl0ZW1JbnRlcm5hbD4+O1xuXG4gICAgcHVibGljIGhhc0dyb3VwOiBib29sZWFuO1xuXG4gICAgcHVibGljIGhhc0V4cGFuZEljb24gPSBmYWxzZTtcblxuICAgIC8vIOe8k+WtmCBFbGVtZW50IOWSjCBEcmFnUmVmIOeahOWFs+ezu++8jOaWueS+v+WcqCBJdGVtIOaLluWKqOaXtuafpeaJvlxuICAgIHByaXZhdGUgaXRlbURyYWdSZWZNYXAgPSBuZXcgTWFwPEhUTUxFbGVtZW50LCBDZGtEcmFnPEdhbnR0SXRlbUludGVybmFsPj4oKTtcblxuICAgIHByaXZhdGUgaXRlbURyYWdNb3ZlZCA9IG5ldyBTdWJqZWN0PENka0RyYWdNb3ZlPigpO1xuXG4gICAgLy8gSXRlbSDmi5bliqjnu4/ov4fnm67moIfml7bkuLTml7borrDlvZXnm67moIdpZOS7peWPiuebuOWvueW6lOebruagh+eahOS9jee9rlxuICAgIHByaXZhdGUgaXRlbURyb3BUYXJnZXQ6IHtcbiAgICAgICAgcG9zaXRpb24/OiBHYW50dFRhYmxlRHJvcFBvc2l0aW9uO1xuICAgICAgICBpZD86IHN0cmluZztcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgQEluamVjdChHQU5UVF9BQlNUUkFDVF9UT0tFTikgcHVibGljIGdhbnR0OiBHYW50dEFic3RyYWN0Q29tcG9uZW50LFxuICAgICAgICBASW5qZWN0KEdBTlRUX1VQUEVSX1RPS0VOKSBwdWJsaWMgZ2FudHRVcHBlcjogR2FudHRVcHBlcixcbiAgICAgICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudFxuICAgICkge31cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmNvbHVtbnMuY2hhbmdlcy5waXBlKHN0YXJ0V2l0aCh0aGlzLmNvbHVtbnMpLCB0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmhhc0V4cGFuZEljb24gPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuY29sdW1ucy5mb3JFYWNoKChjb2x1bW4pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbHVtbi5jb2x1bW5XaWR0aCkge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW4uY29sdW1uV2lkdGggPSBjb2VyY2VDc3NQaXhlbFZhbHVlKGRlZmF1bHRDb2x1bW5XaWR0aCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChjb2x1bW4uc2hvd0V4cGFuZEljb24pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNFeHBhbmRJY29uID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNka0RyYWdzLmNoYW5nZXNcbiAgICAgICAgICAgIC5waXBlKHN0YXJ0V2l0aCh0aGlzLmNka0RyYWdzKSwgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZHJhZ3M6IFF1ZXJ5TGlzdDxDZGtEcmFnPEdhbnR0SXRlbUludGVybmFsPj4pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLml0ZW1EcmFnUmVmTWFwLmNsZWFyKCk7XG4gICAgICAgICAgICAgICAgZHJhZ3MuZm9yRWFjaCgoZHJhZykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZHJhZy5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjZGtEcmFnIOWPmOWMluaXtu+8jOe8k+WtmCBFbGVtZW50IOS4jiBEcmFnUmVmIOeahOWFs+ezu++8jOaWueS+vyBEcmFnIE1vdmUg5pe25p+l5om+XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLml0ZW1EcmFnUmVmTWFwLnNldChkcmFnLmVsZW1lbnQubmF0aXZlRWxlbWVudCwgZHJhZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuaXRlbURyYWdNb3ZlZFxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgZGVib3VuY2VUaW1lKDMwKSxcbiAgICAgICAgICAgICAgICAvLyAgZGVib3VuY2Ug5Y+v6IO95Lya5a+86Ie05ouW5Yqo57uT5p2f5ZCO5LuN54S25omn6KGMIG1vdmVkIO+8jOaJgOS7pemAmui/h+WIpOaWrSBkcmFnZ2luZyDnirbmgIHmnaXov4fmu6Tml6DmlYggbW92ZWRcbiAgICAgICAgICAgICAgICBmaWx0ZXIoKGV2ZW50OiBDZGtEcmFnTW92ZSkgPT4gZXZlbnQuc291cmNlLl9kcmFnUmVmLmlzRHJhZ2dpbmcoKSksXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMub25JdGVtRHJhZ01vdmVkKGV2ZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIGV4cGFuZEdyb3VwKGdyb3VwOiBHYW50dEdyb3VwSW50ZXJuYWwpIHtcbiAgICAgICAgdGhpcy5nYW50dC5leHBhbmRHcm91cChncm91cCk7XG4gICAgfVxuXG4gICAgZXhwYW5kQ2hpbGRyZW4oZXZlbnQ6IE1vdXNlRXZlbnQsIGl0ZW06IEdhbnR0SXRlbUludGVybmFsKSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB0aGlzLmdhbnR0LmV4cGFuZENoaWxkcmVuKGl0ZW0pO1xuICAgIH1cblxuICAgIG9uSXRlbURyYWdTdGFydGVkKGV2ZW50OiBDZGtEcmFnU3RhcnQ8R2FudHRJdGVtSW50ZXJuYWw+KSB7XG4gICAgICAgIHRoaXMuZ2FudHRUYWJsZURyYWdnaW5nID0gdHJ1ZTtcbiAgICAgICAgLy8g5ouW5Yqo5byA5aeL5pe26ZqQ6JeP5omA5pyJ55qE5a2Q6aG5XG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5nZXRDaGlsZHJlbkVsZW1lbnRzQnlFbGVtZW50KGV2ZW50LnNvdXJjZS5nZXRQbGFjZWhvbGRlckVsZW1lbnQoKSk7XG4gICAgICAgIGNoaWxkcmVuLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZHJhZy1pdGVtLWhpZGUnKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZW1pdEl0ZW1EcmFnTW92ZWQoZXZlbnQ6IENka0RyYWdNb3ZlKSB7XG4gICAgICAgIHRoaXMuaXRlbURyYWdNb3ZlZC5uZXh0KGV2ZW50KTtcbiAgICB9XG5cbiAgICBvbkl0ZW1EcmFnTW92ZWQoZXZlbnQ6IENka0RyYWdNb3ZlPEdhbnR0SXRlbUludGVybmFsPikge1xuICAgICAgICAvLyDpgJrov4fpvKDmoIfkvY3nva7mn6Xmib7lr7nlupTnmoTnm67moIcgSXRlbSDlhYPntKBcbiAgICAgICAgbGV0IGN1cnJlbnRQb2ludEVsZW1lbnQgPSB0aGlzLmRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZXZlbnQucG9pbnRlclBvc2l0aW9uLngsIGV2ZW50LnBvaW50ZXJQb3NpdGlvbi55KSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKCFjdXJyZW50UG9pbnRFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLmNsZWFudXBEcmFnQXJ0aWZhY3RzKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHRhcmdldEVsZW1lbnQgPSBjdXJyZW50UG9pbnRFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnZ2FudHQtdGFibGUtaXRlbScpXG4gICAgICAgICAgICA/IGN1cnJlbnRQb2ludEVsZW1lbnRcbiAgICAgICAgICAgIDogKGN1cnJlbnRQb2ludEVsZW1lbnQuY2xvc2VzdCgnLmdhbnR0LXRhYmxlLWl0ZW0nKSBhcyBIVE1MRWxlbWVudCk7XG4gICAgICAgIGlmICghdGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5jbGVhbnVwRHJhZ0FydGlmYWN0cygpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g57yT5a2Y5pS+572u55uu5qCHSWQg5bm26K6h566X6byg5qCH55u45a+55bqU55qE5L2N572uXG4gICAgICAgIHRoaXMuaXRlbURyb3BUYXJnZXQgPSB7XG4gICAgICAgICAgICBpZDogdGhpcy5pdGVtRHJhZ1JlZk1hcC5nZXQodGFyZ2V0RWxlbWVudCk/LmRhdGEuaWQsXG4gICAgICAgICAgICBwb3NpdGlvbjogdGhpcy5nZXRUYXJnZXRQb3NpdGlvbih0YXJnZXRFbGVtZW50LCBldmVudClcbiAgICAgICAgfTtcblxuICAgICAgICAvLyDmiafooYzlpJbpg6jkvKDlhaXnmoQgZHJvcEVudGVyUHJlZGljYXRlIOWIpOaWreaYr+WQpuWFgeiuuOaLluWFpeebruagh+mhuVxuICAgICAgICBpZiAodGhpcy5kcm9wRW50ZXJQcmVkaWNhdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldERyYWdSZWYgPSB0aGlzLml0ZW1EcmFnUmVmTWFwLmdldCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0aGlzLmRyb3BFbnRlclByZWRpY2F0ZSh7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZTogZXZlbnQuc291cmNlLmRhdGEub3JpZ2luLFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXQ6IHRhcmdldERyYWdSZWYuZGF0YS5vcmlnaW4sXG4gICAgICAgICAgICAgICAgICAgIGRyb3BQb3NpdGlvbjogdGhpcy5pdGVtRHJvcFRhcmdldC5wb3NpdGlvblxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dEcm9wUG9zaXRpb25QbGFjZWhvbGRlcih0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtRHJvcFRhcmdldCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNob3dEcm9wUG9zaXRpb25QbGFjZWhvbGRlcih0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uSXRlbURyYWdFbmRlZChldmVudDogQ2RrRHJhZ0VuZDxHYW50dEl0ZW1JbnRlcm5hbD4pIHtcbiAgICAgICAgdGhpcy5nYW50dFRhYmxlRHJhZ2dpbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBvbkxpc3REcm9wcGVkKGV2ZW50OiBDZGtEcmFnRHJvcDxHYW50dEl0ZW1JbnRlcm5hbFtdLCBHYW50dEl0ZW1JbnRlcm5hbFtdLCBHYW50dEl0ZW1JbnRlcm5hbD4pIHtcbiAgICAgICAgaWYgKCF0aGlzLml0ZW1Ecm9wVGFyZ2V0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGFyZ2V0RHJhZ1JlZiA9IHRoaXMuY2RrRHJhZ3MuZmluZCgoaXRlbSkgPT4gaXRlbS5kYXRhPy5pZCA9PT0gdGhpcy5pdGVtRHJvcFRhcmdldC5pZCk7XG4gICAgICAgIGNvbnN0IHNvdXJjZUl0ZW0gPSBldmVudC5pdGVtLmRhdGE7XG4gICAgICAgIGNvbnN0IHRhcmdldEl0ZW0gPSB0YXJnZXREcmFnUmVmPy5kYXRhO1xuXG4gICAgICAgIHRoaXMucmVtb3ZlSXRlbShzb3VyY2VJdGVtKTtcblxuICAgICAgICBzd2l0Y2ggKHRoaXMuaXRlbURyb3BUYXJnZXQucG9zaXRpb24pIHtcbiAgICAgICAgICAgIGNhc2UgJ2JlZm9yZSc6XG4gICAgICAgICAgICBjYXNlICdhZnRlcic6XG4gICAgICAgICAgICAgICAgdGhpcy5pbnNlcnRJdGVtKHRhcmdldEl0ZW0sIHNvdXJjZUl0ZW0sIHRoaXMuaXRlbURyb3BUYXJnZXQucG9zaXRpb24pO1xuICAgICAgICAgICAgICAgIHNvdXJjZUl0ZW0udXBkYXRlTGV2ZWwodGFyZ2V0SXRlbS5sZXZlbCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpbnNpZGUnOlxuICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Q2hpbGRyZW5JdGVtKHRhcmdldEl0ZW0sIHNvdXJjZUl0ZW0pO1xuICAgICAgICAgICAgICAgIHNvdXJjZUl0ZW0udXBkYXRlTGV2ZWwodGFyZ2V0SXRlbS5sZXZlbCArIDEpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kcmFnRHJvcHBlZC5lbWl0KHtcbiAgICAgICAgICAgIHNvdXJjZTogc291cmNlSXRlbS5vcmlnaW4sXG4gICAgICAgICAgICBzb3VyY2VQYXJlbnQ6IHRoaXMuZ2V0UGFyZW50QnlJdGVtKHNvdXJjZUl0ZW0pPy5vcmlnaW4sXG4gICAgICAgICAgICB0YXJnZXQ6IHRhcmdldEl0ZW0ub3JpZ2luLFxuICAgICAgICAgICAgdGFyZ2V0UGFyZW50OiB0aGlzLmdldFBhcmVudEJ5SXRlbSh0YXJnZXRJdGVtKT8ub3JpZ2luLFxuICAgICAgICAgICAgZHJvcFBvc2l0aW9uOiB0aGlzLml0ZW1Ecm9wVGFyZ2V0LnBvc2l0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuY2xlYW51cERyYWdBcnRpZmFjdHModHJ1ZSk7XG4gICAgfVxuXG4gICAgdHJhY2tCeShpbmRleDogbnVtYmVyLCBpdGVtOiBHYW50dEdyb3VwSW50ZXJuYWwgfCBHYW50dEl0ZW1JbnRlcm5hbCkge1xuICAgICAgICByZXR1cm4gaXRlbS5pZCB8fCBpbmRleDtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbW92ZUl0ZW0oaXRlbTogR2FudHRJdGVtSW50ZXJuYWwpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJEYXRhLnNwbGljZSh0aGlzLnJlbmRlckRhdGEuaW5kZXhPZihpdGVtKSwgMSk7XG4gICAgICAgIHRoaXMuZmxhdERhdGEuc3BsaWNlKHRoaXMuZmxhdERhdGEuaW5kZXhPZihpdGVtKSwgMSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbnNlcnRJdGVtKHRhcmdldDogR2FudHRJdGVtSW50ZXJuYWwsIGluc2VydGVkOiBHYW50dEl0ZW1JbnRlcm5hbCwgcG9zaXRpb246ICdiZWZvcmUnIHwgJ2FmdGVyJykge1xuICAgICAgICBpZiAocG9zaXRpb24gPT09ICdiZWZvcmUnKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckRhdGEuc3BsaWNlKHRoaXMucmVuZGVyRGF0YS5pbmRleE9mKHRhcmdldCksIDAsIGluc2VydGVkKTtcbiAgICAgICAgICAgIHRoaXMuZmxhdERhdGEuc3BsaWNlKHRoaXMuZmxhdERhdGEuaW5kZXhPZih0YXJnZXQpLCAwLCBpbnNlcnRlZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBkcmFnUmVmID0gdGhpcy5jZGtEcmFncy5maW5kKChkcmFnKSA9PiBkcmFnLmRhdGEgPT09IHRhcmdldCk7XG4gICAgICAgICAgICAvLyDlpoLmnpznm67moIfpobnmmK/lsZXlvIDnmoTvvIzmj5LlhaXnmoQgaW5kZXgg5L2N572u6ZyA6KaB6ICD6JmR5a2Q6aG555qE5pWw6YePXG4gICAgICAgICAgICBsZXQgY2hpbGRyZW5Db3VudCA9IDA7XG4gICAgICAgICAgICBpZiAodGFyZ2V0LmV4cGFuZGVkKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW5Db3VudCA9IHRoaXMuZ2V0Q2hpbGRyZW5FbGVtZW50c0J5RWxlbWVudChkcmFnUmVmLmVsZW1lbnQubmF0aXZlRWxlbWVudCk/Lmxlbmd0aCB8fCAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJEYXRhLnNwbGljZSh0aGlzLnJlbmRlckRhdGEuaW5kZXhPZih0YXJnZXQpICsgMSArIGNoaWxkcmVuQ291bnQsIDAsIGluc2VydGVkKTtcbiAgICAgICAgICAgIHRoaXMuZmxhdERhdGEuc3BsaWNlKHRoaXMuZmxhdERhdGEuaW5kZXhPZih0YXJnZXQpICsgMSArIGNoaWxkcmVuQ291bnQsIDAsIGluc2VydGVkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5zZXJ0Q2hpbGRyZW5JdGVtKHRhcmdldDogR2FudHRJdGVtSW50ZXJuYWwsIGluc2VydGVkOiBHYW50dEl0ZW1JbnRlcm5hbCkge1xuICAgICAgICBpZiAodGFyZ2V0LmV4cGFuZGVkKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckRhdGEuc3BsaWNlKHRoaXMucmVuZGVyRGF0YS5pbmRleE9mKHRhcmdldCkgKyB0YXJnZXQuY2hpbGRyZW4ubGVuZ3RoICsgMSwgMCwgaW5zZXJ0ZWQpO1xuICAgICAgICAgICAgdGhpcy5mbGF0RGF0YS5zcGxpY2UodGhpcy5mbGF0RGF0YS5pbmRleE9mKHRhcmdldCkgKyB0YXJnZXQuY2hpbGRyZW4ubGVuZ3RoICsgMSwgMCwgaW5zZXJ0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIHRhcmdldC5jaGlsZHJlbi5wdXNoKGluc2VydGVkKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFBhcmVudEJ5SXRlbShpdGVtOiBHYW50dEl0ZW1JbnRlcm5hbCkge1xuICAgICAgICByZXR1cm4gKHRoaXMuZmxhdERhdGEgfHwgW10pLmZpbmQoKG46IEdhbnR0SXRlbUludGVybmFsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbi5jaGlsZHJlbj8uaW5jbHVkZXMoaXRlbSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q2hpbGRyZW5FbGVtZW50c0J5RWxlbWVudChlbGVtZW50OiBIVE1MRWxlbWVudCkge1xuICAgICAgICAvLyDpgJrov4flvqrnjq/mjIHnu63mn6Xmib4gbmV4dCBlbGVtZW5077yM5aaC5p6cIGVsZW1lbnQg55qEIGxldmVsIOWwj+S6juW9k+WJjSBpdGVtIOeahCBsZXZlbO+8jOWImeS4uuWug+eahCBjaGlsZHJlblxuICAgICAgICBjb25zdCBjaGlsZHJlbjogSFRNTEVsZW1lbnRbXSA9IFtdO1xuICAgICAgICBjb25zdCBkcmFnUmVmID0gdGhpcy5pdGVtRHJhZ1JlZk1hcC5nZXQoZWxlbWVudCk7XG4gICAgICAgIGxldCBuZXh0RWxlbWVudCA9IGVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBsZXQgbmV4dERyYWdSZWYgPSB0aGlzLml0ZW1EcmFnUmVmTWFwLmdldChuZXh0RWxlbWVudCk7XG4gICAgICAgIHdoaWxlIChuZXh0RHJhZ1JlZiAmJiBuZXh0RHJhZ1JlZi5kYXRhLmxldmVsID4gZHJhZ1JlZi5kYXRhLmxldmVsKSB7XG4gICAgICAgICAgICBjaGlsZHJlbi5wdXNoKG5leHRFbGVtZW50KTtcbiAgICAgICAgICAgIG5leHRFbGVtZW50ID0gbmV4dEVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgICAgbmV4dERyYWdSZWYgPSB0aGlzLml0ZW1EcmFnUmVmTWFwLmdldChuZXh0RWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNoaWxkcmVuO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0VGFyZ2V0UG9zaXRpb24odGFyZ2V0OiBIVE1MRWxlbWVudCwgZXZlbnQ6IENka0RyYWdNb3ZlKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldFJlY3QgPSB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IGJlZm9yZU9yQWZ0ZXJHYXAgPSB0YXJnZXRSZWN0LmhlaWdodCAqIDAuMztcbiAgICAgICAgLy8g5bCGIEl0ZW0g6auY5bqm5YiG5Li65LiK5Lit5LiL5LiJ5q6177yM5YW25Lit5LiK5LiL55qEIEdhcCDkuLogaGVpZ2h0IOeahCAzMCXvvIzpgJrov4fliKTmlq3pvKDmoIfkvY3nva7lnKjlk6rkuIDmrrUgZ2FwIOadpeiuoeeul+WvueW6lOeahOS9jee9rlxuICAgICAgICBpZiAoZXZlbnQucG9pbnRlclBvc2l0aW9uLnkgLSB0YXJnZXRSZWN0LnRvcCA8IGJlZm9yZU9yQWZ0ZXJHYXApIHtcbiAgICAgICAgICAgIHJldHVybiAnYmVmb3JlJztcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5wb2ludGVyUG9zaXRpb24ueSA+PSB0YXJnZXRSZWN0LmJvdHRvbSAtIGJlZm9yZU9yQWZ0ZXJHYXApIHtcbiAgICAgICAgICAgIHJldHVybiAnYWZ0ZXInO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuICdpbnNpZGUnO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzaG93RHJvcFBvc2l0aW9uUGxhY2Vob2xkZXIodGFyZ2V0RWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5jbGVhbnVwRHJhZ0FydGlmYWN0cygpO1xuICAgICAgICBpZiAodGhpcy5pdGVtRHJvcFRhcmdldCAmJiB0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50LmNsYXNzTGlzdC5hZGQoYGRyb3AtcG9zaXRpb24tJHt0aGlzLml0ZW1Ecm9wVGFyZ2V0LnBvc2l0aW9ufWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhbnVwRHJhZ0FydGlmYWN0cyhkcm9wcGVkID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKGRyb3BwZWQpIHtcbiAgICAgICAgICAgIHRoaXMuaXRlbURyb3BUYXJnZXQgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmRyb3AtcG9zaXRpb24tYmVmb3JlJykuZm9yRWFjaCgoZWxlbWVudCkgPT4gZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdkcm9wLXBvc2l0aW9uLWJlZm9yZScpKTtcbiAgICAgICAgdGhpcy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZHJvcC1wb3NpdGlvbi1hZnRlcicpLmZvckVhY2goKGVsZW1lbnQpID0+IGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZHJvcC1wb3NpdGlvbi1hZnRlcicpKTtcbiAgICAgICAgdGhpcy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZHJvcC1wb3NpdGlvbi1pbnNpZGUnKS5mb3JFYWNoKChlbGVtZW50KSA9PiBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Ryb3AtcG9zaXRpb24taW5zaWRlJykpO1xuICAgICAgICB0aGlzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5kcmFnLWl0ZW0taGlkZScpLmZvckVhY2goKGVsZW1lbnQpID0+IGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZHJvcC1pdGVtLWhpZGUnKSk7XG4gICAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cImdhbnR0LXRhYmxlLWJvZHktY29udGFpbmVyXCJcbiAgY2RrRHJvcExpc3RcbiAgW2Nka0Ryb3BMaXN0QXV0b1Njcm9sbFN0ZXBdPVwiNlwiXG4gIFtjZGtEcm9wTGlzdERhdGFdPVwicmVuZGVyRGF0YVwiXG4gIFtjZGtEcm9wTGlzdFNvcnRpbmdEaXNhYmxlZF09XCJ0cnVlXCJcbiAgKGNka0Ryb3BMaXN0RHJvcHBlZCk9XCJvbkxpc3REcm9wcGVkKCRldmVudClcIlxuPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXJlbmRlckRhdGE/Lmxlbmd0aFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhZW1wdHlUZW1wbGF0ZVwiPlxuICAgICAgPGdhbnR0LWljb24gY2xhc3M9XCJlbXB0eS1pY29uXCIgaWNvbk5hbWU9XCJlbXB0eVwiPjwvZ2FudHQtaWNvbj5cbiAgICAgIDxkaXYgY2xhc3M9XCJlbXB0eS10ZXh0XCI+5rKh5pyJ5pWw5o2uPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImVtcHR5VGVtcGxhdGVcIj48L25nLXRlbXBsYXRlPlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicmVuZGVyRGF0YSAmJiByZW5kZXJEYXRhLmxlbmd0aCA+IDBcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJlbmRlckRhdGE7IHRyYWNrQnk6IHRyYWNrQnlcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJnYW50dC10YWJsZS1ncm91cFwiIFtuZ0NsYXNzXT1cIml0ZW0uY2xhc3NcIiAqbmdJZj1cIml0ZW0uaXRlbXNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImdhbnR0LXRhYmxlLWdyb3VwLXRpdGxlXCIgW2NsYXNzLmV4cGFuZGVkXT1cIml0ZW0uZXhwYW5kZWRcIiAoY2xpY2spPVwiZXhwYW5kR3JvdXAoaXRlbSlcIj5cbiAgICAgICAgICA8Z2FudHQtaWNvbiBjbGFzcz1cImV4cGFuZC1pY29uXCIgW2ljb25OYW1lXT1cIml0ZW0uZXhwYW5kZWQgPyAnYW5nbGUtZG93bicgOiAnYW5nbGUtcmlnaHQnXCI+PC9nYW50dC1pY29uPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJncm91cFRlbXBsYXRlOyBlbHNlIGRlZmF1bHRcIj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJncm91cFRlbXBsYXRlXCJcbiAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiBpdGVtLm9yaWdpbiwgZ3JvdXA6IGl0ZW0ub3JpZ2luIH1cIlxuICAgICAgICAgICAgPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0PlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncm91cC10aXRsZVwiPnt7IGl0ZW0udGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cIiFpdGVtLml0ZW1zXCJcbiAgICAgICAgKGNsaWNrKT1cIml0ZW1DbGljay5lbWl0KHsgZXZlbnQ6ICRldmVudCwgc2VsZWN0ZWRWYWx1ZTogaXRlbS5vcmlnaW4gfSlcIlxuICAgICAgICBjZGtEcmFnXG4gICAgICAgIFtjZGtEcmFnRGF0YV09XCJpdGVtXCJcbiAgICAgICAgW2Nka0RyYWdEaXNhYmxlZF09XCIoZHJhZ2dhYmxlICYmIGl0ZW0uaXRlbURyYWdnYWJsZSA9PT0gZmFsc2UpIHx8ICFkcmFnZ2FibGVcIlxuICAgICAgICAoY2RrRHJhZ1N0YXJ0ZWQpPVwib25JdGVtRHJhZ1N0YXJ0ZWQoJGV2ZW50KVwiXG4gICAgICAgIChjZGtEcmFnRW5kZWQpPVwib25JdGVtRHJhZ0VuZGVkKCRldmVudClcIlxuICAgICAgICAoY2RrRHJhZ01vdmVkKT1cImVtaXRJdGVtRHJhZ01vdmVkKCRldmVudClcIlxuICAgICAgICBjbGFzcz1cImdhbnR0LXRhYmxlLWl0ZW1cIlxuICAgICAgICBbY2xhc3MuZ2FudHQtdGFibGUtaXRlbS13aXRoLWdyb3VwXT1cImhhc0dyb3VwXCJcbiAgICAgICAgW2NsYXNzLmdhbnR0LXRhYmxlLWl0ZW0tZmlyc3QtbGV2ZWwtZ3JvdXBdPVwiaXRlbS5sZXZlbCA9PT0gMCAmJiAoaXRlbS50eXBlIHwgaXNHYW50dFJhbmdlSXRlbSlcIlxuICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cImdhbnR0LnN0eWxlcy5saW5lSGVpZ2h0XCJcbiAgICAgICAgW3N0eWxlLmxpbmVIZWlnaHQucHhdPVwiZ2FudHQuc3R5bGVzLmxpbmVIZWlnaHRcIlxuICAgICAgICBbY2xhc3MuZ2FudHQtdGFibGUtaXRlbS1hY3RpdmVdPVwiZ2FudHRVcHBlci5pc1NlbGVjdGVkKGl0ZW0uaWQpXCJcbiAgICAgID5cbiAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwicm93QmVmb3JlVGVtcGxhdGVcIlxuICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogaXRlbS5vcmlnaW4sIGl0ZW06IGl0ZW0ub3JpZ2luIH1cIlxuICAgICAgICA+PC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZ2FudHQtdGFibGUtY29sdW1uXCIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBjb2x1bW5zOyBsZXQgZmlyc3QgPSBmaXJzdFwiIFtzdHlsZS53aWR0aF09XCJjb2x1bW4uY29sdW1uV2lkdGhcIj5cbiAgICAgICAgICA8IS0tIGRyYWcgaWNvbiAtLT5cbiAgICAgICAgICA8Z2FudHQtaWNvblxuICAgICAgICAgICAgKm5nSWY9XCJmaXJzdCAmJiBkcmFnZ2FibGVcIlxuICAgICAgICAgICAgY2xhc3M9XCJnYW50dC1kcmFnLWhhbmRsZVwiXG4gICAgICAgICAgICBpY29uTmFtZT1cImRyYWdcIlxuICAgICAgICAgICAgY2RrRHJhZ0hhbmRsZVxuICAgICAgICAgICAgW2Nka0RyYWdIYW5kbGVEaXNhYmxlZF09XCIoZHJhZ2dhYmxlICYmIGl0ZW0uaXRlbURyYWdnYWJsZSA9PT0gZmFsc2UpIHx8ICFkcmFnZ2FibGVcIlxuICAgICAgICAgID48L2dhbnR0LWljb24+XG4gICAgICAgICAgPCEtLSBleHBhbmQgaWNvbiAtLT5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAqbmdJZj1cImNvbHVtbj8uc2hvd0V4cGFuZEljb24gfHwgKCFoYXNFeHBhbmRJY29uICYmIGZpcnN0KVwiXG4gICAgICAgICAgICBjbGFzcz1cImdhbnR0LWV4cGFuZC1pY29uXCJcbiAgICAgICAgICAgIFtzdHlsZS5tYXJnaW5MZWZ0LnB4XT1cIml0ZW0ubGV2ZWwgKiAyMFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0ubGV2ZWwgPCBnYW50dC5tYXhMZXZlbCAtIDEgJiYgaXRlbS5leHBhbmRhYmxlXCI+XG4gICAgICAgICAgICAgIDxnYW50dC1pY29uXG4gICAgICAgICAgICAgICAgKm5nSWY9XCIhaXRlbS5sb2FkaW5nXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImV4cGFuZC1pY29uXCJcbiAgICAgICAgICAgICAgICBbaWNvbk5hbWVdPVwiaXRlbS5leHBhbmRlZCA/ICdhbmdsZS1kb3duJyA6ICdhbmdsZS1yaWdodCdcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJleHBhbmRDaGlsZHJlbigkZXZlbnQsIGl0ZW0pXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8L2dhbnR0LWljb24+XG4gICAgICAgICAgICAgIDxnYW50dC1pY29uICpuZ0lmPVwiaXRlbS5sb2FkaW5nXCIgW2ljb25OYW1lXT1cIidsb2FkaW5nJ1wiPjwvZ2FudHQtaWNvbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwhLS0gY29sdW1uIGNvbnRlbnQgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImdhbnR0LXRhYmxlLWNvbHVtbi1jb250ZW50XCI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sdW1uLnRlbXBsYXRlUmVmXCJcbiAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiBpdGVtLm9yaWdpbiwgaXRlbTogaXRlbS5vcmlnaW4gfVwiXG4gICAgICAgICAgICA+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInJvd0FmdGVyVGVtcGxhdGVcIlxuICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogaXRlbS5vcmlnaW4sIGl0ZW06IGl0ZW0ub3JpZ2luIH1cIlxuICAgICAgICA+PC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuIl19
|