mmhglobal-dynamicform 1.2.3 → 1.3.2

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 (198) hide show
  1. package/README.md +14 -2
  2. package/esm2020/lib/directives/fieldelement.directive.mjs +16 -0
  3. package/esm2020/lib/directives/scrollbar.theme.directive.mjs +43 -0
  4. package/esm2020/lib/mmhglobal-dynamicform.module.mjs +464 -0
  5. package/esm2020/lib/services/main.service.mjs +752 -0
  6. package/esm2020/lib/services/zcomponent.debug.service.mjs +621 -0
  7. package/esm2020/lib/services/zcomponent.service.mjs +81 -0
  8. package/esm2020/lib/uiactionbutton/uiactionbutton.component.mjs +265 -0
  9. package/esm2020/lib/uiappmenucontent/uiappmenucontent.component.mjs +67 -0
  10. package/esm2020/lib/uicontent/uicontent.component.mjs +41 -0
  11. package/esm2020/lib/uiheader/uiheader.component.mjs +66 -0
  12. package/esm2020/lib/uimenubutton/uimenubutton.component.mjs +35 -0
  13. package/esm2020/lib/uimenucontent/uimenucontent.component.mjs +37 -0
  14. package/{esm2015/lib/uipage/uipage.component.js → esm2020/lib/uipage/uipage.component.mjs} +12 -13
  15. package/esm2020/lib/uivalidationmessage/uivalidationmessage.component.mjs +41 -0
  16. package/esm2020/lib/zbullet/zbullet.component.mjs +74 -0
  17. package/esm2020/lib/zbuttons/zbuttons.component.mjs +171 -0
  18. package/esm2020/lib/zcard/zcard.component.mjs +72 -0
  19. package/esm2020/lib/zchart/zchart.component.mjs +201 -0
  20. package/esm2020/lib/zcheckbox/zcheckbox.component.mjs +166 -0
  21. package/esm2020/lib/zchip/zchip.component.mjs +121 -0
  22. package/esm2020/lib/zcodeeditor/zcodeeditor.component.mjs +169 -0
  23. package/esm2020/lib/zcodeeditor/zcodeeditor.pipe.mjs +60 -0
  24. package/esm2020/lib/zdaterange/zdaterange.component.mjs +70 -0
  25. package/esm2020/lib/zdatetime/dateParser.pipe.mjs +30 -0
  26. package/esm2020/lib/zdatetime/zdatetime.component.mjs +285 -0
  27. package/esm2020/lib/zdiv/zdiv.component.mjs +50 -0
  28. package/esm2020/lib/zdiv/zdiv.pipe.mjs +31 -0
  29. package/esm2020/lib/zform/zform.component.mjs +147 -0
  30. package/esm2020/lib/zformcontrol/zformcontrol.component.mjs +49 -0
  31. package/esm2020/lib/zgauge/zgauge.component.mjs +148 -0
  32. package/esm2020/lib/zgrid/date-range-cell-filter.component.mjs +135 -0
  33. package/esm2020/lib/zgrid/zgrid.binding.directive.mjs +490 -0
  34. package/esm2020/lib/zgrid/zgrid.component.mjs +847 -0
  35. package/esm2020/lib/zgrid/zgrid.popup.anchor-target.directive.mjs +17 -0
  36. package/esm2020/lib/zimg/zimg.component.mjs +121 -0
  37. package/esm2020/lib/zkcard/zkcard.component.mjs +367 -0
  38. package/esm2020/lib/zlabel/zlabel.component.mjs +62 -0
  39. package/esm2020/lib/zmfb/zmfb.component.mjs +215 -0
  40. package/esm2020/lib/zmodal/zmodal-mobile.component.mjs +120 -0
  41. package/esm2020/lib/zmodal/zmodal.component.mjs +125 -0
  42. package/esm2020/lib/znumeric/znumeric.component.mjs +119 -0
  43. package/esm2020/lib/zpostselectinput/zpostselectinput.component.mjs +352 -0
  44. package/esm2020/lib/zquerybuilder/zquerybuilder.component.mjs +204 -0
  45. package/esm2020/lib/zreport/zreport.component.mjs +105 -0
  46. package/esm2020/lib/zreport/zreport.config.mjs +117 -0
  47. package/esm2020/lib/zscheduler/zscheduler.component.mjs +267 -0
  48. package/{esm2015/lib/zscheduler/zscheduler.toolbar.component.js → esm2020/lib/zscheduler/zscheduler.toolbar.component.mjs} +55 -19
  49. package/esm2020/lib/zselectmultiple/zselectmultiple.component.mjs +577 -0
  50. package/esm2020/lib/zselectmultiple/zselectmultiple.directive.mjs +35 -0
  51. package/esm2020/lib/ztab/ztab.component.mjs +187 -0
  52. package/esm2020/lib/ztab/ztab.pipe.mjs +26 -0
  53. package/esm2020/lib/ztext/ztext.component.mjs +297 -0
  54. package/esm2020/lib/ztextarea/ztextarea.component.mjs +109 -0
  55. package/esm2020/lib/ztexteditor/ztexteditor.component.mjs +57 -0
  56. package/esm2020/lib/ztree/ztree.component.mjs +380 -0
  57. package/esm2020/lib/ztreelist/ztreelist.component.mjs +544 -0
  58. package/esm2020/lib/ztrendcard/ztrendcard.component.mjs +92 -0
  59. package/esm2020/lib/zudf/zudf.component.mjs +205 -0
  60. package/esm2020/lib/zunknown/zunknown.component.mjs +20 -0
  61. package/esm2020/lib/zupload/zupload.component.mjs +359 -0
  62. package/esm2020/lib/zworkflowbuttons/zworkflowbuttons.component.mjs +216 -0
  63. package/esm2020/mmhglobal-dynamicform.mjs +5 -0
  64. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  65. package/fesm2015/mmhglobal-dynamicform.mjs +10790 -0
  66. package/fesm2015/mmhglobal-dynamicform.mjs.map +1 -0
  67. package/fesm2020/mmhglobal-dynamicform.mjs +10779 -0
  68. package/fesm2020/mmhglobal-dynamicform.mjs.map +1 -0
  69. package/lib/directives/fieldelement.directive.d.ts +3 -0
  70. package/lib/directives/scrollbar.theme.directive.d.ts +3 -0
  71. package/lib/mmhglobal-dynamicform.module.d.ts +92 -0
  72. package/lib/services/main.service.d.ts +3 -0
  73. package/lib/services/zcomponent.debug.service.d.ts +8 -5
  74. package/lib/services/zcomponent.service.d.ts +7 -2
  75. package/lib/uiactionbutton/uiactionbutton.component.d.ts +3 -0
  76. package/lib/uiappmenucontent/uiappmenucontent.component.d.ts +3 -0
  77. package/lib/uicontent/uicontent.component.d.ts +3 -0
  78. package/lib/uiheader/uiheader.component.d.ts +3 -0
  79. package/lib/uimenubutton/uimenubutton.component.d.ts +3 -0
  80. package/lib/uimenucontent/uimenucontent.component.d.ts +3 -0
  81. package/lib/uipage/uipage.component.d.ts +3 -0
  82. package/lib/uivalidationmessage/uivalidationmessage.component.d.ts +3 -0
  83. package/lib/zbullet/zbullet.component.d.ts +3 -0
  84. package/lib/zbuttons/zbuttons.component.d.ts +3 -0
  85. package/lib/zcard/zcard.component.d.ts +3 -0
  86. package/lib/zchart/zchart.component.d.ts +3 -0
  87. package/lib/zcheckbox/zcheckbox.component.d.ts +3 -0
  88. package/lib/zchip/zchip.component.d.ts +3 -0
  89. package/lib/zcodeeditor/zcodeeditor.component.d.ts +3 -0
  90. package/lib/zcodeeditor/zcodeeditor.pipe.d.ts +3 -0
  91. package/lib/zdaterange/zdaterange.component.d.ts +3 -0
  92. package/lib/zdatetime/dateParser.pipe.d.ts +3 -0
  93. package/lib/zdatetime/zdatetime.component.d.ts +3 -0
  94. package/lib/zdiv/zdiv.component.d.ts +3 -0
  95. package/lib/zdiv/zdiv.pipe.d.ts +3 -0
  96. package/lib/zform/zform.component.d.ts +3 -0
  97. package/lib/zformcontrol/zformcontrol.component.d.ts +3 -0
  98. package/lib/zgauge/zgauge.component.d.ts +3 -0
  99. package/lib/zgrid/date-range-cell-filter.component.d.ts +3 -0
  100. package/lib/zgrid/zgrid.binding.directive.d.ts +3 -0
  101. package/lib/zgrid/zgrid.component.d.ts +4 -1
  102. package/lib/zgrid/zgrid.popup.anchor-target.directive.d.ts +3 -0
  103. package/lib/zimg/zimg.component.d.ts +3 -0
  104. package/lib/zkcard/zkcard.component.d.ts +3 -0
  105. package/lib/zlabel/zlabel.component.d.ts +3 -0
  106. package/lib/zmfb/zmfb.component.d.ts +3 -0
  107. package/lib/zmodal/zmodal-mobile.component.d.ts +3 -0
  108. package/lib/zmodal/zmodal.component.d.ts +3 -0
  109. package/lib/znumeric/znumeric.component.d.ts +3 -0
  110. package/lib/zpostselectinput/zpostselectinput.component.d.ts +3 -0
  111. package/lib/zquerybuilder/zquerybuilder.component.d.ts +3 -0
  112. package/lib/zreport/zreport.component.d.ts +3 -0
  113. package/lib/zreport/zreport.config.d.ts +3 -0
  114. package/lib/zscheduler/zscheduler.component.d.ts +3 -0
  115. package/lib/zscheduler/zscheduler.toolbar.component.d.ts +3 -0
  116. package/lib/zselectmultiple/zselectmultiple.component.d.ts +3 -0
  117. package/lib/zselectmultiple/zselectmultiple.directive.d.ts +3 -0
  118. package/lib/ztab/ztab.component.d.ts +3 -0
  119. package/lib/ztab/ztab.pipe.d.ts +3 -0
  120. package/lib/ztext/ztext.component.d.ts +3 -0
  121. package/lib/ztextarea/ztextarea.component.d.ts +3 -0
  122. package/lib/ztexteditor/ztexteditor.component.d.ts +3 -0
  123. package/lib/ztree/ztree.component.d.ts +3 -0
  124. package/lib/ztreelist/ztreelist.component.d.ts +3 -0
  125. package/lib/ztrendcard/ztrendcard.component.d.ts +3 -0
  126. package/lib/zudf/zudf.component.d.ts +3 -0
  127. package/lib/zunknown/zunknown.component.d.ts +3 -0
  128. package/lib/zupload/zupload.component.d.ts +3 -0
  129. package/lib/zworkflowbuttons/zworkflowbuttons.component.d.ts +3 -0
  130. package/mmhglobal-dynamicform.d.ts +1 -2
  131. package/package.json +20 -11
  132. package/bundles/mmhglobal-dynamicform.umd.js +0 -11360
  133. package/bundles/mmhglobal-dynamicform.umd.js.map +0 -1
  134. package/bundles/mmhglobal-dynamicform.umd.min.js +0 -16
  135. package/bundles/mmhglobal-dynamicform.umd.min.js.map +0 -1
  136. package/esm2015/lib/directives/fieldelement.directive.js +0 -15
  137. package/esm2015/lib/directives/scrollbar.theme.directive.js +0 -42
  138. package/esm2015/lib/mmhglobal-dynamicform.module.js +0 -314
  139. package/esm2015/lib/services/main.service.js +0 -766
  140. package/esm2015/lib/services/zcomponent.debug.service.js +0 -626
  141. package/esm2015/lib/services/zcomponent.service.js +0 -167
  142. package/esm2015/lib/uiactionbutton/uiactionbutton.component.js +0 -271
  143. package/esm2015/lib/uiappmenucontent/uiappmenucontent.component.js +0 -69
  144. package/esm2015/lib/uicontent/uicontent.component.js +0 -41
  145. package/esm2015/lib/uiheader/uiheader.component.js +0 -65
  146. package/esm2015/lib/uimenubutton/uimenubutton.component.js +0 -40
  147. package/esm2015/lib/uimenucontent/uimenucontent.component.js +0 -34
  148. package/esm2015/lib/uivalidationmessage/uivalidationmessage.component.js +0 -39
  149. package/esm2015/lib/zbullet/zbullet.component.js +0 -71
  150. package/esm2015/lib/zbuttons/zbuttons.component.js +0 -168
  151. package/esm2015/lib/zcard/zcard.component.js +0 -68
  152. package/esm2015/lib/zchart/zchart.component.js +0 -199
  153. package/esm2015/lib/zcheckbox/zcheckbox.component.js +0 -158
  154. package/esm2015/lib/zchip/zchip.component.js +0 -117
  155. package/esm2015/lib/zcodeeditor/zcodeeditor.component.js +0 -163
  156. package/esm2015/lib/zcodeeditor/zcodeeditor.pipe.js +0 -56
  157. package/esm2015/lib/zdaterange/zdaterange.component.js +0 -63
  158. package/esm2015/lib/zdatetime/dateParser.pipe.js +0 -26
  159. package/esm2015/lib/zdatetime/zdatetime.component.js +0 -279
  160. package/esm2015/lib/zdiv/zdiv.component.js +0 -48
  161. package/esm2015/lib/zdiv/zdiv.pipe.js +0 -27
  162. package/esm2015/lib/zform/zform.component.js +0 -148
  163. package/esm2015/lib/zformcontrol/zformcontrol.component.js +0 -49
  164. package/esm2015/lib/zgauge/zgauge.component.js +0 -146
  165. package/esm2015/lib/zgrid/date-range-cell-filter.component.js +0 -102
  166. package/esm2015/lib/zgrid/zgrid.binding.directive.js +0 -493
  167. package/esm2015/lib/zgrid/zgrid.component.js +0 -834
  168. package/esm2015/lib/zgrid/zgrid.popup.anchor-target.directive.js +0 -16
  169. package/esm2015/lib/zimg/zimg.component.js +0 -123
  170. package/esm2015/lib/zkcard/zkcard.component.js +0 -372
  171. package/esm2015/lib/zlabel/zlabel.component.js +0 -59
  172. package/esm2015/lib/zmfb/zmfb.component.js +0 -215
  173. package/esm2015/lib/zmodal/zmodal-mobile.component.js +0 -119
  174. package/esm2015/lib/zmodal/zmodal.component.js +0 -130
  175. package/esm2015/lib/znumeric/znumeric.component.js +0 -114
  176. package/esm2015/lib/zpostselectinput/zpostselectinput.component.js +0 -345
  177. package/esm2015/lib/zquerybuilder/zquerybuilder.component.js +0 -196
  178. package/esm2015/lib/zreport/zreport.component.js +0 -104
  179. package/esm2015/lib/zreport/zreport.config.js +0 -115
  180. package/esm2015/lib/zscheduler/zscheduler.component.js +0 -268
  181. package/esm2015/lib/zselectmultiple/zselectmultiple.component.js +0 -565
  182. package/esm2015/lib/zselectmultiple/zselectmultiple.directive.js +0 -28
  183. package/esm2015/lib/ztab/ztab.component.js +0 -180
  184. package/esm2015/lib/ztab/ztab.pipe.js +0 -22
  185. package/esm2015/lib/ztext/ztext.component.js +0 -286
  186. package/esm2015/lib/ztextarea/ztextarea.component.js +0 -104
  187. package/esm2015/lib/ztexteditor/ztexteditor.component.js +0 -52
  188. package/esm2015/lib/ztree/ztree.component.js +0 -374
  189. package/esm2015/lib/ztreelist/ztreelist.component.js +0 -539
  190. package/esm2015/lib/ztrendcard/ztrendcard.component.js +0 -89
  191. package/esm2015/lib/zudf/zudf.component.js +0 -206
  192. package/esm2015/lib/zunknown/zunknown.component.js +0 -20
  193. package/esm2015/lib/zupload/zupload.component.js +0 -358
  194. package/esm2015/lib/zworkflowbuttons/zworkflowbuttons.component.js +0 -215
  195. package/esm2015/mmhglobal-dynamicform.js +0 -7
  196. package/fesm2015/mmhglobal-dynamicform.js +0 -10729
  197. package/fesm2015/mmhglobal-dynamicform.js.map +0 -1
  198. package/mmhglobal-dynamicform.metadata.json +0 -1
