mmhglobal-dynamicform 2.28.6 → 2.30.0

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.
Files changed (36) hide show
  1. package/README.md +414 -1019
  2. package/esm2020/lib/components/datalistingfieldbase.component.mjs +2 -2
  3. package/esm2020/lib/embed-components/processing-record-loader/processing-record-loader.component.mjs +2 -2
  4. package/esm2020/lib/kscrollview/kscrollview.component.mjs +2 -2
  5. package/esm2020/lib/mmhglobal-dynamicform.module.mjs +26 -8
  6. package/esm2020/lib/services/main.service.mjs +19 -4
  7. package/esm2020/lib/services/zcomponent.debug.service.mjs +3 -3
  8. package/esm2020/lib/services/zcomponent.service.mjs +2 -2
  9. package/esm2020/lib/sfdatetimepicker/sfdatetimepicker.component.mjs +51 -0
  10. package/esm2020/lib/uiheader/uiheader.component.mjs +2 -2
  11. package/esm2020/lib/zbuttons/zbuttons.component.mjs +17 -4
  12. package/esm2020/lib/zdatetime/dateKendoFormatParser.pipe.mjs +2 -1
  13. package/esm2020/lib/zdatetime/zdatetime.component.mjs +11 -7
  14. package/esm2020/lib/zform/zform.component.mjs +3 -3
  15. package/esm2020/lib/zganttchart/zganttchart.component.mjs +160 -0
  16. package/esm2020/lib/zinput-container/zinput-container.component.mjs +22 -20
  17. package/esm2020/lib/zinput-container/zinput-container.pipe.mjs +4 -3
  18. package/esm2020/lib/zloop/zloop.component.mjs +2 -2
  19. package/esm2020/lib/ztreelist/ztreelist.component.mjs +3 -3
  20. package/esm2020/lib/zudf/zudf.component.mjs +2 -2
  21. package/esm2020/lib/zupload/zupload.component.mjs +6 -7
  22. package/esm2020/lib/zworkflowbuttons/zworkflowbuttons.component.mjs +4 -3
  23. package/esm2020/public-api.mjs +3 -1
  24. package/fesm2015/mmhglobal-dynamicform.mjs +304 -59
  25. package/fesm2015/mmhglobal-dynamicform.mjs.map +1 -1
  26. package/fesm2020/mmhglobal-dynamicform.mjs +305 -59
  27. package/fesm2020/mmhglobal-dynamicform.mjs.map +1 -1
  28. package/lib/mmhglobal-dynamicform.module.d.ts +43 -39
  29. package/lib/services/zcomponent.debug.service.d.ts +1 -1
  30. package/lib/sfdatetimepicker/sfdatetimepicker.component.d.ts +23 -0
  31. package/lib/zdatetime/zdatetime.component.d.ts +2 -1
  32. package/lib/zganttchart/zganttchart.component.d.ts +40 -0
  33. package/lib/zinput-container/zinput-container.component.d.ts +1 -0
  34. package/lib/zinput-container/zinput-container.pipe.d.ts +1 -0
  35. package/package.json +1 -1
  36. package/public-api.d.ts +2 -0
@@ -0,0 +1,160 @@
1
+ /********** Angular **********/
2
+ import { Component } from "@angular/core";
3
+ /********** Component & Service **********/
4
+ import { DataListingFieldBase } from "../components/datalistingfieldbase.component";
5
+ import { ZComponentHelper } from "mmhglobal-zcore";
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "../services/zcomponent.service";
8
+ import * as i2 from "@progress/kendo-angular-gantt";
9
+ import * as i3 from "@angular/common";
10
+ export class ZganttchartComponent extends DataListingFieldBase {
11
+ constructor(componentService) {
12
+ super(componentService);
13
+ this.componentService = componentService;
14
+ this.activeView = "day";
15
+ this.views = ["day", "week", "month", "year"];
16
+ this.collapsible = false;
17
+ this.collapsed = false;
18
+ this.timelineSize = '70%';
19
+ this.columns = []; // Initialize columns array
20
+ this.selectable = false;
21
+ this.totalCount = 0;
22
+ this.selectionState = new Set();
23
+ this.isSelected = (dataItem) => {
24
+ return this.selectionState.has(dataItem[this.data.UniqueKey ?? "Id"]);
25
+ };
26
+ }
27
+ ngOnInit() {
28
+ this.collapsible = this.data.AllowCollapse ?? false;
29
+ this.collapsed = this.data.DefaultCollapse ?? false;
30
+ this.timelineSize = this.data.TimelineSize ?? '70%';
31
+ this.selectable = this.data.Selectable ?? false;
32
+ this.initViews();
33
+ this.setActiveView();
34
+ this.generateGridColumns();
35
+ ZComponentHelper.registerComponent(this);
36
+ }
37
+ ngAfterViewInit() {
38
+ this.componentService.decrementComponentCounterForField(this.data);
39
+ }
40
+ ngOnDestroy() {
41
+ }
42
+ initViews() {
43
+ if (this.data.TimelineViewType && Array.isArray(this.data.TimelineViewType)) {
44
+ this.views = this.data.TimelineViewType
45
+ .map(view => view.toLowerCase())
46
+ .filter(view => this.isValidTimelineView(view));
47
+ }
48
+ }
49
+ setActiveView() {
50
+ if (this.data.TimelimeDefault) {
51
+ const defaultView = this.data.TimelimeDefault.toLowerCase();
52
+ if (this.isValidTimelineView(defaultView)) {
53
+ this.activeView = defaultView;
54
+ }
55
+ }
56
+ }
57
+ isValidTimelineView(view) {
58
+ return ['day', 'week', 'month', 'year'].includes(view);
59
+ }
60
+ generateGridColumns() {
61
+ if (!Array.isArray(this.data.ColumnFields) || this.data.ColumnFields.length === 0) {
62
+ console.warn(`Invalid/Empty gantt chart column fields: '${this.data.Name}'`);
63
+ return;
64
+ }
65
+ this.columns = this.data.ColumnFields.map(field => ({
66
+ name: field.Name,
67
+ field: field.Value,
68
+ title: field.Name,
69
+ width: field.width || 80,
70
+ format: field.Format
71
+ }));
72
+ }
73
+ setData(ganttData) {
74
+ if (ganttData) {
75
+ this.ganttData = ganttData.map(task => ({
76
+ ...task,
77
+ start: this.ensureDate(task.start),
78
+ end: this.ensureDate(task.end)
79
+ })).filter(task => task.start && task.end); // Only include tasks with valid start and end dates
80
+ if (this.data.Max) {
81
+ this.ganttData = this.ganttData.slice(0, this.data.Max);
82
+ }
83
+ this.updateValueVariable();
84
+ this.totalCount = this.ganttData.length;
85
+ }
86
+ else {
87
+ console.warn('No data provided to setData; received a null or undefined parameter.');
88
+ }
89
+ }
90
+ updateValueVariable() {
91
+ // Extract and trim the value from this.data.value if it exists
92
+ const fieldName = this.data.Value.split('.').pop(); // Gets the last part after the last dot
93
+ if (!fieldName) {
94
+ console.warn(`Gantt Chart ${this.data.Name} Value could not be determined.`);
95
+ return;
96
+ }
97
+ // Determine the target object
98
+ if (this.data.Value.includes('group.') && this.group) {
99
+ this.group[fieldName] = this.ganttData;
100
+ }
101
+ else {
102
+ if (this.hasOwnProperty(fieldName)) {
103
+ this[fieldName] = this.ganttData;
104
+ }
105
+ }
106
+ }
107
+ ensureDate(date) {
108
+ // Check if the date is already a Date object
109
+ if (date instanceof Date) {
110
+ return date;
111
+ }
112
+ // If the date is a string, convert it to a Date object
113
+ const parsedDate = new Date(date);
114
+ if (!isNaN(parsedDate.getTime())) {
115
+ return parsedDate;
116
+ }
117
+ else {
118
+ // Log a warning if the date string is invalid and return a default date or null
119
+ // console.warn(`Invalid date format: ${date}`);
120
+ return null; // or return null if you prefer to handle invalid dates differently
121
+ }
122
+ }
123
+ get selectedKeys() {
124
+ return Array.from(this.selectionState);
125
+ }
126
+ toggleSelection({ dataItem, sender, originalEvent, }) {
127
+ // Prevents context menu opening
128
+ originalEvent.preventDefault();
129
+ const uniqueKey = this.data.UniqueKey ?? "Id";
130
+ // For future toggling multi select
131
+ // if (this.isSelected(dataItem)) {
132
+ // this.selectionState.delete(dataItem[uniqueKey]);
133
+ // }
134
+ // else {
135
+ // this.selectionState.add(dataItem[uniqueKey]);
136
+ // }
137
+ this.selectionState = new Set;
138
+ this.selectionState.add(dataItem[uniqueKey]);
139
+ // Manually trigger the Gantt to re-evaluate the isSelected callback for each task
140
+ sender.updateView();
141
+ if (this.data.OnItemClick) {
142
+ const func = ZComponentHelper.getGroupEvalValue.call(this, this.data.OnItemClick);
143
+ if (typeof func === 'function') {
144
+ const callFunc = func.bind(this.group.ctrlScope);
145
+ callFunc(dataItem);
146
+ }
147
+ return;
148
+ }
149
+ }
150
+ clearSelection() {
151
+ this.selectionState = new Set;
152
+ }
153
+ }
154
+ ZganttchartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ZganttchartComponent, deps: [{ token: i1.ZComponentService }], target: i0.ɵɵFactoryTarget.Component });
155
+ ZganttchartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.3", type: ZganttchartComponent, selector: "app-zganttchart", usesInheritance: true, ngImport: i0, template: "<kendo-gantt [style.height.px]=\"500\"\n [data]=\"ganttData\"\n kendoGanttExpandable\n [initiallyExpanded]=\"true\"\n [toolbarSettings]=\"{ position: 'both', addTaskTool: 'none' }\"\n [activeView]=\"activeView\"\n [sortable]=\"true\"\n [selectable]=\"selectable\"\n [isSelected]=\"isSelected\"\n (cellClick)=\"toggleSelection($event)\"\n (taskClick)=\"toggleSelection($event)\"\n [timelinePaneOptions]=\"{ collapsed: collapsed,\n collapsible: collapsible,\n size: timelineSize\n }\">\n <kendo-gantt-column *ngFor=\"let col of columns;\"\n [field]=\"col.field\"\n [title]=\"col.title\"\n [width]=\"col.width\"\n [format]=\"col.format\">\n </kendo-gantt-column>\n <ng-template kendoGanttToolbarTemplate\n position=\"both\"\n let-position=\"position\">\n <div *ngIf=\"position === 'top'\" class=\"toolbar-top\">\n <span>{{data.Title}}</span>\n <kendo-gantt-view-selector [views]=\"views\"\n [(activeView)]=\"activeView\"></kendo-gantt-view-selector>\n </div>\n <div *ngIf=\"position === 'bottom'\" class=\"toolbar-bottom\">\n <span>Total {{totalCount}} records</span>\n </div>\n </ng-template>\n <kendo-gantt-timeline-day-view></kendo-gantt-timeline-day-view>\n <kendo-gantt-timeline-week-view></kendo-gantt-timeline-week-view>\n <kendo-gantt-timeline-month-view></kendo-gantt-timeline-month-view>\n <kendo-gantt-timeline-year-view></kendo-gantt-timeline-year-view>\n</kendo-gantt>\n", styles: ["label.k-radio-label{display:inline-block;margin-right:10px}.toolbar-top{display:flex;width:100%;justify-content:space-between;align-items:center}.toolbar-bottom{display:flex;width:100%;align-items:end}\n"], components: [{ type: i2.GanttComponent, selector: "kendo-gantt", inputs: ["aria-roledescription", "role", "taskModelFields", "dependencyModelFields", "activeView", "data", "isSelected", "validateNewDependency", "selectable", "toolbarSettings", "fetchChildren", "hasChildren", "dependencies", "sortable", "sort", "filterable", "filter", "workDayStart", "workDayEnd", "workWeekStart", "workWeekEnd", "navigable", "timelinePaneOptions", "treeListPaneOptions", "taskClass", "rowClass", "isExpanded", "columnsAutoSize", "columnMenu", "columnsReorderable", "columnsResizable", "dragScrollSettings"], outputs: ["selectionChange", "rowExpand", "taskDblClick", "cellDblClick", "cellClose", "taskDelete", "rowCollapse", "remove", "cancel", "save", "taskAdd", "dependencyAdd", "sortChange", "filterChange", "dataStateChange", "treeListPaneCollapsedChange", "timelinePaneCollapsedChange", "timelinePaneSizeChange", "activeViewChange", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "cellClick", "taskClick"], exportAs: ["kendoGantt"] }, { type: i2.GanttColumnComponent, selector: "kendo-gantt-column", inputs: ["format", "filter", "filterable", "editor", "editable", "locked", "lockable", "hidden", "media", "style", "headerStyle", "footerStyle", "class", "headerClass", "footerClass"] }, { type: i2.ViewSelectorComponent, selector: "kendo-gantt-view-selector", inputs: ["views", "activeView"], outputs: ["activeViewChange"] }, { type: i2.TimelineDayViewComponent, selector: "kendo-gantt-timeline-day-view" }, { type: i2.TimelineWeekViewComponent, selector: "kendo-gantt-timeline-week-view" }, { type: i2.TimelineMonthViewComponent, selector: "kendo-gantt-timeline-month-view" }, { type: i2.TimelineYearViewComponent, selector: "kendo-gantt-timeline-year-view" }], directives: [{ type: i2.GanttExpandableDirective, selector: "[kendoGanttExpandable]", inputs: ["expandBy"], exportAs: ["kendoGanttExpandable"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.ToolbarTemplateDirective, selector: "[kendoGanttToolbarTemplate]", inputs: ["position"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ZganttchartComponent, decorators: [{
157
+ type: Component,
158
+ args: [{ selector: 'app-zganttchart', template: "<kendo-gantt [style.height.px]=\"500\"\n [data]=\"ganttData\"\n kendoGanttExpandable\n [initiallyExpanded]=\"true\"\n [toolbarSettings]=\"{ position: 'both', addTaskTool: 'none' }\"\n [activeView]=\"activeView\"\n [sortable]=\"true\"\n [selectable]=\"selectable\"\n [isSelected]=\"isSelected\"\n (cellClick)=\"toggleSelection($event)\"\n (taskClick)=\"toggleSelection($event)\"\n [timelinePaneOptions]=\"{ collapsed: collapsed,\n collapsible: collapsible,\n size: timelineSize\n }\">\n <kendo-gantt-column *ngFor=\"let col of columns;\"\n [field]=\"col.field\"\n [title]=\"col.title\"\n [width]=\"col.width\"\n [format]=\"col.format\">\n </kendo-gantt-column>\n <ng-template kendoGanttToolbarTemplate\n position=\"both\"\n let-position=\"position\">\n <div *ngIf=\"position === 'top'\" class=\"toolbar-top\">\n <span>{{data.Title}}</span>\n <kendo-gantt-view-selector [views]=\"views\"\n [(activeView)]=\"activeView\"></kendo-gantt-view-selector>\n </div>\n <div *ngIf=\"position === 'bottom'\" class=\"toolbar-bottom\">\n <span>Total {{totalCount}} records</span>\n </div>\n </ng-template>\n <kendo-gantt-timeline-day-view></kendo-gantt-timeline-day-view>\n <kendo-gantt-timeline-week-view></kendo-gantt-timeline-week-view>\n <kendo-gantt-timeline-month-view></kendo-gantt-timeline-month-view>\n <kendo-gantt-timeline-year-view></kendo-gantt-timeline-year-view>\n</kendo-gantt>\n", styles: ["label.k-radio-label{display:inline-block;margin-right:10px}.toolbar-top{display:flex;width:100%;justify-content:space-between;align-items:center}.toolbar-bottom{display:flex;width:100%;align-items:end}\n"] }]
159
+ }], ctorParameters: function () { return [{ type: i1.ZComponentService }]; } });
160
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemdhbnR0Y2hhcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbW1oZ2xvYmFsLWR5bmFtaWNmb3JtL3NyYy9saWIvemdhbnR0Y2hhcnQvemdhbnR0Y2hhcnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbW1oZ2xvYmFsLWR5bmFtaWNmb3JtL3NyYy9saWIvemdhbnR0Y2hhcnQvemdhbnR0Y2hhcnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0JBQStCO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBTzdELDJDQUEyQztBQUMzQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUVwRixPQUFPLEVBRUwsZ0JBQWdCLEVBQ2pCLE1BQU0saUJBQWlCLENBQUM7Ozs7O0FBT3pCLE1BQU0sT0FBTyxvQkFBcUIsU0FBUSxvQkFBb0I7SUFVNUQsWUFDUyxnQkFBbUM7UUFFMUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFGakIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFtQjtRQVZyQyxlQUFVLEdBQXFCLEtBQUssQ0FBQztRQUNyQyxVQUFLLEdBQXVCLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDN0QsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFDcEIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixZQUFPLEdBQVUsRUFBRSxDQUFDLENBQUMsMkJBQTJCO1FBQ2hELGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsZUFBVSxHQUFXLENBQUMsQ0FBQztRQStIdkIsbUJBQWMsR0FBYSxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRXJDLGVBQVUsR0FBRyxDQUFDLFFBQWEsRUFBVyxF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QUNuQyxxREFBcUQ7UUFDckQsSUFBSTtRQUNKLFNBQVM7UUFDVCxrREFBa0Q7UUFDbEQsSUFBSTtRQUVKLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUM7UUFDOUIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFFN0Msa0ZBQWtGO1FBQ2xGLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUVwQixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3pCLE1BQU0sSUFBSSxHQUFHLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNsRixJQUFJLE9BQU8sSUFBSSxLQUFLLFVBQVUsRUFBRTtnQkFDOUIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUNqRCxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDcEI7WUFDRCxPQUFPO1NBQ1I7SUFDSCxDQUFDO0lBRU0sY0FBYztRQUNuQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksR0FBRyxDQUFDO0lBQ2hDLENBQUM7O2lIQWpMVSxvQkFBb0I7cUdBQXBCLG9CQUFvQiw4RUNyQmpDLDB3REFzQ0E7MkZEakJhLG9CQUFvQjtrQkFMaEMsU0FBUzsrQkFDRSxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKiBBbmd1bGFyICoqKioqKioqKiovXG5pbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgT25EZXN0cm95IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcblxuLyoqKioqKioqKiogSW9uaWMgKioqKioqKioqKi9cblxuLyoqKioqKioqKiogUGx1Z2luICoqKioqKioqKiovXG5pbXBvcnQgeyBDZWxsQ2xpY2tFdmVudCwgVGFza0NsaWNrRXZlbnQsIFRpbWVsaW5lVmlld1R5cGUgfSBmcm9tIFwiQHByb2dyZXNzL2tlbmRvLWFuZ3VsYXItZ2FudHRcIjtcblxuLyoqKioqKioqKiogQ29tcG9uZW50ICYgU2VydmljZSAqKioqKioqKioqL1xuaW1wb3J0IHsgRGF0YUxpc3RpbmdGaWVsZEJhc2UgfSBmcm9tIFwiLi4vY29tcG9uZW50cy9kYXRhbGlzdGluZ2ZpZWxkYmFzZS5jb21wb25lbnRcIjtcbmltcG9ydCB7IFpDb21wb25lbnRTZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL3pjb21wb25lbnQuc2VydmljZVwiO1xuaW1wb3J0IHtcbiAgWkNvbXBvbmVudCxcbiAgWkNvbXBvbmVudEhlbHBlclxufSBmcm9tIFwibW1oZ2xvYmFsLXpjb3JlXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC16Z2FudHRjaGFydCcsXG4gIHRlbXBsYXRlVXJsOiAnLi96Z2FudHRjaGFydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3pnYW50dGNoYXJ0LmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFpnYW50dGNoYXJ0Q29tcG9uZW50IGV4dGVuZHMgRGF0YUxpc3RpbmdGaWVsZEJhc2UgaW1wbGVtZW50cyBaQ29tcG9uZW50LCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIHB1YmxpYyBhY3RpdmVWaWV3OiBUaW1lbGluZVZpZXdUeXBlID0gXCJkYXlcIjtcbiAgcHVibGljIHZpZXdzOiBUaW1lbGluZVZpZXdUeXBlW10gPSBbXCJkYXlcIiwgXCJ3ZWVrXCIsIFwibW9udGhcIiwgXCJ5ZWFyXCJdO1xuICBwdWJsaWMgY29sbGFwc2libGUgPSBmYWxzZTtcbiAgcHVibGljIGNvbGxhcHNlZCA9IGZhbHNlO1xuICBwdWJsaWMgdGltZWxpbmVTaXplID0gJzcwJSc7XG4gIHB1YmxpYyBjb2x1bW5zOiBhbnlbXSA9IFtdOyAvLyBJbml0aWFsaXplIGNvbHVtbnMgYXJyYXlcbiAgcHVibGljIHNlbGVjdGFibGUgPSBmYWxzZTtcbiAgcHVibGljIHRvdGFsQ291bnQ6IG51bWJlciA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGNvbXBvbmVudFNlcnZpY2U6IFpDb21wb25lbnRTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKGNvbXBvbmVudFNlcnZpY2UpO1xuICB9XG5cbiAgcHVibGljIGdhbnR0RGF0YTogYW55O1xuXG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5jb2xsYXBzaWJsZSA9IHRoaXMuZGF0YS5BbGxvd0NvbGxhcHNlID8/IGZhbHNlO1xuICAgIHRoaXMuY29sbGFwc2VkID0gdGhpcy5kYXRhLkRlZmF1bHRDb2xsYXBzZSA/PyBmYWxzZTtcbiAgICB0aGlzLnRpbWVsaW5lU2l6ZSA9IHRoaXMuZGF0YS5UaW1lbGluZVNpemUgPz8gJzcwJSc7XG4gICAgdGhpcy5zZWxlY3RhYmxlID0gdGhpcy5kYXRhLlNlbGVjdGFibGUgPz8gZmFsc2U7XG4gICAgdGhpcy5pbml0Vmlld3MoKTtcbiAgICB0aGlzLnNldEFjdGl2ZVZpZXcoKTtcbiAgICB0aGlzLmdlbmVyYXRlR3JpZENvbHVtbnMoKTtcbiAgICBaQ29tcG9uZW50SGVscGVyLnJlZ2lzdGVyQ29tcG9uZW50KHRoaXMpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuY29tcG9uZW50U2VydmljZS5kZWNyZW1lbnRDb21wb25lbnRDb3VudGVyRm9yRmllbGQodGhpcy5kYXRhKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0Vmlld3MoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGF0YS5UaW1lbGluZVZpZXdUeXBlICYmIEFycmF5LmlzQXJyYXkodGhpcy5kYXRhLlRpbWVsaW5lVmlld1R5cGUpKSB7XG4gICAgICB0aGlzLnZpZXdzID0gdGhpcy5kYXRhLlRpbWVsaW5lVmlld1R5cGVcbiAgICAgICAgLm1hcCh2aWV3ID0+IHZpZXcudG9Mb3dlckNhc2UoKSlcbiAgICAgICAgLmZpbHRlcih2aWV3ID0+IHRoaXMuaXNWYWxpZFRpbWVsaW5lVmlldyh2aWV3KSkgYXMgVGltZWxpbmVWaWV3VHlwZVtdO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0QWN0aXZlVmlldygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kYXRhLlRpbWVsaW1lRGVmYXVsdCkge1xuICAgICAgY29uc3QgZGVmYXVsdFZpZXcgPSB0aGlzLmRhdGEuVGltZWxpbWVEZWZhdWx0LnRvTG93ZXJDYXNlKCk7XG4gICAgICBpZiAodGhpcy5pc1ZhbGlkVGltZWxpbmVWaWV3KGRlZmF1bHRWaWV3KSkge1xuICAgICAgICB0aGlzLmFjdGl2ZVZpZXcgPSBkZWZhdWx0VmlldyBhcyBUaW1lbGluZVZpZXdUeXBlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNWYWxpZFRpbWVsaW5lVmlldyh2aWV3OiBzdHJpbmcpOiB2aWV3IGlzIFRpbWVsaW5lVmlld1R5cGUge1xuICAgIHJldHVybiBbJ2RheScsICd3ZWVrJywgJ21vbnRoJywgJ3llYXInXS5pbmNsdWRlcyh2aWV3KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2VuZXJhdGVHcmlkQ29sdW1ucygpOiB2b2lkIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodGhpcy5kYXRhLkNvbHVtbkZpZWxkcykgfHwgdGhpcy5kYXRhLkNvbHVtbkZpZWxkcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUud2FybihgSW52YWxpZC9FbXB0eSBnYW50dCBjaGFydCBjb2x1bW4gZmllbGRzOiAnJHt0aGlzLmRhdGEuTmFtZX0nYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jb2x1bW5zID0gdGhpcy5kYXRhLkNvbHVtbkZpZWxkcy5tYXAoZmllbGQgPT4gKHtcbiAgICAgIG5hbWU6IGZpZWxkLk5hbWUsXG4gICAgICBmaWVsZDogZmllbGQuVmFsdWUsXG4gICAgICB0aXRsZTogZmllbGQuTmFtZSxcbiAgICAgIHdpZHRoOiBmaWVsZC53aWR0aCB8fCA4MCxcbiAgICAgIGZvcm1hdDogZmllbGQuRm9ybWF0XG4gICAgfSkpO1xuICB9XG5cbiAgcHVibGljIHNldERhdGEoZ2FudHREYXRhOiBhbnlbXSk6IHZvaWQge1xuICAgIGlmIChnYW50dERhdGEpIHtcbiAgICAgIHRoaXMuZ2FudHREYXRhID0gZ2FudHREYXRhLm1hcCh0YXNrID0+ICh7XG4gICAgICAgIC4uLnRhc2ssXG4gICAgICAgIHN0YXJ0OiB0aGlzLmVuc3VyZURhdGUodGFzay5zdGFydCksXG4gICAgICAgIGVuZDogdGhpcy5lbnN1cmVEYXRlKHRhc2suZW5kKVxuICAgICAgfSkpLmZpbHRlcih0YXNrID0+IHRhc2suc3RhcnQgJiYgdGFzay5lbmQpOyAvLyBPbmx5IGluY2x1ZGUgdGFza3Mgd2l0aCB2YWxpZCBzdGFydCBhbmQgZW5kIGRhdGVzXG5cbiAgICAgIGlmICh0aGlzLmRhdGEuTWF4KSB7XG4gICAgICAgIHRoaXMuZ2FudHREYXRhID0gdGhpcy5nYW50dERhdGEuc2xpY2UoMCwgdGhpcy5kYXRhLk1heCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMudXBkYXRlVmFsdWVWYXJpYWJsZSgpO1xuXG4gICAgICB0aGlzLnRvdGFsQ291bnQgPSB0aGlzLmdhbnR0RGF0YS5sZW5ndGg7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY29uc29sZS53YXJuKCdObyBkYXRhIHByb3ZpZGVkIHRvIHNldERhdGE7IHJlY2VpdmVkIGEgbnVsbCBvciB1bmRlZmluZWQgcGFyYW1ldGVyLicpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlVmFsdWVWYXJpYWJsZSgpIHtcbiAgICAvLyBFeHRyYWN0IGFuZCB0cmltIHRoZSB2YWx1ZSBmcm9tIHRoaXMuZGF0YS52YWx1ZSBpZiBpdCBleGlzdHNcbiAgICBjb25zdCBmaWVsZE5hbWUgPSB0aGlzLmRhdGEuVmFsdWUuc3BsaXQoJy4nKS5wb3AoKTsgLy8gR2V0cyB0aGUgbGFzdCBwYXJ0IGFmdGVyIHRoZSBsYXN0IGRvdFxuXG4gICAgaWYgKCFmaWVsZE5hbWUpIHtcbiAgICAgIGNvbnNvbGUud2FybihgR2FudHQgQ2hhcnQgJHt0aGlzLmRhdGEuTmFtZX0gVmFsdWUgY291bGQgbm90IGJlIGRldGVybWluZWQuYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRGV0ZXJtaW5lIHRoZSB0YXJnZXQgb2JqZWN0IFxuICAgIGlmICh0aGlzLmRhdGEuVmFsdWUuaW5jbHVkZXMoJ2dyb3VwLicpICYmIHRoaXMuZ3JvdXApIHtcbiAgICAgIHRoaXMuZ3JvdXBbZmllbGROYW1lXSA9IHRoaXMuZ2FudHREYXRhO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkTmFtZSkpIHtcbiAgICAgICAgdGhpc1tmaWVsZE5hbWVdID0gdGhpcy5nYW50dERhdGE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBlbnN1cmVEYXRlKGRhdGU6IHN0cmluZyB8IERhdGUpOiBEYXRlIHwgbnVsbCB7XG4gICAgLy8gQ2hlY2sgaWYgdGhlIGRhdGUgaXMgYWxyZWFkeSBhIERhdGUgb2JqZWN0XG4gICAgaWYgKGRhdGUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICByZXR1cm4gZGF0ZTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgZGF0ZSBpcyBhIHN0cmluZywgY29udmVydCBpdCB0byBhIERhdGUgb2JqZWN0XG4gICAgY29uc3QgcGFyc2VkRGF0ZSA9IG5ldyBEYXRlKGRhdGUpO1xuICAgIGlmICghaXNOYU4ocGFyc2VkRGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICByZXR1cm4gcGFyc2VkRGF0ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTG9nIGEgd2FybmluZyBpZiB0aGUgZGF0ZSBzdHJpbmcgaXMgaW52YWxpZCBhbmQgcmV0dXJuIGEgZGVmYXVsdCBkYXRlIG9yIG51bGxcbiAgICAgIC8vIGNvbnNvbGUud2FybihgSW52YWxpZCBkYXRlIGZvcm1hdDogJHtkYXRlfWApO1xuICAgICAgcmV0dXJuIG51bGw7IC8vIG9yIHJldHVybiBudWxsIGlmIHlvdSBwcmVmZXIgdG8gaGFuZGxlIGludmFsaWQgZGF0ZXMgZGlmZmVyZW50bHlcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNlbGVjdGVkS2V5cygpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5zZWxlY3Rpb25TdGF0ZSk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0aW9uU3RhdGU6IFNldDxhbnk+ID0gbmV3IFNldCgpO1xuXG4gIHB1YmxpYyBpc1NlbGVjdGVkID0gKGRhdGFJdGVtOiBhbnkpOiBib29sZWFuID0+IHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb25TdGF0ZS5oYXMoZGF0YUl0ZW1bdGhpcy5kYXRhLlVuaXF1ZUtleSA/PyBcIklkXCJdKTtcbiAgfTtcblxuICBwdWJsaWMgdG9nZ2xlU2VsZWN0aW9uKHtcbiAgICBkYXRhSXRlbSxcbiAgICBzZW5kZXIsXG4gICAgb3JpZ2luYWxFdmVudCxcbiAgfTogQ2VsbENsaWNrRXZlbnQgfCBUYXNrQ2xpY2tFdmVudCk6IHZvaWQge1xuICAgIC8vIFByZXZlbnRzIGNvbnRleHQgbWVudSBvcGVuaW5nXG4gICAgb3JpZ2luYWxFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgdW5pcXVlS2V5ID0gdGhpcy5kYXRhLlVuaXF1ZUtleSA/PyBcIklkXCI7XG5cbiAgICAvLyBGb3IgZnV0dXJlIHRvZ2dsaW5nIG11bHRpIHNlbGVjdCBcbiAgICAvLyBpZiAodGhpcy5pc1NlbGVjdGVkKGRhdGFJdGVtKSkge1xuICAgIC8vICAgdGhpcy5zZWxlY3Rpb25TdGF0ZS5kZWxldGUoZGF0YUl0ZW1bdW5pcXVlS2V5XSk7XG4gICAgLy8gfVxuICAgIC8vIGVsc2Uge1xuICAgIC8vICAgdGhpcy5zZWxlY3Rpb25TdGF0ZS5hZGQoZGF0YUl0ZW1bdW5pcXVlS2V5XSk7XG4gICAgLy8gfVxuXG4gICAgdGhpcy5zZWxlY3Rpb25TdGF0ZSA9IG5ldyBTZXQ7XG4gICAgdGhpcy5zZWxlY3Rpb25TdGF0ZS5hZGQoZGF0YUl0ZW1bdW5pcXVlS2V5XSk7XG5cbiAgICAvLyBNYW51YWxseSB0cmlnZ2VyIHRoZSBHYW50dCB0byByZS1ldmFsdWF0ZSB0aGUgaXNTZWxlY3RlZCBjYWxsYmFjayBmb3IgZWFjaCB0YXNrXG4gICAgc2VuZGVyLnVwZGF0ZVZpZXcoKTtcblxuICAgIGlmICh0aGlzLmRhdGEuT25JdGVtQ2xpY2spIHtcbiAgICAgIGNvbnN0IGZ1bmMgPSBaQ29tcG9uZW50SGVscGVyLmdldEdyb3VwRXZhbFZhbHVlLmNhbGwodGhpcywgdGhpcy5kYXRhLk9uSXRlbUNsaWNrKTtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjb25zdCBjYWxsRnVuYyA9IGZ1bmMuYmluZCh0aGlzLmdyb3VwLmN0cmxTY29wZSk7XG4gICAgICAgIGNhbGxGdW5jKGRhdGFJdGVtKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgY2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3Rpb25TdGF0ZSA9IG5ldyBTZXQ7XG4gIH1cbn1cbiIsIjxrZW5kby1nYW50dCBbc3R5bGUuaGVpZ2h0LnB4XT1cIjUwMFwiXG4gICAgICAgICAgICAgW2RhdGFdPVwiZ2FudHREYXRhXCJcbiAgICAgICAgICAgICBrZW5kb0dhbnR0RXhwYW5kYWJsZVxuICAgICAgICAgICAgIFtpbml0aWFsbHlFeHBhbmRlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICBbdG9vbGJhclNldHRpbmdzXT1cInsgcG9zaXRpb246ICdib3RoJywgYWRkVGFza1Rvb2w6ICdub25lJyB9XCJcbiAgICAgICAgICAgICBbYWN0aXZlVmlld109XCJhY3RpdmVWaWV3XCJcbiAgICAgICAgICAgICBbc29ydGFibGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgW3NlbGVjdGFibGVdPVwic2VsZWN0YWJsZVwiXG4gICAgICAgICAgICAgW2lzU2VsZWN0ZWRdPVwiaXNTZWxlY3RlZFwiXG4gICAgICAgICAgICAgKGNlbGxDbGljayk9XCJ0b2dnbGVTZWxlY3Rpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgKHRhc2tDbGljayk9XCJ0b2dnbGVTZWxlY3Rpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgW3RpbWVsaW5lUGFuZU9wdGlvbnNdPVwieyBjb2xsYXBzZWQ6IGNvbGxhcHNlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbGFwc2libGU6IGNvbGxhcHNpYmxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplOiB0aW1lbGluZVNpemVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIj5cbiAgPGtlbmRvLWdhbnR0LWNvbHVtbiAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnM7XCJcbiAgICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmZpZWxkXCJcbiAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiY29sLnRpdGxlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbd2lkdGhdPVwiY29sLndpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICBbZm9ybWF0XT1cImNvbC5mb3JtYXRcIj5cbiAgPC9rZW5kby1nYW50dC1jb2x1bW4+XG4gIDxuZy10ZW1wbGF0ZSBrZW5kb0dhbnR0VG9vbGJhclRlbXBsYXRlXG4gICAgICAgICAgICAgICBwb3NpdGlvbj1cImJvdGhcIlxuICAgICAgICAgICAgICAgbGV0LXBvc2l0aW9uPVwicG9zaXRpb25cIj5cbiAgICA8ZGl2ICpuZ0lmPVwicG9zaXRpb24gPT09ICd0b3AnXCIgY2xhc3M9XCJ0b29sYmFyLXRvcFwiPlxuICAgICAgPHNwYW4+e3tkYXRhLlRpdGxlfX08L3NwYW4+XG4gICAgICA8a2VuZG8tZ2FudHQtdmlldy1zZWxlY3RvciBbdmlld3NdPVwidmlld3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhhY3RpdmVWaWV3KV09XCJhY3RpdmVWaWV3XCI+PC9rZW5kby1nYW50dC12aWV3LXNlbGVjdG9yPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nSWY9XCJwb3NpdGlvbiA9PT0gJ2JvdHRvbSdcIiBjbGFzcz1cInRvb2xiYXItYm90dG9tXCI+XG4gICAgICA8c3Bhbj5Ub3RhbCB7e3RvdGFsQ291bnR9fSByZWNvcmRzPC9zcGFuPlxuICAgIDwvZGl2PlxuICA8L25nLXRlbXBsYXRlPlxuICA8a2VuZG8tZ2FudHQtdGltZWxpbmUtZGF5LXZpZXc+PC9rZW5kby1nYW50dC10aW1lbGluZS1kYXktdmlldz5cbiAgPGtlbmRvLWdhbnR0LXRpbWVsaW5lLXdlZWstdmlldz48L2tlbmRvLWdhbnR0LXRpbWVsaW5lLXdlZWstdmlldz5cbiAgPGtlbmRvLWdhbnR0LXRpbWVsaW5lLW1vbnRoLXZpZXc+PC9rZW5kby1nYW50dC10aW1lbGluZS1tb250aC12aWV3PlxuICA8a2VuZG8tZ2FudHQtdGltZWxpbmUteWVhci12aWV3Pjwva2VuZG8tZ2FudHQtdGltZWxpbmUteWVhci12aWV3PlxuPC9rZW5kby1nYW50dD5cbiJdfQ==