@@ -0,0 +1,359 @@
1
+ /********** Angular **********/
2
+ import { Component, Input, ViewChild } from "@angular/core";
3
+ import { Validators } from "@angular/forms";
4
+ /********** Ionic **********/
5
+ /********** Plugin **********/
6
+ // import { environment } from "src/environments/environment";
7
+ import { take } from 'rxjs/operators';
8
+ import { HttpEventType } from '@angular/common/http';
9
+ /********** Component & Service **********/
10
+ import { ZComponentHelper, ZComponentProperties, UploadMetaData } from "mmhglobal-zcore";
11
+ import * as i0 from "@angular/core";
12
+ import * as i1 from "mmhglobal-zcore";
13
+ import * as i2 from "@ionic/angular";
14
+ import * as i3 from "@progress/kendo-angular-upload";
15
+ import * as i4 from "@angular/common";
16
+ import * as i5 from "@angular/forms";
17
+ export class MyFileInfo {
18
+ }
19
+ export class ZuploadComponent {
20
+ // zModelValue = [{
21
+ // name: "RXJS 01.png",
22
+ // size: 128753,
23
+ // uid: "c96e234d-af61-4587-adcc-3b400ddef884"
24
+ // }];
25
+ // fieldElement = [{
26
+ // Name: 'FileUploadList',
27
+ // Type: 'zupload',
28
+ // Value: 'FileUploadList',
29
+ // SelectionOptions: ['jpg', 'jpeg', 'png', 'bmp', 'pdf'],
30
+ // UploadMetaData: 'group.UploadMetaData',
31
+ // AutoUpload: false,
32
+ // AllowRemove: true,
33
+ // Multiple: false,
34
+ // OnSuccess: 'group.onSuccess()',
35
+ // DivClass: "col-md-12 col-md-6",
36
+ // Visible: true
37
+ // }];
38
+ constructor(authService, compressImage, zcoreService, ngZone) {
39
+ this.authService = authService;
40
+ this.compressImage = compressImage;
41
+ this.zcoreService = zcoreService;
42
+ this.ngZone = ngZone;
43
+ this.componentProperties = new ZComponentProperties();
44
+ this.uploadAttachmentUrl = null;
45
+ this.uploadSaveUrl = "/Attachment/Chunk_Upload_Save"; // should represent an actual API endpoint
46
+ this.uploadRemoveUrl = "/Attachment/Chunk_Upload_Remove"; // should represent an actual API endpoint
47
+ this.downloadFileUrl = "/Attachment/downloadFile";
48
+ this.getImageUrl = "/Attachment/getImage"; // GET method
49
+ this.isAutoUpload = false;
50
+ this.isMultiple = false;
51
+ this.imagePreviews = [];
52
+ this.uid = [];
53
+ this.showFileList = true;
54
+ this.fileList = [];
55
+ this.restrictions = {
56
+ minFileSize: 1,
57
+ maxFileSize: 4194304,
58
+ allowedExtensions: [
59
+ "jpg",
60
+ "jpeg",
61
+ "png",
62
+ "bmp",
63
+ "pdf",
64
+ "txt",
65
+ "docx",
66
+ "doc",
67
+ "xlsx",
68
+ "xls",
69
+ "ppt",
70
+ "pptx",
71
+ "csv",
72
+ ],
73
+ };
74
+ this.chunkSettings = {
75
+ size: 102400,
76
+ maxAutoRetries: 3,
77
+ };
78
+ this.setEnable = (status) => {
79
+ const fc = this.group.form.controls[this.data.Value];
80
+ status ? fc.enable() : fc.disable();
81
+ this.componentProperties.isReadOnly = !status;
82
+ };
83
+ this.setVisible = (status) => {
84
+ this.componentProperties.isVisible = status;
85
+ this.data.Visible = status;
86
+ };
87
+ this.setRequire = (status) => {
88
+ this.componentProperties.isRequired = status;
89
+ ZComponentHelper.changeValidator(status, this.group, this.data.Value, this.componentProperties, Validators.required);
90
+ };
91
+ this.uploadAttachmentUrl = this.zcoreService.getEnvironment().uploadAttachmentUrl;
92
+ this.uploadSaveUrl = this.uploadAttachmentUrl + this.uploadSaveUrl;
93
+ this.uploadRemoveUrl = this.uploadAttachmentUrl + this.uploadRemoveUrl;
94
+ }
95
+ ngOnInit() {
96
+ ZComponentHelper.setComponentProperties(this);
97
+ ZComponentHelper.registerComponent(this);
98
+ // this.group['UploadMetaData'] = new UploadMetaData(null, '15', 'SO-No-1234', 'SaleOrder');
99
+ // this.uploadSaveUrl = uploadAttachmentUrl + this.uploadSaveUrl;
100
+ // this.uploadRemoveUrl = uploadAttachmentUrl + this.uploadRemoveUrl;
101
+ if (this.data.SelectOptions) {
102
+ this.restrictions.allowedExtensions = this.data
103
+ .SelectOptions;
104
+ }
105
+ if (this.data.MinFileSize) {
106
+ this.restrictions.minFileSize = this.data.MinFileSize;
107
+ }
108
+ if (this.data.MaxFileSize) {
109
+ this.restrictions.maxFileSize = this.data.MaxFileSize;
110
+ }
111
+ this.isAutoUpload = this.data.AutoUpload || false;
112
+ if (!this.data.AllowRemove) {
113
+ this.uploadRemoveUrl = "";
114
+ }
115
+ if (this.data.Multiple) {
116
+ this.isMultiple = this.data.Multiple;
117
+ }
118
+ }
119
+ getIon_InvalidClass(form, data) {
120
+ return ZComponentHelper.getIon_InvalidClass(form, data);
121
+ }
122
+ onSuccess(e) {
123
+ // angular kendo upload didn't filter away Sent event for remove, so we have to handle it here
124
+ // upload progress not required for removal, thus it's also removed
125
+ // @ts-ignore
126
+ if (e.operation === "remove" && (e.response.type === HttpEventType.Sent || e.response.type === HttpEventType.UploadProgress)) {
127
+ return;
128
+ }
129
+ if (!Array.isArray(this.group.zModel[this.data.Value])) {
130
+ this.group.zModel[this.data.Value] = [];
131
+ }
132
+ const file = e.files[0];
133
+ const existingFileIndex = this.group.zModel[this.data.Value].findIndex(f => f.name === file.name && f.uid === file.uid);
134
+ if (e.operation === "upload") {
135
+ // console.log('upload Success: ', e);
136
+ file.myUid = file.uid;
137
+ delete file['httpSubscription'];
138
+ if (existingFileIndex !== -1) {
139
+ this.group.zModel[this.data.Value][existingFileIndex] = file;
140
+ }
141
+ else {
142
+ this.group.zModel[this.data.Value].push(file);
143
+ }
144
+ }
145
+ else if (e.operation === "remove") {
146
+ if (existingFileIndex !== -1) {
147
+ this.group.zModel[this.data.Value].splice(existingFileIndex, 1);
148
+ }
149
+ }
150
+ this.group.subject.next({
151
+ type: "zupload-onSuccess",
152
+ target: this.data.OnSuccess,
153
+ event: e,
154
+ data: { value: e.files[0], field: this.data },
155
+ });
156
+ }
157
+ compressionConfigHandler(imgConfig) {
158
+ if (imgConfig.FileSizeMaxSize) {
159
+ imgConfig.FileSizeMaxSizeByte = this.convertSizeToByte(imgConfig.FileSizeMaxSize);
160
+ }
161
+ if (imgConfig.FileSizeMinSize) {
162
+ imgConfig.FileSizeMinSizeByte = this.convertSizeToByte(imgConfig.FileSizeMinSize);
163
+ }
164
+ else {
165
+ imgConfig.FileSizeMinSizeByte = 0;
166
+ }
167
+ return imgConfig;
168
+ }
169
+ convertSizeToByte(sizeString) {
170
+ let _tempFileSizeMaxSize = 0;
171
+ let sizeByByte = 0;
172
+ let sizeType = 'b';
173
+ // remove all space
174
+ const _tempFileSize = sizeString.replace(/ /g, '');
175
+ // check last char is alphabetic
176
+ const lastChar = _tempFileSize.substr(_tempFileSize.length - 1);
177
+ if (isNaN(parseFloat(lastChar))) {
178
+ const secLastChar = _tempFileSize.substr(_tempFileSize.length - 2).slice(0, -1);
179
+ if (isNaN(parseFloat(secLastChar))) {
180
+ // check last 2nd char is alphabetic
181
+ sizeType = secLastChar + sizeType;
182
+ _tempFileSizeMaxSize = parseFloat(_tempFileSize.slice(0, -2));
183
+ }
184
+ else {
185
+ _tempFileSizeMaxSize = parseFloat(_tempFileSize.slice(0, -1));
186
+ }
187
+ switch (sizeType.toLowerCase()) {
188
+ case "b":
189
+ sizeByByte = _tempFileSizeMaxSize;
190
+ break;
191
+ case "kb":
192
+ sizeByByte = _tempFileSizeMaxSize * 1024;
193
+ break;
194
+ case "mb":
195
+ sizeByByte = _tempFileSizeMaxSize * 1048576;
196
+ break;
197
+ case "gb":
198
+ sizeByByte = _tempFileSizeMaxSize * 1073741824;
199
+ break;
200
+ }
201
+ }
202
+ else {
203
+ // default using bytes if no size type
204
+ sizeByByte = parseFloat(_tempFileSize);
205
+ }
206
+ return sizeByByte;
207
+ }
208
+ uploadEventHandler(e) {
209
+ // Image Preview
210
+ const me = this;
211
+ e.files.forEach((file) => {
212
+ if (file.rawFile && file.rawFile.type.includes("image")) {
213
+ if (!file.validationErrors) {
214
+ const reader = new FileReader();
215
+ reader.onload = function (ev) {
216
+ if (me.data.EnableImagePreview) {
217
+ if (!me.uid.includes(file.uid)) {
218
+ me.uid.push(file.uid);
219
+ me.imagePreviews.push({ ...file, src: reader.result });
220
+ }
221
+ }
222
+ };
223
+ reader.readAsDataURL(file.rawFile);
224
+ }
225
+ }
226
+ });
227
+ // Add metadata to the upload event
228
+ let additional = ZComponentHelper.getGroupEvalValue.call(this, this.data.UploadMetaData);
229
+ if (!(additional instanceof UploadMetaData)) {
230
+ console.error("UploadMetaData defined at " + this.data.UploadMetaData + " is invalid: ", additional);
231
+ additional = new UploadMetaData(null, "0");
232
+ }
233
+ const str = JSON.stringify(additional);
234
+ e.data = { additional: str, };
235
+ e.headers = e.headers.append("Authorization", "Bearer " + this.authService.e1AccessToken);
236
+ }
237
+ onRemove(e) {
238
+ // remove file from component memory
239
+ const index = this.fileList.findIndex((item) => item.uid === e.files[0].uid);
240
+ if (index >= 0) {
241
+ this.fileList.splice(index, 1);
242
+ this.group['zupload_' + this.data.Value] = this.fileList;
243
+ }
244
+ if (this.data['FileRemovedEvent']) {
245
+ this.group.subject.next({
246
+ type: "zupload-fileRemovedEvent",
247
+ target: this.data['FileRemovedEvent'],
248
+ data: e
249
+ });
250
+ }
251
+ else {
252
+ const myFile = e.files[0];
253
+ // console.log('remove done: ', e);
254
+ e.data = {
255
+ id: myFile.myUid,
256
+ };
257
+ e.headers = e.headers.append("Authorization", "Bearer " + this.authService.e1AccessToken);
258
+ if (this.data.EnableImagePreview) {
259
+ e.files.forEach((file) => {
260
+ this.imagePreviews = this.imagePreviews.filter(f => f.uid !== file.uid);
261
+ });
262
+ }
263
+ }
264
+ }
265
+ onChange(file) {
266
+ if (this.data['FileChangedEvent']) {
267
+ this.group.subject.next({
268
+ type: "zupload-fileChangedEvent",
269
+ target: this.data['FileChangedEvent'],
270
+ data: file
271
+ });
272
+ }
273
+ }
274
+ selectEventHandler(e) {
275
+ const me = this;
276
+ if (this.data['SelectFileOnly']) {
277
+ // append all file to component memory
278
+ e.files.forEach(async (file) => {
279
+ if (file.rawFile) {
280
+ const reader = new FileReader();
281
+ reader.onload = function (ev) {
282
+ // clone the data and also add the readed file to the object
283
+ const fileData = Object.assign({}, file);
284
+ fileData['file'] = ev.target["result"];
285
+ // push to component fileList
286
+ me.fileList.push(fileData);
287
+ me.group['zupload_' + me.data.Value] = me.fileList;
288
+ if (me.data['FileSelectedEvent']) {
289
+ // call the project event
290
+ me.group.subject.next({
291
+ type: "zupload-fileSelectedEvent",
292
+ target: me.data['FileSelectedEvent'],
293
+ data: me.fileList
294
+ });
295
+ }
296
+ };
297
+ await reader.readAsDataURL(file.rawFile);
298
+ }
299
+ });
300
+ }
301
+ else {
302
+ // Only workable for Auto Upload = false
303
+ if (!this.data.AutoUpload) {
304
+ // Compression for image file
305
+ const imageCompressionEnabled = this.data.Compression ? true : false;
306
+ //Check if Image Compression is enabled.
307
+ if (imageCompressionEnabled === true) {
308
+ e.files.forEach((file) => {
309
+ // Compress only if it is an image file
310
+ if (file.rawFile && file.rawFile.type.includes("image")) {
311
+ if (!file.validationErrors) {
312
+ const imgConfig = this.compressionConfigHandler(this.data.Compression);
313
+ if (file.size > imgConfig.FileSizeMinSizeByte) {
314
+ me.compressImage.compress(file.rawFile, imgConfig) //Pass in parameter to set the Compression Options
315
+ .pipe(take(1))
316
+ .subscribe(compressFile => {
317
+ this.ngZone.run(() => {
318
+ file.rawFile = compressFile;
319
+ file.size = compressFile.size;
320
+ // clone the data and also add the readed file to the object
321
+ const fileData = Object.assign({}, file);
322
+ // push to component fileList
323
+ me.fileList.push(fileData);
324
+ const reader = new FileReader();
325
+ reader.readAsDataURL(file.rawFile);
326
+ });
327
+ console.log(`Compressed file size: ${(file.rawFile.size / 1024).toFixed(2)}KB`);
328
+ });
329
+ } // file size check
330
+ } // validationErrors check
331
+ } // file type check
332
+ }); // loop each file
333
+ } // imagecompression check
334
+ // add to group scope
335
+ me.group['zupload_' + me.data.Value] = e.files;
336
+ }
337
+ }
338
+ }
339
+ clearFiles() {
340
+ this.uploadComponent.clearFiles();
341
+ this.group['zupload_' + this.data.Value] = this.fileList;
342
+ }
343
+ }
344
+ ZuploadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.4", ngImport: i0, type: ZuploadComponent, deps: [{ token: i1.AuthService }, { token: i1.CompressImageService }, { token: i1.ZCoreService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
345
+ ZuploadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.4", type: ZuploadComponent, selector: "app-zupload", inputs: { data: "data", group: "group", form: "form" }, viewQueries: [{ propertyName: "uploadComponent", first: true, predicate: ["uploadComponent"], descendants: true }], ngImport: i0, template: "<ion-item [formGroup]=\"form\" *ngIf=\"(!!componentProperties.isVisibleField ? group[componentProperties.isVisibleField] : componentProperties.isVisible)\" [ngClass]=\"getIon_InvalidClass(form, data)\" style=\"margin-left: -15px;\">\r\n <ion-label [attr.for]=\"data.Value\" *ngIf=\"data.ShowLabel === undefined || data.ShowLabel\" position=\"stacked\" style=\"margin-bottom: 10px;\">\r\n {{data.Label}} <ion-text *ngIf=\"(!!componentProperties.isRequiredField ? group[componentProperties.isRequiredField] : componentProperties.isRequired)\" color=\"danger\">*</ion-text>\r\n </ion-label>\r\n <div class=\"ion-row\" style=\"justify-content: space-between; width: 100%\">\r\n <span style=\"flex: 1;\">\r\n <kendo-upload #uploadComponent\r\n *ngIf=\"!data.SelectFileOnly\"\r\n [id]=\"data.Value\"\r\n [autoUpload]=\"isAutoUpload\"\r\n [saveUrl]=\"uploadSaveUrl\"\r\n [removeUrl]=\"uploadRemoveUrl\"\r\n [restrictions]=\"restrictions\"\r\n [formControlName]=\"data.Value\"\r\n [multiple]=\"isMultiple\"\r\n [chunkable]=\"chunkSettings\"\r\n [showFileList]=\"showFileList\"\r\n (select)=\"selectEventHandler($event)\"\r\n (remove)=\"onRemove($event)\" \r\n (success)=\"onSuccess($event)\"\r\n (upload)=\"uploadEventHandler($event)\">\r\n </kendo-upload>\r\n\r\n <kendo-fileselect #uploadComponent\r\n *ngIf=\"data.SelectFileOnly\"\r\n [id]=\"data.Value\"\r\n (select)=\"selectEventHandler($event)\"\r\n (remove)=\"onRemove($event)\" \r\n (valueChange)=\"onChange($event)\"\r\n [restrictions]=\"restrictions\" >\r\n </kendo-fileselect>\r\n </span>\r\n </div>\r\n</ion-item>\r\n<br />\r\n<!--<div class=\"wrap\" *ngIf=\"data.EnableCompression\">\r\n <ion-label>Enable Compression: </ion-label>\r\n <ion-checkbox style=\"margin: -5px 0;\" color=\"primary\" (ionChange)=\"toogleEnableCompression($event)\"></ion-checkbox>\r\n</div>-->\r\n<ion-label *ngIf=\"imagePreviews.length\" position=\"stacked\">\r\n Image Preview:\r\n</ion-label>\r\n<div *ngIf=\"imagePreviews.length\" >\r\n <img *ngFor=\"let image of imagePreviews\"\r\n [src]=\"image.src\"\r\n alt=\"image preview\"\r\n height=\"100\"\r\n style=\"margin: 5px; border: 1px solid gray;\"/>\r\n</div>\r\n", styles: [""], components: [{ type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { type: i2.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { type: i3.UploadComponent, selector: "kendo-upload", inputs: ["chunkable", "multiple", "disabled", "showFileList", "tabindex", "focusableId", "actionsLayout", "autoUpload", "batch", "withCredentials", "saveField", "saveHeaders", "saveMethod", "saveUrl", "responseType", "removeField", "removeHeaders", "removeMethod", "removeUrl", "concurrent", "tabIndex", "restrictions", "zoneId", "accept"], outputs: ["blur", "cancel", "clear", "complete", "error", "focus", "pause", "remove", "resume", "select", "success", "upload", "uploadProgress", "valueChange"], exportAs: ["kendoUpload"] }, { type: i3.FileSelectComponent, selector: "kendo-fileselect", inputs: ["disabled", "multiple", "showFileList", "tabindex", "focusableId", "name", "restrictions", "accept", "zoneId"], outputs: ["blur", "focus", "select", "remove", "valueChange"], exportAs: ["kendoFileSelect"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
346
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.4", ngImport: i0, type: ZuploadComponent, decorators: [{
347
+ type: Component,
348
+ args: [{ selector: "app-zupload", template: "<ion-item [formGroup]=\"form\" *ngIf=\"(!!componentProperties.isVisibleField ? group[componentProperties.isVisibleField] : componentProperties.isVisible)\" [ngClass]=\"getIon_InvalidClass(form, data)\" style=\"margin-left: -15px;\">\r\n <ion-label [attr.for]=\"data.Value\" *ngIf=\"data.ShowLabel === undefined || data.ShowLabel\" position=\"stacked\" style=\"margin-bottom: 10px;\">\r\n {{data.Label}} <ion-text *ngIf=\"(!!componentProperties.isRequiredField ? group[componentProperties.isRequiredField] : componentProperties.isRequired)\" color=\"danger\">*</ion-text>\r\n </ion-label>\r\n <div class=\"ion-row\" style=\"justify-content: space-between; width: 100%\">\r\n <span style=\"flex: 1;\">\r\n <kendo-upload #uploadComponent\r\n *ngIf=\"!data.SelectFileOnly\"\r\n [id]=\"data.Value\"\r\n [autoUpload]=\"isAutoUpload\"\r\n [saveUrl]=\"uploadSaveUrl\"\r\n [removeUrl]=\"uploadRemoveUrl\"\r\n [restrictions]=\"restrictions\"\r\n [formControlName]=\"data.Value\"\r\n [multiple]=\"isMultiple\"\r\n [chunkable]=\"chunkSettings\"\r\n [showFileList]=\"showFileList\"\r\n (select)=\"selectEventHandler($event)\"\r\n (remove)=\"onRemove($event)\" \r\n (success)=\"onSuccess($event)\"\r\n (upload)=\"uploadEventHandler($event)\">\r\n </kendo-upload>\r\n\r\n <kendo-fileselect #uploadComponent\r\n *ngIf=\"data.SelectFileOnly\"\r\n [id]=\"data.Value\"\r\n (select)=\"selectEventHandler($event)\"\r\n (remove)=\"onRemove($event)\" \r\n (valueChange)=\"onChange($event)\"\r\n [restrictions]=\"restrictions\" >\r\n </kendo-fileselect>\r\n </span>\r\n </div>\r\n</ion-item>\r\n<br />\r\n<!--<div class=\"wrap\" *ngIf=\"data.EnableCompression\">\r\n <ion-label>Enable Compression: </ion-label>\r\n <ion-checkbox style=\"margin: -5px 0;\" color=\"primary\" (ionChange)=\"toogleEnableCompression($event)\"></ion-checkbox>\r\n</div>-->\r\n<ion-label *ngIf=\"imagePreviews.length\" position=\"stacked\">\r\n Image Preview:\r\n</ion-label>\r\n<div *ngIf=\"imagePreviews.length\" >\r\n <img *ngFor=\"let image of imagePreviews\"\r\n [src]=\"image.src\"\r\n alt=\"image preview\"\r\n height=\"100\"\r\n style=\"margin: 5px; border: 1px solid gray;\"/>\r\n</div>\r\n", styles: [""] }]
349
+ }], ctorParameters: function () { return [{ type: i1.AuthService }, { type: i1.CompressImageService }, { type: i1.ZCoreService }, { type: i0.NgZone }]; }, propDecorators: { data: [{
350
+ type: Input
351
+ }], group: [{
352
+ type: Input
353
+ }], form: [{
354
+ type: Input
355
+ }], uploadComponent: [{
356
+ type: ViewChild,
357
+ args: ["uploadComponent"]
358
+ }] } });
359
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoienVwbG9hZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9tbWhnbG9iYWwtZHluYW1pY2Zvcm0vc3JjL2xpYi96dXBsb2FkL3p1cGxvYWQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbW1oZ2xvYmFsLWR5bmFtaWNmb3JtL3NyYy9saWIvenVwbG9hZC96dXBsb2FkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtCQUErQjtBQUMvQixPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBVSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUUsT0FBTyxFQUFhLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXZELDZCQUE2QjtBQUU3Qiw4QkFBOEI7QUFDOUIsOERBQThEO0FBQzlELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFZckQsMkNBQTJDO0FBQzNDLE9BQU8sRUFFTyxnQkFBZ0IsRUFBeUIsb0JBQW9CLEVBQ3pELGNBQWMsRUFDL0IsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7OztBQUV6QixNQUFNLE9BQU8sVUFBVTtDQUl0QjtBQU9ELE1BQU0sT0FBTyxnQkFBZ0I7SUE2QzNCLG1CQUFtQjtJQUNuQix5QkFBeUI7SUFDekIsa0JBQWtCO0lBQ2xCLGdEQUFnRDtJQUNoRCxNQUFNO0lBRU4sb0JBQW9CO0lBQ3BCLDRCQUE0QjtJQUM1QixxQkFBcUI7SUFDckIsNkJBQTZCO0lBQzdCLDREQUE0RDtJQUM1RCw0Q0FBNEM7SUFDNUMsdUJBQXVCO0lBQ3ZCLHVCQUF1QjtJQUN2QixxQkFBcUI7SUFDckIsb0NBQW9DO0lBQ3BDLG9DQUFvQztJQUNwQyxrQkFBa0I7SUFDbEIsTUFBTTtJQUVOLFlBQ1UsV0FBd0IsRUFDeEIsYUFB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QWIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ3dCLGVBQWU7c0JBQTVDLFNBQVM7dUJBQUMsaUJBQWlCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKiogQW5ndWxhciAqKioqKioqKioqL1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE5nWm9uZSwgVmlld0NoaWxkIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHsgRm9ybUdyb3VwLCBWYWxpZGF0b3JzIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XHJcblxyXG4vKioqKioqKioqKiBJb25pYyAqKioqKioqKioqL1xyXG5cclxuLyoqKioqKioqKiogUGx1Z2luICoqKioqKioqKiovXHJcbi8vIGltcG9ydCB7IGVudmlyb25tZW50IH0gZnJvbSBcInNyYy9lbnZpcm9ubWVudHMvZW52aXJvbm1lbnRcIjtcclxuaW1wb3J0IHsgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgSHR0cEV2ZW50VHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHtcclxuICBGaWxlSW5mbyxcclxuICBTdWNjZXNzRXZlbnQsXHJcbiAgUmVtb3ZlRXZlbnQsXHJcbiAgVXBsb2FkRXZlbnQsXHJcbiAgRmlsZVJlc3RyaWN0aW9ucyxcclxuICBDaHVua1NldHRpbmdzLFxyXG4gIFNlbGVjdEV2ZW50LFxyXG4gIFVwbG9hZENvbXBvbmVudFxyXG59IGZyb20gXCJAcHJvZ3Jlc3Mva2VuZG8tYW5ndWxhci11cGxvYWRcIjtcclxuXHJcbi8qKioqKioqKioqIENvbXBvbmVudCAmIFNlcnZpY2UgKioqKioqKioqKi9cclxuaW1wb3J0IHtcclxuICBBdXRoU2VydmljZSwgWkNvcmVTZXJ2aWNlLCBDb21wcmVzc0ltYWdlU2VydmljZSxcclxuICBaQ29tcG9uZW50LCBaQ29tcG9uZW50SGVscGVyLCBaQ29tcG9uZW50T3V0cHV0RXZlbnQsIFpDb21wb25lbnRQcm9wZXJ0aWVzLFxyXG4gIFpGaWVsZCwgWkdyb3VwLCBVcGxvYWRNZXRhRGF0YSwgSW1hZ2VDb21wcmVzc2lvbkNvbmZpZ1xyXG59IGZyb20gXCJtbWhnbG9iYWwtemNvcmVcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBNeUZpbGVJbmZvIGltcGxlbWVudHMgRmlsZUluZm8ge1xyXG4gIG5hbWU6IHN0cmluZztcclxuICB1aWQ/OiBzdHJpbmc7XHJcbiAgbXlVaWQ/OiBzdHJpbmc7XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiBcImFwcC16dXBsb2FkXCIsXHJcbiAgdGVtcGxhdGVVcmw6IFwiLi96dXBsb2FkLmNvbXBvbmVudC5odG1sXCIsXHJcbiAgc3R5bGVVcmxzOiBbXCIuL3p1cGxvYWQuY29tcG9uZW50LnNjc3NcIl0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBadXBsb2FkQ29tcG9uZW50IGltcGxlbWVudHMgWkNvbXBvbmVudCwgT25Jbml0IHtcclxuICBASW5wdXQoKSBkYXRhOiBaRmllbGQ7XHJcbiAgQElucHV0KCkgZ3JvdXA6IFpHcm91cDtcclxuICBASW5wdXQoKSBmb3JtOiBGb3JtR3JvdXA7XHJcbiAgQFZpZXdDaGlsZChcInVwbG9hZENvbXBvbmVudFwiKSB1cGxvYWRDb21wb25lbnQ6IFVwbG9hZENvbXBvbmVudDtcclxuXHJcbiAgY29tcG9uZW50UHJvcGVydGllcyA9IG5ldyBaQ29tcG9uZW50UHJvcGVydGllcygpO1xyXG4gIHVwbG9hZEF0dGFjaG1lbnRVcmw6IHN0cmluZyA9IG51bGw7XHJcbiAgdXBsb2FkU2F2ZVVybCA9IFwiL0F0dGFjaG1lbnQvQ2h1bmtfVXBsb2FkX1NhdmVcIjsgLy8gc2hvdWxkIHJlcHJlc2VudCBhbiBhY3R1YWwgQVBJIGVuZHBvaW50XHJcbiAgdXBsb2FkUmVtb3ZlVXJsID0gXCIvQXR0YWNobWVudC9DaHVua19VcGxvYWRfUmVtb3ZlXCI7IC8vIHNob3VsZCByZXByZXNlbnQgYW4gYWN0dWFsIEFQSSBlbmRwb2ludFxyXG4gIGRvd25sb2FkRmlsZVVybCA9IFwiL0F0dGFjaG1lbnQvZG93bmxvYWRGaWxlXCI7XHJcbiAgZ2V0SW1hZ2VVcmwgPSBcIi9BdHRhY2htZW50L2dldEltYWdlXCI7IC8vIEdFVCBtZXRob2RcclxuICBpc0F1dG9VcGxvYWQgPSBmYWxzZTtcclxuICBpc011bHRpcGxlID0gZmFsc2U7XHJcbiAgaW1hZ2VQcmV2aWV3czogYW55W10gPSBbXTtcclxuICB1aWQ6IHN0cmluZ1tdID0gW107XHJcbiAgc2hvd0ZpbGVMaXN0ID0gdHJ1ZTtcclxuICBmaWxlTGlzdDogYW55W10gPSBbXTtcclxuXHJcbiAgcHVibGljIHJlc3RyaWN0aW9uczogRmlsZVJlc3RyaWN0aW9ucyA9IHtcclxuXHJcbiAgICBtaW5GaWxlU2l6ZTogMSxcclxuICAgIG1heEZpbGVTaXplOiA0MTk0MzA0LFxyXG4gICAgYWxsb3dlZEV4dGVuc2lvbnM6IFtcclxuICAgICAgXCJqcGdcIixcclxuICAgICAgXCJqcGVnXCIsXHJcbiAgICAgIFwicG5nXCIsXHJcbiAgICAgIFwiYm1wXCIsXHJcbiAgICAgIFwicGRmXCIsXHJcbiAgICAgIFwidHh0XCIsXHJcbiAgICAgIFwiZG9jeFwiLFxyXG4gICAgICBcImRvY1wiLFxyXG4gICAgICBcInhsc3hcIixcclxuICAgICAgXCJ4bHNcIixcclxuICAgICAgXCJwcHRcIixcclxuICAgICAgXCJwcHR4XCIsXHJcbiAgICAgIFwiY3N2XCIsXHJcbiAgICBdLFxyXG4gIH07XHJcblxyXG4gIHB1YmxpYyBjaHVua1NldHRpbmdzOiBDaHVua1NldHRpbmdzID0ge1xyXG4gICAgc2l6ZTogMTAyNDAwLFxyXG4gICAgbWF4QXV0b1JldHJpZXM6IDMsXHJcbiAgfTtcclxuXHJcbiAgLy8gek1vZGVsVmFsdWUgPSBbe1xyXG4gIC8vICAgbmFtZTogXCJSWEpTIDAxLnBuZ1wiLFxyXG4gIC8vICAgc2l6ZTogMTI4NzUzLFxyXG4gIC8vICAgdWlkOiBcImM5NmUyMzRkLWFmNjEtNDU4Ny1hZGNjLTNiNDAwZGRlZjg4NFwiXHJcbiAgLy8gfV07XHJcblxyXG4gIC8vIGZpZWxkRWxlbWVudCA9IFt7XHJcbiAgLy8gICBOYW1lOiAnRmlsZVVwbG9hZExpc3QnLFxyXG4gIC8vICAgVHlwZTogJ3p1cGxvYWQnLFxyXG4gIC8vICAgVmFsdWU6ICdGaWxlVXBsb2FkTGlzdCcsXHJcbiAgLy8gICBTZWxlY3Rpb25PcHRpb25zOiBbJ2pwZycsICdqcGVnJywgJ3BuZycsICdibXAnLCAncGRmJ10sXHJcbiAgLy8gICBVcGxvYWRNZXRhRGF0YTogJ2dyb3VwLlVwbG9hZE1ldGFEYXRhJyxcclxuICAvLyAgIEF1dG9VcGxvYWQ6IGZhbHNlLFxyXG4gIC8vICAgQWxsb3dSZW1vdmU6IHRydWUsXHJcbiAgLy8gICBNdWx0aXBsZTogZmFsc2UsXHJcbiAgLy8gICBPblN1Y2Nlc3M6ICdncm91cC5vblN1Y2Nlc3MoKScsXHJcbiAgLy8gICBEaXZDbGFzczogXCJjb2wtbWQtMTIgY29sLW1kLTZcIixcclxuICAvLyAgIFZpc2libGU6IHRydWVcclxuICAvLyB9XTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGF1dGhTZXJ2aWNlOiBBdXRoU2VydmljZSxcclxuICAgIHByaXZhdGUgY29tcHJlc3NJbWFnZTogQ29tcHJlc3NJbWFnZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHpjb3JlU2VydmljZTogWkNvcmVTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZVxyXG4gICkge1xyXG4gICAgdGhpcy51cGxvYWRBdHRhY2htZW50VXJsID0gdGhpcy56Y29yZVNlcnZpY2UuZ2V0RW52aXJvbm1lbnQoKS51cGxvYWRBdHRhY2htZW50VXJsO1xyXG4gICAgdGhpcy51cGxvYWRTYXZlVXJsID0gdGhpcy51cGxvYWRBdHRhY2htZW50VXJsICsgdGhpcy51cGxvYWRTYXZlVXJsO1xyXG4gICAgdGhpcy51cGxvYWRSZW1vdmVVcmwgPSB0aGlzLnVwbG9hZEF0dGFjaG1lbnRVcmwgKyB0aGlzLnVwbG9hZFJlbW92ZVVybDtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgWkNvbXBvbmVudEhlbHBlci5zZXRDb21wb25lbnRQcm9wZXJ0aWVzKHRoaXMpO1xyXG4gICAgWkNvbXBvbmVudEhlbHBlci5yZWdpc3RlckNvbXBvbmVudCh0aGlzKTtcclxuXHJcbiAgICAvLyB0aGlzLmdyb3VwWydVcGxvYWRNZXRhRGF0YSddID0gbmV3IFVwbG9hZE1ldGFEYXRhKG51bGwsICcxNScsICdTTy1Oby0xMjM0JywgJ1NhbGVPcmRlcicpO1xyXG5cclxuXHJcbiAgICAvLyB0aGlzLnVwbG9hZFNhdmVVcmwgPSB1cGxvYWRBdHRhY2htZW50VXJsICsgdGhpcy51cGxvYWRTYXZlVXJsO1xyXG4gICAgLy8gdGhpcy51cGxvYWRSZW1vdmVVcmwgPSB1cGxvYWRBdHRhY2htZW50VXJsICsgdGhpcy51cGxvYWRSZW1vdmVVcmw7XHJcblxyXG4gICAgaWYgKHRoaXMuZGF0YS5TZWxlY3RPcHRpb25zKSB7XHJcbiAgICAgIHRoaXMucmVzdHJpY3Rpb25zLmFsbG93ZWRFeHRlbnNpb25zID0gKHRoaXMuZGF0YVxyXG4gICAgICAgIC5TZWxlY3RPcHRpb25zIGFzIHVua25vd24pIGFzIHN0cmluZ1tdO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmRhdGEuTWluRmlsZVNpemUpIHtcclxuICAgICAgdGhpcy5yZXN0cmljdGlvbnMubWluRmlsZVNpemUgPSB0aGlzLmRhdGEuTWluRmlsZVNpemU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuZGF0YS5NYXhGaWxlU2l6ZSkge1xyXG4gICAgICB0aGlzLnJlc3RyaWN0aW9ucy5tYXhGaWxlU2l6ZSA9IHRoaXMuZGF0YS5NYXhGaWxlU2l6ZTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmlzQXV0b1VwbG9hZCA9IHRoaXMuZGF0YS5BdXRvVXBsb2FkIHx8IGZhbHNlO1xyXG5cclxuICAgIGlmICghdGhpcy5kYXRhLkFsbG93UmVtb3ZlKSB7XHJcbiAgICAgIHRoaXMudXBsb2FkUmVtb3ZlVXJsID0gXCJcIjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5kYXRhLk11bHRpcGxlKSB7XHJcbiAgICAgIHRoaXMuaXNNdWx0aXBsZSA9IHRoaXMuZGF0YS5NdWx0aXBsZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXRFbmFibGUgPSAoc3RhdHVzOiBib29sZWFuKSA9PiB7XHJcbiAgICBjb25zdCBmYyA9IHRoaXMuZ3JvdXAuZm9ybS5jb250cm9sc1t0aGlzLmRhdGEuVmFsdWVdO1xyXG4gICAgc3RhdHVzID8gZmMuZW5hYmxlKCkgOiBmYy5kaXNhYmxlKCk7XHJcbiAgICB0aGlzLmNvbXBvbmVudFByb3BlcnRpZXMuaXNSZWFkT25seSA9ICFzdGF0dXM7XHJcbiAgfTtcclxuXHJcbiAgcHVibGljIHNldFZpc2libGUgPSAoc3RhdHVzOiBib29sZWFuKSA9PiB7XHJcbiAgICB0aGlzLmNvbXBvbmVudFByb3BlcnRpZXMuaXNWaXNpYmxlID0gc3RhdHVzO1xyXG4gICAgdGhpcy5kYXRhLlZpc2libGUgPSBzdGF0dXM7XHJcbiAgfTtcclxuXHJcbiAgcHVibGljIHNldFJlcXVpcmUgPSAoc3RhdHVzOiBib29sZWFuKSA9PiB7XHJcbiAgICB0aGlzLmNvbXBvbmVudFByb3BlcnRpZXMuaXNSZXF1aXJlZCA9IHN0YXR1cztcclxuICAgIFpDb21wb25lbnRIZWxwZXIuY2hhbmdlVmFsaWRhdG9yKFxyXG4gICAgICBzdGF0dXMsXHJcbiAgICAgIHRoaXMuZ3JvdXAsXHJcbiAgICAgIHRoaXMuZGF0YS5WYWx1ZSxcclxuICAgICAgdGhpcy5jb21wb25lbnRQcm9wZXJ0aWVzLFxyXG4gICAgICBWYWxpZGF0b3JzLnJlcXVpcmVkXHJcbiAgICApO1xyXG4gIH07XHJcblxyXG4gIGdldElvbl9JbnZhbGlkQ2xhc3MoZm9ybTogRm9ybUdyb3VwLCBkYXRhOiBaRmllbGQpIHtcclxuICAgIHJldHVybiBaQ29tcG9uZW50SGVscGVyLmdldElvbl9JbnZhbGlkQ2xhc3MoZm9ybSwgZGF0YSk7XHJcbiAgfVxyXG5cclxuICBvblN1Y2Nlc3MoZTogU3VjY2Vzc0V2ZW50KTogdm9pZCB7XHJcbiAgICAvLyBhbmd1bGFyIGtlbmRvIHVwbG9hZCBkaWRuJ3QgZmlsdGVyIGF3YXkgU2VudCBldmVudCBmb3IgcmVtb3ZlLCBzbyB3ZSBoYXZlIHRvIGhhbmRsZSBpdCBoZXJlXHJcbiAgICAvLyB1cGxvYWQgcHJvZ3Jlc3Mgbm90IHJlcXVpcmVkIGZvciByZW1vdmFsLCB0aHVzIGl0J3MgYWxzbyByZW1vdmVkXHJcbiAgICAvLyBAdHMtaWdub3JlXHJcbiAgICBpZiAoZS5vcGVyYXRpb24gPT09IFwicmVtb3ZlXCIgJiYgKGUucmVzcG9uc2UudHlwZSA9PT0gSHR0cEV2ZW50VHlwZS5TZW50IHx8IGUucmVzcG9uc2UudHlwZSA9PT0gSHR0cEV2ZW50VHlwZS5VcGxvYWRQcm9ncmVzcykpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLmdyb3VwLnpNb2RlbFt0aGlzLmRhdGEuVmFsdWVdKSkge1xyXG4gICAgICB0aGlzLmdyb3VwLnpNb2RlbFt0aGlzLmRhdGEuVmFsdWVdID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZmlsZSA9IGUuZmlsZXNbMF0gYXMgTXlGaWxlSW5mbztcclxuICAgIGNvbnN0IGV4aXN0aW5nRmlsZUluZGV4ID0gdGhpcy5ncm91cC56TW9kZWxbdGhpcy5kYXRhLlZhbHVlXS5maW5kSW5kZXgoZiA9PiBmLm5hbWUgPT09IGZpbGUubmFtZSAmJiBmLnVpZCA9PT0gZmlsZS51aWQpO1xyXG4gICAgaWYgKGUub3BlcmF0aW9uID09PSBcInVwbG9hZFwiKSB7XHJcbiAgICAgIC8vIGNvbnNvbGUubG9nKCd1cGxvYWQgU3VjY2VzczogJywgZSk7XHJcbiAgICAgIGZpbGUubXlVaWQgPSBmaWxlLnVpZDtcclxuICAgICAgZGVsZXRlIGZpbGVbJ2h0dHBTdWJzY3JpcHRpb24nXTtcclxuXHJcbiAgICAgIGlmIChleGlzdGluZ0ZpbGVJbmRleCAhPT0gLTEpIHtcclxuICAgICAgICB0aGlzLmdyb3VwLnpNb2RlbFt0aGlzLmRhdGEuVmFsdWVdW2V4aXN0aW5nRmlsZUluZGV4XSA9IGZpbGU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5ncm91cC56TW9kZWxbdGhpcy5kYXRhLlZhbHVlXS5wdXNoKGZpbGUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgfSBlbHNlIGlmIChlLm9wZXJhdGlvbiA9PT0gXCJyZW1vdmVcIikge1xyXG4gICAgICBpZiAoZXhpc3RpbmdGaWxlSW5kZXggIT09IC0xKSB7XHJcbiAgICAgICAgdGhpcy5ncm91cC56TW9kZWxbdGhpcy5kYXRhLlZhbHVlXS5zcGxpY2UoZXhpc3RpbmdGaWxlSW5kZXgsIDEpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5ncm91cC5zdWJqZWN0Lm5leHQoe1xyXG4gICAgICB0eXBlOiBcInp1cGxvYWQtb25TdWNjZXNzXCIsXHJcbiAgICAgIHRhcmdldDogdGhpcy5kYXRhLk9uU3VjY2VzcyxcclxuICAgICAgZXZlbnQ6IGUsXHJcbiAgICAgIGRhdGE6IHsgdmFsdWU6IGUuZmlsZXNbMF0sIGZpZWxkOiB0aGlzLmRhdGEgfSxcclxuICAgIH0gYXMgWkNvbXBvbmVudE91dHB1dEV2ZW50KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY29tcHJlc3Npb25Db25maWdIYW5kbGVyKGltZ0NvbmZpZzogSW1hZ2VDb21wcmVzc2lvbkNvbmZpZyk6IEltYWdlQ29tcHJlc3Npb25Db25maWcge1xyXG4gICAgaWYgKGltZ0NvbmZpZy5GaWxlU2l6ZU1heFNpemUpIHtcclxuICAgICAgaW1nQ29uZmlnLkZpbGVTaXplTWF4U2l6ZUJ5dGUgPSB0aGlzLmNvbnZlcnRTaXplVG9CeXRlKGltZ0NvbmZpZy5GaWxlU2l6ZU1heFNpemUpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpbWdDb25maWcuRmlsZVNpemVNaW5TaXplKSB7XHJcbiAgICAgIGltZ0NvbmZpZy5GaWxlU2l6ZU1pblNpemVCeXRlID0gdGhpcy5jb252ZXJ0U2l6ZVRvQnl0ZShpbWdDb25maWcuRmlsZVNpemVNaW5TaXplKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICBpbWdDb25maWcuRmlsZVNpemVNaW5TaXplQnl0ZSA9IDA7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGltZ0NvbmZpZztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY29udmVydFNpemVUb0J5dGUoc2l6ZVN0cmluZzogc3RyaW5nKTogbnVtYmVyIHtcclxuICAgIGxldCBfdGVtcEZpbGVTaXplTWF4U2l6ZTogbnVtYmVyID0gMDtcclxuICAgIGxldCBzaXplQnlCeXRlOiBudW1iZXIgPSAwO1xyXG4gICAgbGV0IHNpemVUeXBlID0gJ2InO1xyXG5cclxuICAgIC8vIHJlbW92ZSBhbGwgc3BhY2VcclxuICAgIGNvbnN0IF90ZW1wRmlsZVNpemUgPSBzaXplU3RyaW5nLnJlcGxhY2UoLyAvZywgJycpO1xyXG5cclxuICAgIC8vIGNoZWNrIGxhc3QgY2hhciBpcyBhbHBoYWJldGljXHJcbiAgICBjb25zdCBsYXN0Q2hhciA9IF90ZW1wRmlsZVNpemUuc3Vic3RyKF90ZW1wRmlsZVNpemUubGVuZ3RoIC0gMSk7XHJcbiAgICBpZiAoaXNOYU4ocGFyc2VGbG9hdChsYXN0Q2hhcikpKSB7XHJcbiAgICAgIGNvbnN0IHNlY0xhc3RDaGFyID0gX3RlbXBGaWxlU2l6ZS5zdWJzdHIoX3RlbXBGaWxlU2l6ZS5sZW5ndGggLSAyKS5zbGljZSgwLCAtMSk7XHJcblxyXG4gICAgICBpZiAoaXNOYU4ocGFyc2VGbG9hdChzZWNMYXN0Q2hhcikpKSB7XHJcbiAgICAgICAgLy8gY2hlY2sgbGFzdCAybmQgY2hhciBpcyBhbHBoYWJldGljXHJcbiAgICAgICAgc2l6ZVR5cGUgPSBzZWNMYXN0Q2hhciArIHNpemVUeXBlO1xyXG4gICAgICAgIF90ZW1wRmlsZVNpemVNYXhTaXplID0gcGFyc2VGbG9hdChfdGVtcEZpbGVTaXplLnNsaWNlKDAsIC0yKSk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgX3RlbXBGaWxlU2l6ZU1heFNpemUgPSBwYXJzZUZsb2F0KF90ZW1wRmlsZVNpemUuc2xpY2UoMCwgLTEpKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc3dpdGNoIChzaXplVHlwZS50b0xvd2VyQ2FzZSgpKSB7XHJcbiAgICAgICAgY2FzZSBcImJcIjpcclxuICAgICAgICAgIHNpemVCeUJ5dGUgPSBfdGVtcEZpbGVTaXplTWF4U2l6ZVxyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBcImtiXCI6XHJcbiAgICAgICAgICBzaXplQnlCeXRlID0gX3RlbXBGaWxlU2l6ZU1heFNpemUgKiAxMDI0XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFwibWJcIjpcclxuICAgICAgICAgIHNpemVCeUJ5dGUgPSBfdGVtcEZpbGVTaXplTWF4U2l6ZSAqIDEwNDg1NzZcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgXCJnYlwiOlxyXG4gICAgICAgICAgc2l6ZUJ5Qnl0ZSA9IF90ZW1wRmlsZVNpemVNYXhTaXplICogMTA3Mzc0MTgyNFxyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAvLyBkZWZhdWx0IHVzaW5nIGJ5dGVzIGlmIG5vIHNpemUgdHlwZVxyXG4gICAgICBzaXplQnlCeXRlID0gcGFyc2VGbG9hdChfdGVtcEZpbGVTaXplKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc2l6ZUJ5Qnl0ZTtcclxuICB9XHJcblxyXG4gIHVwbG9hZEV2ZW50SGFuZGxlcihlOiBVcGxvYWRFdmVudCkge1xyXG4gICAgLy8gSW1hZ2UgUHJldmlld1xyXG4gICAgY29uc3QgbWUgPSB0aGlzO1xyXG4gICAgZS5maWxlcy5mb3JFYWNoKChmaWxlOiBGaWxlSW5mbykgPT4ge1xyXG4gICAgICBpZiAoZmlsZS5yYXdGaWxlICYmIGZpbGUucmF3RmlsZS50eXBlLmluY2x1ZGVzKFwiaW1hZ2VcIikpIHtcclxuICAgICAgICBpZiAoIWZpbGUudmFsaWRhdGlvbkVycm9ycykge1xyXG4gICAgICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcclxuICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoZXYpIHtcclxuICAgICAgICAgICAgaWYgKG1lLmRhdGEuRW5hYmxlSW1hZ2VQcmV2aWV3KSB7XHJcbiAgICAgICAgICAgICAgaWYgKCFtZS51aWQuaW5jbHVkZXMoZmlsZS51aWQpKSB7XHJcbiAgICAgICAgICAgICAgICBtZS51aWQucHVzaChmaWxlLnVpZCk7XHJcbiAgICAgICAgICAgICAgICBtZS5pbWFnZVByZXZpZXdzLnB1c2goeyAuLi5maWxlLCBzcmM6IDxzdHJpbmc+cmVhZGVyLnJlc3VsdCB9KTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUucmF3RmlsZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBBZGQgbWV0YWRhdGEgdG8gdGhlIHVwbG9hZCBldmVudFxyXG4gICAgbGV0IGFkZGl0aW9uYWw6IFVwbG9hZE1ldGFEYXRhID0gWkNvbXBvbmVudEhlbHBlci5nZXRHcm91cEV2YWxWYWx1ZS5jYWxsKHRoaXMsIHRoaXMuZGF0YS5VcGxvYWRNZXRhRGF0YSk7XHJcblxyXG4gICAgaWYgKCEoYWRkaXRpb25hbCBpbnN0YW5jZW9mIFVwbG9hZE1ldGFEYXRhKSkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKFwiVXBsb2FkTWV0YURhdGEgZGVmaW5lZCBhdCBcIiArIHRoaXMuZGF0YS5VcGxvYWRNZXRhRGF0YSArIFwiIGlzIGludmFsaWQ6IFwiLCBhZGRpdGlvbmFsKTtcclxuICAgICAgYWRkaXRpb25hbCA9IG5ldyBVcGxvYWRNZXRhRGF0YShudWxsLCBcIjBcIik7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgc3RyID0gSlNPTi5zdHJpbmdpZnkoYWRkaXRpb25hbCk7XHJcblxyXG4gICAgZS5kYXRhID0geyBhZGRpdGlvbmFsOiBzdHIsIH07XHJcbiAgICBlLmhlYWRlcnMgPSBlLmhlYWRlcnMuYXBwZW5kKFwiQXV0aG9yaXphdGlvblwiLCBcIkJlYXJlciBcIiArIHRoaXMuYXV0aFNlcnZpY2UuZTFBY2Nlc3NUb2tlbik7XHJcbiAgfVxyXG5cclxuICBvblJlbW92ZShlOiBSZW1vdmVFdmVudCk6IHZvaWQge1xyXG4gICAgLy8gcmVtb3ZlIGZpbGUgZnJvbSBjb21wb25lbnQgbWVtb3J5XHJcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuZmlsZUxpc3QuZmluZEluZGV4KFxyXG4gICAgICAoaXRlbSkgPT4gaXRlbS51aWQgPT09IGUuZmlsZXNbMF0udWlkXHJcbiAgICApO1xyXG5cclxuICAgIGlmIChpbmRleCA+PSAwKSB7XHJcbiAgICAgIHRoaXMuZmlsZUxpc3Quc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgdGhpcy5ncm91cFsnenVwbG9hZF8nICsgdGhpcy5kYXRhLlZhbHVlXSA9IHRoaXMuZmlsZUxpc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuZGF0YVsnRmlsZVJlbW92ZWRFdmVudCddKSB7XHJcbiAgICAgIHRoaXMuZ3JvdXAuc3ViamVjdC5uZXh0KHtcclxuICAgICAgICB0eXBlOiBcInp1cGxvYWQtZmlsZVJlbW92ZWRFdmVudFwiLFxyXG4gICAgICAgIHRhcmdldDogdGhpcy5kYXRhWydGaWxlUmVtb3ZlZEV2ZW50J10sXHJcbiAgICAgICAgZGF0YTogZVxyXG4gICAgICB9IGFzIFpDb21wb25lbnRPdXRwdXRFdmVudCk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgY29uc3QgbXlGaWxlOiBNeUZpbGVJbmZvID0gZS5maWxlc1swXSBhcyBNeUZpbGVJbmZvO1xyXG5cclxuICAgICAgLy8gY29uc29sZS5sb2coJ3JlbW92ZSBkb25lOiAnLCBlKTtcclxuICAgICAgZS5kYXRhID0ge1xyXG4gICAgICAgIGlkOiBteUZpbGUubXlVaWQsXHJcbiAgICAgIH07XHJcbiAgICAgIGUuaGVhZGVycyA9IGUuaGVhZGVycy5hcHBlbmQoXHJcbiAgICAgICAgXCJBdXRob3JpemF0aW9uXCIsXHJcbiAgICAgICAgXCJCZWFyZXIgXCIgKyB0aGlzLmF1dGhTZXJ2aWNlLmUxQWNjZXNzVG9rZW5cclxuICAgICAgKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmRhdGEuRW5hYmxlSW1hZ2VQcmV2aWV3KSB7XHJcbiAgICAgICAgZS5maWxlcy5mb3JFYWNoKChmaWxlOiBGaWxlSW5mbykgPT4ge1xyXG4gICAgICAgICAgdGhpcy5pbWFnZVByZXZpZXdzID0gdGhpcy5pbWFnZVByZXZpZXdzLmZpbHRlcihmID0+IGYudWlkICE9PSBmaWxlLnVpZCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uQ2hhbmdlKGZpbGU6IEZpbGVJbmZvW10pOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmRhdGFbJ0ZpbGVDaGFuZ2VkRXZlbnQnXSkge1xyXG4gICAgICB0aGlzLmdyb3VwLnN1YmplY3QubmV4dCh7XHJcbiAgICAgICAgdHlwZTogXCJ6dXBsb2FkLWZpbGVDaGFuZ2VkRXZlbnRcIixcclxuICAgICAgICB0YXJnZXQ6IHRoaXMuZGF0YVsnRmlsZUNoYW5nZWRFdmVudCddLFxyXG4gICAgICAgIGRhdGE6IGZpbGVcclxuICAgICAgfSBhcyBaQ29tcG9uZW50T3V0cHV0RXZlbnQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2VsZWN0RXZlbnRIYW5kbGVyKGU6IFNlbGVjdEV2ZW50KSB7XHJcbiAgICBjb25zdCBtZSA9IHRoaXM7XHJcblxyXG4gICAgaWYgKHRoaXMuZGF0YVsnU2VsZWN0RmlsZU9ubHknXSkge1xyXG4gICAgICAvLyBhcHBlbmQgYWxsIGZpbGUgdG8gY29tcG9uZW50IG1lbW9yeVxyXG4gICAgICBlLmZpbGVzLmZvckVhY2goYXN5bmMgKGZpbGU6IEZpbGVJbmZvKSA9PiB7XHJcbiAgICAgICAgaWYgKGZpbGUucmF3RmlsZSkge1xyXG4gICAgICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcclxuICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoZXYpIHtcclxuICAgICAgICAgICAgLy8gY2xvbmUgdGhlIGRhdGEgYW5kIGFsc28gYWRkIHRoZSByZWFkZWQgZmlsZSB0byB0aGUgb2JqZWN0XHJcbiAgICAgICAgICAgIGNvbnN0IGZpbGVEYXRhID0gT2JqZWN0LmFzc2lnbih7fSwgZmlsZSk7XHJcbiAgICAgICAgICAgIGZpbGVEYXRhWydmaWxlJ10gPSBldi50YXJnZXRbXCJyZXN1bHRcIl07XHJcbiAgICAgICAgICAgIC8vIHB1c2ggdG8gY29tcG9uZW50IGZpbGVMaXN0XHJcbiAgICAgICAgICAgIG1lLmZpbGVMaXN0LnB1c2goZmlsZURhdGEpO1xyXG4gICAgICAgICAgICBtZS5ncm91cFsnenVwbG9hZF8nICsgbWUuZGF0YS5WYWx1ZV0gPSBtZS5maWxlTGlzdDtcclxuXHJcbiAgICAgICAgICAgIGlmIChtZS5kYXRhWydGaWxlU2VsZWN0ZWRFdmVudCddKSB7XHJcbiAgICAgICAgICAgICAgLy8gY2FsbCB0aGUgcHJvamVjdCBldmVudFxyXG4gICAgICAgICAgICAgIG1lLmdyb3VwLnN1YmplY3QubmV4dCh7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBcInp1cGxvYWQtZmlsZVNlbGVjdGVkRXZlbnRcIixcclxuICAgICAgICAgICAgICAgIHRhcmdldDogbWUuZGF0YVsnRmlsZVNlbGVjdGVkRXZlbnQnXSxcclxuICAgICAgICAgICAgICAgIGRhdGE6IG1lLmZpbGVMaXN0XHJcbiAgICAgICAgICAgICAgfSBhcyBaQ29tcG9uZW50T3V0cHV0RXZlbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9O1xyXG4gICAgICAgICAgYXdhaXQgcmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZS5yYXdGaWxlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIC8vIE9ubHkgd29ya2FibGUgZm9yIEF1dG8gVXBsb2FkID0gZmFsc2VcclxuICAgICAgaWYgKCF0aGlzLmRhdGEuQXV0b1VwbG9hZCkge1xyXG4gICAgICAgIC8vIENvbXByZXNzaW9uIGZvciBpbWFnZSBmaWxlXHJcbiAgICAgICAgY29uc3QgaW1hZ2VDb21wcmVzc2lvbkVuYWJsZWQgPSB0aGlzLmRhdGEuQ29tcHJlc3Npb24gPyB0cnVlIDogZmFsc2U7XHJcblxyXG4gICAgICAgIC8vQ2hlY2sgaWYgSW1hZ2UgQ29tcHJlc3Npb24gaXMgZW5hYmxlZC5cclxuICAgICAgICBpZiAoaW1hZ2VDb21wcmVzc2lvbkVuYWJsZWQgPT09IHRydWUpIHtcclxuICAgICAgICAgIGUuZmlsZXMuZm9yRWFjaCgoZmlsZTogRmlsZUluZm8pID0+IHtcclxuICAgICAgICAgICAgLy8gQ29tcHJlc3Mgb25seSBpZiBpdCBpcyBhbiBpbWFnZSBmaWxlXHJcbiAgICAgICAgICAgIGlmIChmaWxlLnJhd0ZpbGUgJiYgZmlsZS5yYXdGaWxlLnR5cGUuaW5jbHVkZXMoXCJpbWFnZVwiKSkge1xyXG4gICAgICAgICAgICAgIGlmICghZmlsZS52YWxpZGF0aW9uRXJyb3JzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpbWdDb25maWcgPSB0aGlzLmNvbXByZXNzaW9uQ29uZmlnSGFuZGxlcih0aGlzLmRhdGEuQ29tcHJlc3Npb24pO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IGltZ0NvbmZpZy5GaWxlU2l6ZU1pblNpemVCeXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgIG1lLmNvbXByZXNzSW1hZ2UuY29tcHJlc3MoZmlsZS5yYXdGaWxlLCBpbWdDb25maWcpICAvL1Bhc3MgaW4gcGFyYW1ldGVyIHRvIHNldCB0aGUgQ29tcHJlc3Npb24gT3B0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgIC5waXBlKHRha2UoMSkpXHJcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZShjb21wcmVzc0ZpbGUgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5yYXdGaWxlID0gY29tcHJlc3NGaWxlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnNpemUgPSBjb21wcmVzc0ZpbGUuc2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsb25lIHRoZSBkYXRhIGFuZCBhbHNvIGFkZCB0aGUgcmVhZGVkIGZpbGUgdG8gdGhlIG9iamVjdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWxlRGF0YSA9IE9iamVjdC5hc3NpZ24oe30sIGZpbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBwdXNoIHRvIGNvbXBvbmVudCBmaWxlTGlzdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZS5maWxlTGlzdC5wdXNoKGZpbGVEYXRhKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUucmF3RmlsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDb21wcmVzc2VkIGZpbGUgc2l6ZTogJHsoZmlsZS5yYXdGaWxlLnNpemUgLyAxMDI0KS50b0ZpeGVkKDIpfUtCYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9IC8vIGZpbGUgc2l6ZSBjaGVja1xyXG4gICAgICAgICAgICAgIH0gLy8gdmFsaWRhdGlvbkVycm9ycyBjaGVja1xyXG4gICAgICAgICAgICB9IC8vIGZpbGUgdHlwZSBjaGVja1xyXG4gICAgICAgICAgfSkgLy8gbG9vcCBlYWNoIGZpbGVcclxuICAgICAgICB9IC8vIGltYWdlY29tcHJlc3Npb24gY2hlY2tcclxuXHJcbiAgICAgICAgLy8gYWRkIHRvIGdyb3VwIHNjb3BlXHJcbiAgICAgICAgbWUuZ3JvdXBbJ3p1cGxvYWRfJyArIG1lLmRhdGEuVmFsdWVdID0gZS5maWxlcztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY2xlYXJGaWxlcygpIHtcclxuICAgIHRoaXMudXBsb2FkQ29tcG9uZW50LmNsZWFyRmlsZXMoKTtcclxuICAgIHRoaXMuZ3JvdXBbJ3p1cGxvYWRfJyArIHRoaXMuZGF0YS5WYWx1ZV0gPSB0aGlzLmZpbGVMaXN0O1xyXG4gIH1cclxufVxyXG4iLCI8aW9uLWl0ZW0gW2Zvcm1Hcm91cF09XCJmb3JtXCIgKm5nSWY9XCIoISFjb21wb25lbnRQcm9wZXJ0aWVzLmlzVmlzaWJsZUZpZWxkID8gZ3JvdXBbY29tcG9uZW50UHJvcGVydGllcy5pc1Zpc2libGVGaWVsZF0gOiBjb21wb25lbnRQcm9wZXJ0aWVzLmlzVmlzaWJsZSlcIiBbbmdDbGFzc109XCJnZXRJb25fSW52YWxpZENsYXNzKGZvcm0sIGRhdGEpXCIgc3R5bGU9XCJtYXJnaW4tbGVmdDogLTE1cHg7XCI+XHJcbiAgPGlvbi1sYWJlbCBbYXR0ci5mb3JdPVwiZGF0YS5WYWx1ZVwiICpuZ0lmPVwiZGF0YS5TaG93TGFiZWwgPT09IHVuZGVmaW5lZCB8fCBkYXRhLlNob3dMYWJlbFwiIHBvc2l0aW9uPVwic3RhY2tlZFwiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTBweDtcIj5cclxuICAgIHt7ZGF0YS5MYWJlbH19IDxpb24tdGV4dCAqbmdJZj1cIighIWNvbXBvbmVudFByb3BlcnRpZXMuaXNSZXF1aXJlZEZpZWxkID8gZ3JvdXBbY29tcG9uZW50UHJvcGVydGllcy5pc1JlcXVpcmVkRmllbGRdIDogY29tcG9uZW50UHJvcGVydGllcy5pc1JlcXVpcmVkKVwiIGNvbG9yPVwiZGFuZ2VyXCI+KjwvaW9uLXRleHQ+XHJcbiAgPC9pb24tbGFiZWw+XHJcbiAgPGRpdiBjbGFzcz1cImlvbi1yb3dcIiBzdHlsZT1cImp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2Vlbjsgd2lkdGg6IDEwMCVcIj5cclxuICAgIDxzcGFuIHN0eWxlPVwiZmxleDogMTtcIj5cclxuICAgICAgPGtlbmRvLXVwbG9hZCAjdXBsb2FkQ29tcG9uZW50XHJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCIhZGF0YS5TZWxlY3RGaWxlT25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2lkXT1cImRhdGEuVmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgIFthdXRvVXBsb2FkXT1cImlzQXV0b1VwbG9hZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3NhdmVVcmxdPVwidXBsb2FkU2F2ZVVybFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3JlbW92ZVVybF09XCJ1cGxvYWRSZW1vdmVVcmxcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtyZXN0cmljdGlvbnNdPVwicmVzdHJpY3Rpb25zXCJcclxuICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cImRhdGEuVmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgIFttdWx0aXBsZV09XCJpc011bHRpcGxlXCJcclxuICAgICAgICAgICAgICAgICAgICBbY2h1bmthYmxlXT1cImNodW5rU2V0dGluZ3NcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzaG93RmlsZUxpc3RdPVwic2hvd0ZpbGVMaXN0XCJcclxuICAgICAgICAgICAgICAgICAgICAoc2VsZWN0KT1cInNlbGVjdEV2ZW50SGFuZGxlcigkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAocmVtb3ZlKT1cIm9uUmVtb3ZlKCRldmVudClcIiBcclxuICAgICAgICAgICAgICAgICAgICAoc3VjY2Vzcyk9XCJvblN1Y2Nlc3MoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKHVwbG9hZCk9XCJ1cGxvYWRFdmVudEhhbmRsZXIoJGV2ZW50KVwiPlxyXG4gICAgICA8L2tlbmRvLXVwbG9hZD5cclxuXHJcbiAgICAgIDxrZW5kby1maWxlc2VsZWN0ICN1cGxvYWRDb21wb25lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkYXRhLlNlbGVjdEZpbGVPbmx5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW2lkXT1cImRhdGEuVmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoc2VsZWN0KT1cInNlbGVjdEV2ZW50SGFuZGxlcigkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKHJlbW92ZSk9XCJvblJlbW92ZSgkZXZlbnQpXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJvbkNoYW5nZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3Jlc3RyaWN0aW9uc109XCJyZXN0cmljdGlvbnNcIiA+XHJcbiAgICAgIDwva2VuZG8tZmlsZXNlbGVjdD5cclxuICAgIDwvc3Bhbj5cclxuICA8L2Rpdj5cclxuPC9pb24taXRlbT5cclxuPGJyIC8+XHJcbjwhLS08ZGl2IGNsYXNzPVwid3JhcFwiICpuZ0lmPVwiZGF0YS5FbmFibGVDb21wcmVzc2lvblwiPlxyXG4gIDxpb24tbGFiZWw+RW5hYmxlIENvbXByZXNzaW9uOiA8L2lvbi1sYWJlbD5cclxuICA8aW9uLWNoZWNrYm94IHN0eWxlPVwibWFyZ2luOiAtNXB4IDA7XCIgY29sb3I9XCJwcmltYXJ5XCIgKGlvbkNoYW5nZSk9XCJ0b29nbGVFbmFibGVDb21wcmVzc2lvbigkZXZlbnQpXCI+PC9pb24tY2hlY2tib3g+XHJcbjwvZGl2Pi0tPlxyXG48aW9uLWxhYmVsICpuZ0lmPVwiaW1hZ2VQcmV2aWV3cy5sZW5ndGhcIiBwb3NpdGlvbj1cInN0YWNrZWRcIj5cclxuICBJbWFnZSBQcmV2aWV3OlxyXG48L2lvbi1sYWJlbD5cclxuPGRpdiAqbmdJZj1cImltYWdlUHJldmlld3MubGVuZ3RoXCIgPlxyXG4gIDxpbWcgKm5nRm9yPVwibGV0IGltYWdlIG9mIGltYWdlUHJldmlld3NcIlxyXG4gICAgICAgW3NyY109XCJpbWFnZS5zcmNcIlxyXG4gICAgICAgYWx0PVwiaW1hZ2UgcHJldmlld1wiXHJcbiAgICAgICBoZWlnaHQ9XCIxMDBcIlxyXG4gICAgICAgc3R5bGU9XCJtYXJnaW46IDVweDsgYm9yZGVyOiAxcHggc29saWQgZ3JheTtcIi8+XHJcbjwvZGl2PlxyXG4iXX0=