@wizishop/img-manager 18.2.0-beta → 18.2.1-beta

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 (177) hide show
  1. package/esm2022/lib/components/canva-btn/canva-btn.component.mjs +73 -0
  2. package/esm2022/lib/components/images-view/images-actions-handler.mjs +168 -0
  3. package/esm2022/lib/components/images-view/images-view.component.mjs +391 -0
  4. package/esm2022/lib/components/images-view/mosaic-view/img-card/img-card.component.mjs +70 -0
  5. package/esm2022/lib/components/images-view/mosaic-view/mosaic-view.component.mjs +73 -0
  6. package/esm2022/lib/components/images-view/table-view/table-view.component.mjs +48 -0
  7. package/esm2022/lib/components/img-editor/cropper/cropper.component.mjs +313 -0
  8. package/esm2022/lib/components/img-editor/img-editor.component.mjs +129 -0
  9. package/esm2022/lib/components/img-editor/info-section/info-section.component.mjs +58 -0
  10. package/esm2022/lib/components/img-selection/img-selection.component.mjs +58 -0
  11. package/esm2022/lib/components/img-tabs/img-tabs.component.mjs +128 -0
  12. package/esm2022/lib/components/img-upload/img-upload.component.mjs +133 -0
  13. package/esm2022/lib/components/loader/loader.component.mjs +21 -0
  14. package/esm2022/lib/components/pexels-lib/pexels-lib.component.mjs +211 -0
  15. package/esm2022/lib/components/shared/alert/alert.component.mjs +26 -0
  16. package/esm2022/lib/components/shared/checkbox/checkbox.component.mjs +56 -0
  17. package/esm2022/lib/components/shared/dropdown/dropdown.component.mjs +21 -0
  18. package/esm2022/lib/components/shared/input-search/input-search.component.mjs +53 -0
  19. package/esm2022/lib/components/shared/pagination/page-selector/page-selector.component.mjs +50 -0
  20. package/esm2022/lib/components/shared/pagination/pagination.component.mjs +49 -0
  21. package/esm2022/lib/components/shared/select/select.component.mjs +117 -0
  22. package/esm2022/lib/components/shared/table/table.component.mjs +124 -0
  23. package/esm2022/lib/components/upload-list/upload-list.component.mjs +85 -0
  24. package/esm2022/lib/directives/abstract-debounce/abstract-debounce.directive.mjs +41 -0
  25. package/{esm2020 → esm2022}/lib/directives/abstract-debounce/debounce-keyup.directive.mjs +5 -5
  26. package/esm2022/lib/directives/auto-hide.directive.mjs +51 -0
  27. package/esm2022/lib/directives/copy-to-clipboard.directive.mjs +36 -0
  28. package/esm2022/lib/directives/drag-drop.directive.mjs +55 -0
  29. package/esm2022/lib/directives/loading.directive.mjs +43 -0
  30. package/esm2022/lib/directives/table/checkBoxRow.directive.mjs +130 -0
  31. package/esm2022/lib/directives/table/column.directive.mjs +50 -0
  32. package/esm2022/lib/directives/table/columnHeader.directive.mjs +215 -0
  33. package/esm2022/lib/directives/table/raw.directive.mjs +34 -0
  34. package/esm2022/lib/directives/zindex-toggle.directive.mjs +45 -0
  35. package/esm2022/lib/dto/canva-create-design.dto.mjs +9 -0
  36. package/esm2022/lib/dto/canva.dto.mjs +6 -0
  37. package/esm2022/lib/dto/config/apis/api.dto.mjs +11 -0
  38. package/esm2022/lib/dto/config/external/external-config.dto.mjs +5 -0
  39. package/esm2022/lib/dto/wizi-block-media.dto.mjs +7 -0
  40. package/esm2022/lib/pipes/images/img-src.pipe.mjs +29 -0
  41. package/{esm2020 → esm2022}/lib/pipes/number-to-array.pipe.mjs +4 -4
  42. package/esm2022/lib/pipes/pagination/array-total-pages/array-pages.pipe.mjs +28 -0
  43. package/esm2022/lib/pipes/pagination/large-number-of-page/large-number-of-page.pipe.mjs +53 -0
  44. package/esm2022/lib/pipes/pagination/text/custom-text.pipe.mjs +36 -0
  45. package/esm2022/lib/pipes/pagination/total-pages/is-last-page.pipe.mjs +25 -0
  46. package/{esm2020 → esm2022}/lib/pipes/select/select-filters.pipe.mjs +4 -4
  47. package/esm2022/lib/services/alert.service.mjs +53 -0
  48. package/{esm2020 → esm2022}/lib/services/api.service.mjs +4 -4
  49. package/esm2022/lib/services/canva.service.mjs +165 -0
  50. package/esm2022/lib/services/config/img-cdn.service.mjs +21 -0
  51. package/esm2022/lib/services/dom.service.mjs +31 -0
  52. package/{esm2020 → esm2022}/lib/services/icon.service.mjs +4 -4
  53. package/{esm2020 → esm2022}/lib/services/image-not-found.service.mjs +4 -4
  54. package/esm2022/lib/services/img-event.service.mjs +33 -0
  55. package/esm2022/lib/services/img-manager.service.mjs +134 -0
  56. package/esm2022/lib/services/img-selection.service.mjs +75 -0
  57. package/esm2022/lib/services/pexels.service.mjs +66 -0
  58. package/esm2022/lib/services/rename-picture.service.mjs +66 -0
  59. package/esm2022/lib/services/snackbar.service.mjs +67 -0
  60. package/esm2022/lib/services/table/filters-table.service.mjs +61 -0
  61. package/esm2022/lib/services/upload.service.mjs +20 -0
  62. package/esm2022/lib/services/user-settings.service.mjs +23 -0
  63. package/esm2022/lib/wz-img-manager.component.mjs +209 -0
  64. package/{esm2020 → esm2022}/lib/wz-img-manager.module.mjs +61 -61
  65. package/{fesm2020 → fesm2022}/wizishop-img-manager.mjs +1018 -830
  66. package/fesm2022/wizishop-img-manager.mjs.map +1 -0
  67. package/lib/components/canva-btn/canva-btn.component.d.ts +1 -1
  68. package/lib/components/images-view/images-actions-handler.d.ts +2 -1
  69. package/lib/components/images-view/images-view.component.d.ts +4 -9
  70. package/lib/components/images-view/mosaic-view/img-card/img-card.component.d.ts +1 -1
  71. package/lib/components/images-view/mosaic-view/mosaic-view.component.d.ts +1 -1
  72. package/lib/components/img-editor/cropper/cropper.component.d.ts +1 -1
  73. package/lib/components/img-editor/img-editor.component.d.ts +1 -1
  74. package/lib/components/img-editor/info-section/info-section.component.d.ts +1 -1
  75. package/lib/components/img-selection/img-selection.component.d.ts +4 -5
  76. package/lib/components/img-tabs/img-tabs.component.d.ts +1 -1
  77. package/lib/components/img-upload/img-upload.component.d.ts +1 -1
  78. package/lib/components/loader/loader.component.d.ts +1 -1
  79. package/lib/components/pexels-lib/pexels-lib.component.d.ts +1 -1
  80. package/lib/components/shared/alert/alert.component.d.ts +1 -1
  81. package/lib/components/shared/checkbox/checkbox.component.d.ts +1 -1
  82. package/lib/components/shared/dropdown/dropdown.component.d.ts +1 -1
  83. package/lib/components/shared/input-search/input-search.component.d.ts +1 -1
  84. package/lib/components/shared/pagination/page-selector/page-selector.component.d.ts +1 -1
  85. package/lib/components/shared/pagination/pagination.component.d.ts +1 -1
  86. package/lib/components/shared/select/select.component.d.ts +1 -1
  87. package/lib/components/shared/table/table.component.d.ts +1 -1
  88. package/lib/components/upload-list/upload-list.component.d.ts +1 -1
  89. package/lib/directives/abstract-debounce/abstract-debounce.directive.d.ts +1 -1
  90. package/lib/directives/auto-hide.directive.d.ts +1 -1
  91. package/lib/directives/copy-to-clipboard.directive.d.ts +1 -1
  92. package/lib/directives/table/checkBoxRow.directive.d.ts +1 -1
  93. package/lib/directives/table/column.directive.d.ts +1 -1
  94. package/lib/directives/table/columnHeader.directive.d.ts +1 -1
  95. package/lib/directives/zindex-toggle.directive.d.ts +1 -1
  96. package/lib/wz-img-manager.component.d.ts +3 -3
  97. package/package.json +7 -13
  98. package/wizishop-img-manager-18.2.1-beta.tgz +0 -0
  99. package/wz-img-manager.scss +20 -3
  100. package/esm2020/lib/components/canva-btn/canva-btn.component.mjs +0 -67
  101. package/esm2020/lib/components/images-view/images-actions-handler.mjs +0 -154
  102. package/esm2020/lib/components/images-view/images-view.component.mjs +0 -369
  103. package/esm2020/lib/components/images-view/mosaic-view/img-card/img-card.component.mjs +0 -66
  104. package/esm2020/lib/components/images-view/mosaic-view/mosaic-view.component.mjs +0 -71
  105. package/esm2020/lib/components/images-view/table-view/table-view.component.mjs +0 -48
  106. package/esm2020/lib/components/img-editor/cropper/cropper.component.mjs +0 -307
  107. package/esm2020/lib/components/img-editor/img-editor.component.mjs +0 -124
  108. package/esm2020/lib/components/img-editor/info-section/info-section.component.mjs +0 -54
  109. package/esm2020/lib/components/img-selection/img-selection.component.mjs +0 -53
  110. package/esm2020/lib/components/img-tabs/img-tabs.component.mjs +0 -122
  111. package/esm2020/lib/components/img-upload/img-upload.component.mjs +0 -126
  112. package/esm2020/lib/components/loader/loader.component.mjs +0 -21
  113. package/esm2020/lib/components/pexels-lib/pexels-lib.component.mjs +0 -203
  114. package/esm2020/lib/components/shared/alert/alert.component.mjs +0 -27
  115. package/esm2020/lib/components/shared/checkbox/checkbox.component.mjs +0 -52
  116. package/esm2020/lib/components/shared/dropdown/dropdown.component.mjs +0 -21
  117. package/esm2020/lib/components/shared/input-search/input-search.component.mjs +0 -54
  118. package/esm2020/lib/components/shared/pagination/page-selector/page-selector.component.mjs +0 -49
  119. package/esm2020/lib/components/shared/pagination/pagination.component.mjs +0 -49
  120. package/esm2020/lib/components/shared/select/select.component.mjs +0 -110
  121. package/esm2020/lib/components/shared/table/table.component.mjs +0 -116
  122. package/esm2020/lib/components/upload-list/upload-list.component.mjs +0 -79
  123. package/esm2020/lib/directives/abstract-debounce/abstract-debounce.directive.mjs +0 -37
  124. package/esm2020/lib/directives/auto-hide.directive.mjs +0 -48
  125. package/esm2020/lib/directives/copy-to-clipboard.directive.mjs +0 -37
  126. package/esm2020/lib/directives/drag-drop.directive.mjs +0 -57
  127. package/esm2020/lib/directives/loading.directive.mjs +0 -42
  128. package/esm2020/lib/directives/table/checkBoxRow.directive.mjs +0 -114
  129. package/esm2020/lib/directives/table/column.directive.mjs +0 -45
  130. package/esm2020/lib/directives/table/columnHeader.directive.mjs +0 -204
  131. package/esm2020/lib/directives/table/raw.directive.mjs +0 -31
  132. package/esm2020/lib/directives/zindex-toggle.directive.mjs +0 -42
  133. package/esm2020/lib/dto/canva-create-design.dto.mjs +0 -4
  134. package/esm2020/lib/dto/canva.dto.mjs +0 -4
  135. package/esm2020/lib/dto/config/apis/api.dto.mjs +0 -9
  136. package/esm2020/lib/dto/config/external/external-config.dto.mjs +0 -3
  137. package/esm2020/lib/dto/wizi-block-media.dto.mjs +0 -3
  138. package/esm2020/lib/pipes/images/img-src.pipe.mjs +0 -28
  139. package/esm2020/lib/pipes/pagination/array-total-pages/array-pages.pipe.mjs +0 -28
  140. package/esm2020/lib/pipes/pagination/large-number-of-page/large-number-of-page.pipe.mjs +0 -53
  141. package/esm2020/lib/pipes/pagination/text/custom-text.pipe.mjs +0 -35
  142. package/esm2020/lib/pipes/pagination/total-pages/is-last-page.pipe.mjs +0 -25
  143. package/esm2020/lib/services/alert.service.mjs +0 -50
  144. package/esm2020/lib/services/canva.service.mjs +0 -159
  145. package/esm2020/lib/services/config/img-cdn.service.mjs +0 -23
  146. package/esm2020/lib/services/dom.service.mjs +0 -33
  147. package/esm2020/lib/services/img-event.service.mjs +0 -35
  148. package/esm2020/lib/services/img-manager.service.mjs +0 -136
  149. package/esm2020/lib/services/img-selection.service.mjs +0 -76
  150. package/esm2020/lib/services/pexels.service.mjs +0 -62
  151. package/esm2020/lib/services/rename-picture.service.mjs +0 -63
  152. package/esm2020/lib/services/snackbar.service.mjs +0 -64
  153. package/esm2020/lib/services/table/filters-table.service.mjs +0 -60
  154. package/esm2020/lib/services/upload.service.mjs +0 -22
  155. package/esm2020/lib/services/user-settings.service.mjs +0 -25
  156. package/esm2020/lib/wz-img-manager.component.mjs +0 -192
  157. package/fesm2015/wizishop-img-manager.mjs +0 -4035
  158. package/fesm2015/wizishop-img-manager.mjs.map +0 -1
  159. package/fesm2020/wizishop-img-manager.mjs.map +0 -1
  160. package/wizishop-img-manager-18.2.0-beta.tgz +0 -0
  161. /package/{esm2020 → esm2022}/lib/animations/easeInOut/ease-in-out.animation.mjs +0 -0
  162. /package/{esm2020 → esm2022}/lib/animations/insertRemove/insert-remove.animation.mjs +0 -0
  163. /package/{esm2020 → esm2022}/lib/animations/listAnnimation/list.animation.mjs +0 -0
  164. /package/{esm2020 → esm2022}/lib/components/shared/select/call-to-action.model.mjs +0 -0
  165. /package/{esm2020 → esm2022}/lib/components/shared/select/select-items.dto.mjs +0 -0
  166. /package/{esm2020 → esm2022}/lib/dto/ImgManagerDisplayConfig.dto.mjs +0 -0
  167. /package/{esm2020 → esm2022}/lib/dto/config/image-cdn/image-cdn-config.dto.mjs +0 -0
  168. /package/{esm2020 → esm2022}/lib/dto/config/img-manager.mjs +0 -0
  169. /package/{esm2020 → esm2022}/lib/dto/export-dtos.api.mjs +0 -0
  170. /package/{esm2020 → esm2022}/lib/dto/img-editor-config.dto.mjs +0 -0
  171. /package/{esm2020 → esm2022}/lib/dto/img-manager.dto.mjs +0 -0
  172. /package/{esm2020 → esm2022}/lib/dto/pexels-img.dto.mjs +0 -0
  173. /package/{esm2020 → esm2022}/lib/dto/picture-name-update.dto.mjs +0 -0
  174. /package/{esm2020 → esm2022}/lib/dto/stateDisplayed.dto.mjs +0 -0
  175. /package/{esm2020 → esm2022}/lib/dto/tabDisplayed.dto.mjs +0 -0
  176. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
  177. /package/{esm2020 → esm2022}/wizishop-img-manager.mjs +0 -0
@@ -0,0 +1,313 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+ import { insertRemove } from '../../../animations/insertRemove/insert-remove.animation';
4
+ import { ImgCDNService } from '../../../services/config/img-cdn.service';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "../../../services/config/img-cdn.service";
7
+ import * as i2 from "@angular/common";
8
+ import * as i3 from "@wizishop/ng-wizi-bulma";
9
+ import * as i4 from "ngx-image-cropper";
10
+ import * as i5 from "../../shared/dropdown/dropdown.component";
11
+ import * as i6 from "@ngx-translate/core";
12
+ export class CropperComponent {
13
+ imgCDNService;
14
+ imgToEdit;
15
+ set isImgModified(isImgModified) {
16
+ this._isImgModified = isImgModified;
17
+ if (!isImgModified) {
18
+ this.restartEdit();
19
+ }
20
+ }
21
+ get isImgModified() {
22
+ return this._isImgModified;
23
+ }
24
+ _isImgModified = false;
25
+ isImgModifiedChange = new EventEmitter();
26
+ editClosed = new EventEmitter();
27
+ currentCroppedImageChange = new EventEmitter();
28
+ msgFailLoad = 'ImgManager.ImgEditor.msgFailLoad';
29
+ isNameModified = false;
30
+ isCropperReady = false; // Use to not display the crop validation btn, after the img is loaded or changed
31
+ currentCroppedImage = ''; // Img modified return in base64
32
+ isCropped = false;
33
+ isLoading = false;
34
+ _isImgCropped = false;
35
+ set isImgCropped(isImgCropped) {
36
+ setTimeout(() => {
37
+ this._isImgCropped = isImgCropped;
38
+ }, 0);
39
+ }
40
+ get isImgCropped() {
41
+ return this._isImgCropped;
42
+ }
43
+ imgCropperChange = new Subject();
44
+ skipNextImgCropped = 1;
45
+ // Image Cropper properties
46
+ imgType;
47
+ imgRoute;
48
+ imageChangedEvent = '';
49
+ croppedImage = '';
50
+ canvasRotation = 0;
51
+ rotation = 0;
52
+ scale = 1;
53
+ showCropper = false;
54
+ containWithinAspectRatio = false;
55
+ transform = {};
56
+ defaultAspectRatio;
57
+ // dropdown list
58
+ resolutionConfig = [
59
+ {
60
+ label: 'ImgManager.ImgEditor.config.origin',
61
+ config: {
62
+ maintainAspectRatio: true
63
+ },
64
+ },
65
+ {
66
+ label: 'ImgManager.ImgEditor.config.free',
67
+ config: {
68
+ maintainAspectRatio: false
69
+ },
70
+ active: true
71
+ },
72
+ {
73
+ label: 'ImgManager.ImgEditor.config.square',
74
+ config: {
75
+ maintainAspectRatio: true,
76
+ aspectRatio: 1 / 1
77
+ }
78
+ },
79
+ {
80
+ label: 'ImgManager.ImgEditor.config.Portrait',
81
+ config: {
82
+ maintainAspectRatio: true,
83
+ aspectRatio: 3 / 4
84
+ }
85
+ },
86
+ {
87
+ label: 'ImgManager.ImgEditor.config.landscape',
88
+ config: {
89
+ maintainAspectRatio: true,
90
+ aspectRatio: 5 / 3
91
+ }
92
+ }
93
+ ];
94
+ rotationConfig = [
95
+ {
96
+ label: 'ImgManager.ImgEditor.config.schedule',
97
+ icon: "fal fa-redo-alt",
98
+ method: "rotateRight",
99
+ active: true
100
+ },
101
+ {
102
+ label: 'ImgManager.ImgEditor.config.AntiSchedule',
103
+ icon: "fal fa-undo-alt",
104
+ method: "rotateLeft"
105
+ },
106
+ {
107
+ label: 'ImgManager.ImgEditor.config.flipVert',
108
+ icon: "fal fa-sort-alt",
109
+ method: "flipVertical"
110
+ },
111
+ {
112
+ label: 'ImgManager.ImgEditor.config.flipHoriz',
113
+ icon: "fal fa-exchange-alt",
114
+ method: "flipHorizontal"
115
+ }
116
+ ];
117
+ zoomConfig = [
118
+ {
119
+ label: 'ImgManager.ImgEditor.config.zoom',
120
+ icon: "fal fa-search-plus",
121
+ method: "zoomIn",
122
+ active: true
123
+ },
124
+ {
125
+ label: 'ImgManager.ImgEditor.config.dezoom',
126
+ icon: "fal fa-search-minus",
127
+ method: "zoomOut"
128
+ }
129
+ ];
130
+ // Img cropper variables
131
+ imgCropperConfig = {
132
+ maintainAspectRatio: false,
133
+ aspectRatio: undefined
134
+ };
135
+ constructor(imgCDNService) {
136
+ this.imgCDNService = imgCDNService;
137
+ }
138
+ ngOnInit() {
139
+ this.init();
140
+ this.detectImgCropperChange();
141
+ }
142
+ init() {
143
+ this.imgRoute = this.getRAWImgRoute();
144
+ this.imgType = this.getImgType();
145
+ this.croppedImage = null;
146
+ this.setDefautAspectRatio();
147
+ }
148
+ getRAWImgRoute() {
149
+ return this.imgCDNService.getUrlImg('raw') + this.imgToEdit.file_name;
150
+ }
151
+ getImgType() {
152
+ return (this.imgToEdit.file_name ? this.imgToEdit.file_name.split('.').pop() : undefined);
153
+ }
154
+ setDefautAspectRatio() {
155
+ const height = parseInt(this.imgToEdit.raw_height);
156
+ const width = parseInt(this.imgToEdit.raw_width);
157
+ this.defaultAspectRatio = height / width;
158
+ this.resolutionConfig[0].config.aspectRatio = this.defaultAspectRatio;
159
+ this.imgCropperConfig.aspectRatio = this.defaultAspectRatio;
160
+ }
161
+ onEditClosed(msgKey) {
162
+ this.editClosed.emit(msgKey);
163
+ }
164
+ onRestart() {
165
+ this.isImgModifiedChange.emit(false);
166
+ }
167
+ restartEdit() {
168
+ this.init();
169
+ this.resetConfCropper();
170
+ }
171
+ onImgModified() {
172
+ this.isImgModified = true;
173
+ this.isImgModifiedChange.emit(true);
174
+ }
175
+ ////// Img cropper methods ////////////////////////////////////////////////////////////////////////////////////////////////////////
176
+ /* Cropper output events */
177
+ fileChangeEvent(event) {
178
+ this.imageChangedEvent = event;
179
+ }
180
+ imageCropped(event) {
181
+ this.imgCropperChange.next();
182
+ this.currentCroppedImage = event.base64;
183
+ this.currentCroppedImageChange.emit(this.currentCroppedImage);
184
+ }
185
+ imageLoaded() {
186
+ this.showCropper = true;
187
+ }
188
+ cropperReady() {
189
+ this.isCropperReady = true;
190
+ }
191
+ loadImageFailed() {
192
+ this.onEditClosed(this.msgFailLoad);
193
+ }
194
+ /* Resize functions */
195
+ changeResolutionSize(index) {
196
+ this.setActiveItem(this.resolutionConfig, index);
197
+ const config = this.resolutionConfig[index].config;
198
+ this.setCropperProperties(config);
199
+ }
200
+ confirmCrop() {
201
+ setTimeout(() => {
202
+ this.imgRoute = null;
203
+ this.croppedImage = this.currentCroppedImage;
204
+ this.skipNextImgCropped = 2;
205
+ this.isImgCropped = false;
206
+ }, 0);
207
+ this.resetConfCropper();
208
+ this.onImgModified();
209
+ }
210
+ resetConfCropper() {
211
+ this.scale = 1;
212
+ this.rotation = 0;
213
+ this.canvasRotation = 0;
214
+ this.transform = {};
215
+ }
216
+ setActiveItem(array, index) {
217
+ // Set active-item class for the dropdown
218
+ array.forEach((item, indexItem) => {
219
+ item.active = indexItem === index ? true : false;
220
+ });
221
+ }
222
+ setCropperProperties(config) {
223
+ for (const property in config) {
224
+ this.imgCropperConfig[property] = config[property];
225
+ }
226
+ }
227
+ detectImgCropperChange() {
228
+ this.imgCropperChange
229
+ .subscribe(() => {
230
+ this.skipNextImgCropped--;
231
+ if (this.skipNextImgCropped >= 0) {
232
+ return;
233
+ }
234
+ this.skipNextImgCropped = 0;
235
+ this.isImgCropped = true;
236
+ });
237
+ }
238
+ /* Rotations functions */
239
+ rotateLeft() {
240
+ this.canvasRotation--;
241
+ this.flipAfterRotate();
242
+ this.onImgModified();
243
+ }
244
+ rotateRight() {
245
+ this.canvasRotation++;
246
+ this.flipAfterRotate();
247
+ this.onImgModified();
248
+ }
249
+ flipHorizontal() {
250
+ this.transform = {
251
+ ...this.transform,
252
+ flipH: !this.transform.flipH
253
+ };
254
+ this.onImgModified();
255
+ }
256
+ flipVertical() {
257
+ this.transform = {
258
+ ...this.transform,
259
+ flipV: !this.transform.flipV
260
+ };
261
+ this.onImgModified();
262
+ }
263
+ flipAfterRotate() {
264
+ const flippedH = this.transform.flipH;
265
+ const flippedV = this.transform.flipV;
266
+ this.transform = {
267
+ ...this.transform,
268
+ flipH: flippedV,
269
+ flipV: flippedH
270
+ };
271
+ }
272
+ /* Zoom functions */
273
+ zoomOut() {
274
+ this.scale -= this.scale < 0.2 ? 0 : .1;
275
+ this.transform = {
276
+ ...this.transform,
277
+ scale: this.scale
278
+ };
279
+ this.onImgModified();
280
+ }
281
+ zoomIn() {
282
+ this.scale += .1;
283
+ this.transform = {
284
+ ...this.transform,
285
+ scale: this.scale
286
+ };
287
+ this.onImgModified();
288
+ }
289
+ applyMethod(method) {
290
+ this[method](); // call the method contains in zoomConfig or rotationConfig
291
+ }
292
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: CropperComponent, deps: [{ token: i1.ImgCDNService }], target: i0.ɵɵFactoryTarget.Component });
293
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.5", type: CropperComponent, selector: "cropper", inputs: { imgToEdit: "imgToEdit", isImgModified: "isImgModified" }, outputs: { isImgModifiedChange: "isImgModifiedChange", editClosed: "editClosed", currentCroppedImageChange: "currentCroppedImageChange" }, ngImport: i0, template: "<div class=\"img-editor__container__toolsContainer\">\r\n\r\n <div *ngIf=\"isImgCropped\">\r\n <div\r\n class=\"img-editor__container__toolsContainer__tool img-editor__container__toolsContainer__tool--button\"\r\n (click)=\"confirmCrop()\"\r\n [nwbToolTip]=\"'ImgManager.ImgEditor.ValidtToolTip' | translate\"\r\n nwbToolTipPosition=\"left\"\r\n >\r\n <i class=\"far fa-check\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.Valid' | translate }}</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Resolution -->\r\n <dropdown dropdownId=\"dropdown-resolution\">\r\n <ng-container label>\r\n <div\r\n class=\"img-editor__container__toolsContainer__tool\"\r\n >\r\n <i class=\"far fa-crop\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.crop' | translate }}</p>\r\n </div>\r\n </ng-container>\r\n <ng-container item *ngFor=\"let item of resolutionConfig; let index = index;\">\r\n <div\r\n class=\"dropdown-item\"\r\n [ngClass]=\"{'active-item': item.active}\"\r\n (click)=\"changeResolutionSize(index)\">\r\n <p>{{item.label | translate}}</p>\r\n </div>\r\n </ng-container>\r\n </dropdown>\r\n\r\n <!-- Zoom -->\r\n <dropdown dropdownId=\"dropdown-rotation\">\r\n <ng-container label>\r\n <div class=\"img-editor__container__toolsContainer__tool\" (click)=\"zoomIn()\">\r\n <i class=\"far fa-expand-arrows-alt\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.display' | translate }}</p>\r\n </div>\r\n </ng-container>\r\n <ng-container item *ngFor=\"let item of zoomConfig; let index = index;\">\r\n <div\r\n class=\"dropdown-item\"\r\n [ngClass]=\"{'active-item': item.active}\"\r\n (click)=\"applyMethod(item.method)\">\r\n <i *ngIf=\"item.icon\" [ngClass]=\"item.icon\"></i>\r\n <p>{{item.label | translate}}</p>\r\n </div>\r\n </ng-container>\r\n </dropdown>\r\n\r\n <!-- Rotation -->\r\n <dropdown dropdownId=\"dropdown-rotation\" dropDownMenuClass=\"img-editor__container__toolsContainer__RotationDropdown\">\r\n <ng-container label>\r\n <div class=\"img-editor__container__toolsContainer__tool\" (click)=\"rotateRight()\">\r\n <i class=\"far fa-redo\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.rotation' | translate }}</p>\r\n </div>\r\n </ng-container>\r\n <ng-container item *ngFor=\"let item of rotationConfig; let index = index;\">\r\n <div\r\n class=\"dropdown-item\"\r\n [ngClass]=\"{'active-item': item.active}\"\r\n (click)=\"applyMethod(item.method)\">\r\n <i *ngIf=\"item.icon\" [ngClass]=\"item.icon\"></i>\r\n <p>{{item.label | translate}}</p>\r\n </div>\r\n </ng-container>\r\n </dropdown>\r\n\r\n <div\r\n class=\"img-editor__container__toolsContainer__tool\"\r\n (click)=\"onRestart()\"\r\n @insertRemoveAnnim\r\n >\r\n <i class=\"far fa-retweet-alt\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.restart' | translate }}</p>\r\n </div>\r\n</div>\r\n\r\n<div class=\"img-editor__image-cropper\" >\r\n <image-cropper\r\n [imageURL]=\"imgRoute\"\r\n [imageBase64]=\"croppedImage\"\r\n [maintainAspectRatio]=\"imgCropperConfig.maintainAspectRatio\"\r\n [containWithinAspectRatio]=\"containWithinAspectRatio\"\r\n [aspectRatio]=\"imgCropperConfig.aspectRatio\"\r\n [onlyScaleDown]=\"true\"\r\n [roundCropper]=\"false\"\r\n [canvasRotation]=\"canvasRotation\"\r\n [transform]=\"transform\"\r\n [alignImage]=\"'center'\"\r\n [style.display]=\"showCropper ? null : 'none'\"\r\n [format]=\"imgType\"\r\n [backgroundColor]=\"'white'\"\r\n (imageCropped)=\"imageCropped($event)\"\r\n (imageLoaded)=\"imageLoaded()\"\r\n (cropperReady)=\"cropperReady()\"\r\n (loadImageFailed)=\"loadImageFailed()\"\r\n ></image-cropper>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NwbToolTipDirective, selector: "[nwbToolTip]", inputs: ["nwbToolTip", "nwbToolTipPosition", "nwbToolTipIsMultiline"] }, { kind: "component", type: i4.ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "format", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "autoCrop", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "cropper", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange"] }, { kind: "component", type: i5.DropdownComponent, selector: "dropdown", inputs: ["dropDownMenuClass", "disable"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], animations: [
294
+ insertRemove
295
+ ] });
296
+ }
297
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: CropperComponent, decorators: [{
298
+ type: Component,
299
+ args: [{ selector: 'cropper', animations: [
300
+ insertRemove
301
+ ], template: "<div class=\"img-editor__container__toolsContainer\">\r\n\r\n <div *ngIf=\"isImgCropped\">\r\n <div\r\n class=\"img-editor__container__toolsContainer__tool img-editor__container__toolsContainer__tool--button\"\r\n (click)=\"confirmCrop()\"\r\n [nwbToolTip]=\"'ImgManager.ImgEditor.ValidtToolTip' | translate\"\r\n nwbToolTipPosition=\"left\"\r\n >\r\n <i class=\"far fa-check\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.Valid' | translate }}</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Resolution -->\r\n <dropdown dropdownId=\"dropdown-resolution\">\r\n <ng-container label>\r\n <div\r\n class=\"img-editor__container__toolsContainer__tool\"\r\n >\r\n <i class=\"far fa-crop\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.crop' | translate }}</p>\r\n </div>\r\n </ng-container>\r\n <ng-container item *ngFor=\"let item of resolutionConfig; let index = index;\">\r\n <div\r\n class=\"dropdown-item\"\r\n [ngClass]=\"{'active-item': item.active}\"\r\n (click)=\"changeResolutionSize(index)\">\r\n <p>{{item.label | translate}}</p>\r\n </div>\r\n </ng-container>\r\n </dropdown>\r\n\r\n <!-- Zoom -->\r\n <dropdown dropdownId=\"dropdown-rotation\">\r\n <ng-container label>\r\n <div class=\"img-editor__container__toolsContainer__tool\" (click)=\"zoomIn()\">\r\n <i class=\"far fa-expand-arrows-alt\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.display' | translate }}</p>\r\n </div>\r\n </ng-container>\r\n <ng-container item *ngFor=\"let item of zoomConfig; let index = index;\">\r\n <div\r\n class=\"dropdown-item\"\r\n [ngClass]=\"{'active-item': item.active}\"\r\n (click)=\"applyMethod(item.method)\">\r\n <i *ngIf=\"item.icon\" [ngClass]=\"item.icon\"></i>\r\n <p>{{item.label | translate}}</p>\r\n </div>\r\n </ng-container>\r\n </dropdown>\r\n\r\n <!-- Rotation -->\r\n <dropdown dropdownId=\"dropdown-rotation\" dropDownMenuClass=\"img-editor__container__toolsContainer__RotationDropdown\">\r\n <ng-container label>\r\n <div class=\"img-editor__container__toolsContainer__tool\" (click)=\"rotateRight()\">\r\n <i class=\"far fa-redo\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.rotation' | translate }}</p>\r\n </div>\r\n </ng-container>\r\n <ng-container item *ngFor=\"let item of rotationConfig; let index = index;\">\r\n <div\r\n class=\"dropdown-item\"\r\n [ngClass]=\"{'active-item': item.active}\"\r\n (click)=\"applyMethod(item.method)\">\r\n <i *ngIf=\"item.icon\" [ngClass]=\"item.icon\"></i>\r\n <p>{{item.label | translate}}</p>\r\n </div>\r\n </ng-container>\r\n </dropdown>\r\n\r\n <div\r\n class=\"img-editor__container__toolsContainer__tool\"\r\n (click)=\"onRestart()\"\r\n @insertRemoveAnnim\r\n >\r\n <i class=\"far fa-retweet-alt\"></i>\r\n <p>{{ 'ImgManager.ImgEditor.restart' | translate }}</p>\r\n </div>\r\n</div>\r\n\r\n<div class=\"img-editor__image-cropper\" >\r\n <image-cropper\r\n [imageURL]=\"imgRoute\"\r\n [imageBase64]=\"croppedImage\"\r\n [maintainAspectRatio]=\"imgCropperConfig.maintainAspectRatio\"\r\n [containWithinAspectRatio]=\"containWithinAspectRatio\"\r\n [aspectRatio]=\"imgCropperConfig.aspectRatio\"\r\n [onlyScaleDown]=\"true\"\r\n [roundCropper]=\"false\"\r\n [canvasRotation]=\"canvasRotation\"\r\n [transform]=\"transform\"\r\n [alignImage]=\"'center'\"\r\n [style.display]=\"showCropper ? null : 'none'\"\r\n [format]=\"imgType\"\r\n [backgroundColor]=\"'white'\"\r\n (imageCropped)=\"imageCropped($event)\"\r\n (imageLoaded)=\"imageLoaded()\"\r\n (cropperReady)=\"cropperReady()\"\r\n (loadImageFailed)=\"loadImageFailed()\"\r\n ></image-cropper>\r\n</div>\r\n" }]
302
+ }], ctorParameters: () => [{ type: i1.ImgCDNService }], propDecorators: { imgToEdit: [{
303
+ type: Input
304
+ }], isImgModified: [{
305
+ type: Input
306
+ }], isImgModifiedChange: [{
307
+ type: Output
308
+ }], editClosed: [{
309
+ type: Output
310
+ }], currentCroppedImageChange: [{
311
+ type: Output
312
+ }] } });
313
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JvcHBlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93ei1pbWctbWFuYWdlci9zcmMvbGliL2NvbXBvbmVudHMvaW1nLWVkaXRvci9jcm9wcGVyL2Nyb3BwZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvd3otaW1nLW1hbmFnZXIvc3JjL2xpYi9jb21wb25lbnRzL2ltZy1lZGl0b3IvY3JvcHBlci9jcm9wcGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFFMUYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMERBQTBELENBQUM7QUFHeEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBDQUEwQyxDQUFDOzs7Ozs7OztBQVN6RSxNQUFNLE9BQU8sZ0JBQWdCO0lBZ0pqQjtJQTdJVixTQUFTLENBQWdCO0lBRXpCLElBQ0ksYUFBYSxDQUFDLGFBQXNCO1FBQ3RDLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckIsQ0FBQztJQUNILENBQUM7SUFDRCxJQUFJLGFBQWE7UUFDZixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUNPLGNBQWMsR0FBWSxLQUFLLENBQUM7SUFHeEMsbUJBQW1CLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztJQUdsRCxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUdoQyx5QkFBeUIsR0FBRyxJQUFJLFlBQVksRUFBVSxD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O3VHQWhWVSxnQkFBZ0I7MkZBQWhCLGdCQUFnQiw4UENmN0IsNnRJQXVHQSxnNkNENUZjO1lBQ1YsWUFBWTtTQUNiOzsyRkFFVSxnQkFBZ0I7a0JBUDVCLFNBQVM7K0JBQ0UsU0FBUyxjQUVQO3dCQUNWLFlBQVk7cUJBQ2I7a0ZBS0QsU0FBUztzQkFEUixLQUFLO2dCQUlGLGFBQWE7c0JBRGhCLEtBQUs7Z0JBYU4sbUJBQW1CO3NCQURsQixNQUFNO2dCQUlQLFVBQVU7c0JBRFQsTUFBTTtnQkFJUCx5QkFBeUI7c0JBRHhCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgSW1hZ2VDcm9wcGVkRXZlbnQsIEltYWdlVHJhbnNmb3JtLCBPdXRwdXRGb3JtYXQgfSBmcm9tICduZ3gtaW1hZ2UtY3JvcHBlcic7XHJcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgaW5zZXJ0UmVtb3ZlIH0gZnJvbSAnLi4vLi4vLi4vYW5pbWF0aW9ucy9pbnNlcnRSZW1vdmUvaW5zZXJ0LXJlbW92ZS5hbmltYXRpb24nO1xyXG5pbXBvcnQgeyBDcm9wcGVyQ29uZmlnRFRPLCBJbWdDcm9wcGVyQ29uZmlnRFRPIH0gZnJvbSAnLi4vLi4vLi4vZHRvL2ltZy1lZGl0b3ItY29uZmlnLmR0byc7XHJcbmltcG9ydCB7IEltZ1BpY3R1cmVEVE8gfSBmcm9tICcuLi8uLi8uLi9kdG8vaW1nLW1hbmFnZXIuZHRvJztcclxuaW1wb3J0IHsgSW1nQ0ROU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2NvbmZpZy9pbWctY2RuLnNlcnZpY2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdjcm9wcGVyJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vY3JvcHBlci5jb21wb25lbnQuaHRtbCcsXHJcbiAgYW5pbWF0aW9uczogW1xyXG4gICAgaW5zZXJ0UmVtb3ZlXHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQ3JvcHBlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgaW1nVG9FZGl0OiBJbWdQaWN0dXJlRFRPO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHNldCBpc0ltZ01vZGlmaWVkKGlzSW1nTW9kaWZpZWQ6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuX2lzSW1nTW9kaWZpZWQgPSBpc0ltZ01vZGlmaWVkO1xyXG4gICAgaWYgKCFpc0ltZ01vZGlmaWVkKSB7XHJcbiAgICAgIHRoaXMucmVzdGFydEVkaXQoKTtcclxuICAgIH1cclxuICB9XHJcbiAgZ2V0IGlzSW1nTW9kaWZpZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5faXNJbWdNb2RpZmllZDtcclxuICB9XHJcbiAgcHJpdmF0ZSBfaXNJbWdNb2RpZmllZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBAT3V0cHV0KClcclxuICBpc0ltZ01vZGlmaWVkQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xyXG5cclxuICBAT3V0cHV0KClcclxuICBlZGl0Q2xvc2VkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICBAT3V0cHV0KClcclxuICBjdXJyZW50Q3JvcHBlZEltYWdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcblxyXG4gIG1zZ0ZhaWxMb2FkOiBzdHJpbmcgPSAnSW1nTWFuYWdlci5JbWdFZGl0b3IubXNnRmFpbExvYWQnO1xyXG5cclxuICBpc05hbWVNb2RpZmllZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGlzQ3JvcHBlclJlYWR5OiBib29sZWFuID0gZmFsc2U7IC8vIFVzZSB0byBub3QgZGlzcGxheSB0aGUgY3JvcCB2YWxpZGF0aW9uIGJ0biwgYWZ0ZXIgdGhlIGltZyBpcyBsb2FkZWQgb3IgY2hhbmdlZFxyXG4gIGN1cnJlbnRDcm9wcGVkSW1hZ2U6IHN0cmluZyA9ICcnOyAvLyBJbWcgbW9kaWZpZWQgcmV0dXJuIGluIGJhc2U2NFxyXG4gIGlzQ3JvcHBlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGlzTG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBfaXNJbWdDcm9wcGVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgc2V0IGlzSW1nQ3JvcHBlZChpc0ltZ0Nyb3BwZWQ6IGJvb2xlYW4pIHtcclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICB0aGlzLl9pc0ltZ0Nyb3BwZWQgPSBpc0ltZ0Nyb3BwZWQ7XHJcbiAgICB9LCAwKTtcclxuICB9XHJcblxyXG4gIGdldCBpc0ltZ0Nyb3BwZWQoKSA6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2lzSW1nQ3JvcHBlZDtcclxuICB9XHJcbiAgaW1nQ3JvcHBlckNoYW5nZTogU3ViamVjdDx2b2lkPiA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcbiAgc2tpcE5leHRJbWdDcm9wcGVkOiBudW1iZXIgPSAxO1xyXG5cclxuICAvLyBJbWFnZSBDcm9wcGVyIHByb3BlcnRpZXNcclxuICBpbWdUeXBlOiBPdXRwdXRGb3JtYXQ7XHJcbiAgaW1nUm91dGU6IHN0cmluZztcclxuICBpbWFnZUNoYW5nZWRFdmVudDogYW55ID0gJyc7XHJcbiAgY3JvcHBlZEltYWdlOiBhbnkgPSAnJztcclxuICBjYW52YXNSb3RhdGlvbiA9IDA7XHJcbiAgcm90YXRpb24gPSAwO1xyXG4gIHNjYWxlID0gMTtcclxuICBzaG93Q3JvcHBlciA9IGZhbHNlO1xyXG4gIGNvbnRhaW5XaXRoaW5Bc3BlY3RSYXRpbyA9IGZhbHNlO1xyXG4gIHRyYW5zZm9ybTogSW1hZ2VUcmFuc2Zvcm0gPSB7fTtcclxuXHJcbiAgZGVmYXVsdEFzcGVjdFJhdGlvOiBudW1iZXI7XHJcblxyXG4gIC8vIGRyb3Bkb3duIGxpc3RcclxuICByZXNvbHV0aW9uQ29uZmlnOkltZ0Nyb3BwZXJDb25maWdEVE9bXSA9IFtcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdJbWdNYW5hZ2VyLkltZ0VkaXRvci5jb25maWcub3JpZ2luJyxcclxuICAgICAgY29uZmlnOiB7XHJcbiAgICAgICAgbWFpbnRhaW5Bc3BlY3RSYXRpbzogdHJ1ZVxyXG4gICAgICB9LFxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdJbWdNYW5hZ2VyLkltZ0VkaXRvci5jb25maWcuZnJlZScsXHJcbiAgICAgIGNvbmZpZzoge1xyXG4gICAgICAgIG1haW50YWluQXNwZWN0UmF0aW86IGZhbHNlXHJcbiAgICAgIH0sXHJcbiAgICAgIGFjdGl2ZTogdHJ1ZVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdJbWdNYW5hZ2VyLkltZ0VkaXRvci5jb25maWcuc3F1YXJlJyxcclxuICAgICAgY29uZmlnOiB7XHJcbiAgICAgICAgbWFpbnRhaW5Bc3BlY3RSYXRpbzogdHJ1ZSxcclxuICAgICAgICBhc3BlY3RSYXRpbzogMSAvIDFcclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdJbWdNYW5hZ2VyLkltZ0VkaXRvci5jb25maWcuUG9ydHJhaXQnLFxyXG4gICAgICBjb25maWc6IHtcclxuICAgICAgICBtYWludGFpbkFzcGVjdFJhdGlvOiB0cnVlLFxyXG4gICAgICAgIGFzcGVjdFJhdGlvOiAzIC8gNFxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBsYWJlbDogJ0ltZ01hbmFnZXIuSW1nRWRpdG9yLmNvbmZpZy5sYW5kc2NhcGUnLFxyXG4gICAgICBjb25maWc6IHtcclxuICAgICAgICBtYWludGFpbkFzcGVjdFJhdGlvOiB0cnVlLFxyXG4gICAgICAgIGFzcGVjdFJhdGlvOiA1IC8gM1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgXTtcclxuXHJcbiAgcm90YXRpb25Db25maWc6SW1nQ3JvcHBlckNvbmZpZ0RUT1tdID0gW1xyXG4gICAge1xyXG4gICAgICBsYWJlbDogJ0ltZ01hbmFnZXIuSW1nRWRpdG9yLmNvbmZpZy5zY2hlZHVsZScsXHJcbiAgICAgIGljb246IFwiZmFsIGZhLXJlZG8tYWx0XCIsXHJcbiAgICAgIG1ldGhvZDogXCJyb3RhdGVSaWdodFwiLFxyXG4gICAgICBhY3RpdmU6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIGxhYmVsOiAnSW1nTWFuYWdlci5JbWdFZGl0b3IuY29uZmlnLkFudGlTY2hlZHVsZScsXHJcbiAgICAgIGljb246IFwiZmFsIGZhLXVuZG8tYWx0XCIsXHJcbiAgICAgIG1ldGhvZDogXCJyb3RhdGVMZWZ0XCJcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIGxhYmVsOiAnSW1nTWFuYWdlci5JbWdFZGl0b3IuY29uZmlnLmZsaXBWZXJ0JyxcclxuICAgICAgaWNvbjogXCJmYWwgZmEtc29ydC1hbHRcIixcclxuICAgICAgbWV0aG9kOiBcImZsaXBWZXJ0aWNhbFwiXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBsYWJlbDogJ0ltZ01hbmFnZXIuSW1nRWRpdG9yLmNvbmZpZy5mbGlwSG9yaXonLFxyXG4gICAgICBpY29uOiBcImZhbCBmYS1leGNoYW5nZS1hbHRcIixcclxuICAgICAgbWV0aG9kOiBcImZsaXBIb3Jpem9udGFsXCJcclxuICAgIH1cclxuICBdO1xyXG5cclxuICB6b29tQ29uZmlnOkltZ0Nyb3BwZXJDb25maWdEVE9bXSA9IFtcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdJbWdNYW5hZ2VyLkltZ0VkaXRvci5jb25maWcuem9vbScsXHJcbiAgICAgIGljb246IFwiZmFsIGZhLXNlYXJjaC1wbHVzXCIsXHJcbiAgICAgIG1ldGhvZDogXCJ6b29tSW5cIixcclxuICAgICAgYWN0aXZlOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBsYWJlbDogJ0ltZ01hbmFnZXIuSW1nRWRpdG9yLmNvbmZpZy5kZXpvb20nLFxyXG4gICAgICBpY29uOiBcImZhbCBmYS1zZWFyY2gtbWludXNcIixcclxuICAgICAgbWV0aG9kOiBcInpvb21PdXRcIlxyXG4gICAgfVxyXG4gIF07XHJcblxyXG4gIC8vIEltZyBjcm9wcGVyIHZhcmlhYmxlc1xyXG4gIGltZ0Nyb3BwZXJDb25maWc6Q3JvcHBlckNvbmZpZ0RUTyA9IHtcclxuICAgIG1haW50YWluQXNwZWN0UmF0aW86IGZhbHNlLFxyXG4gICAgYXNwZWN0UmF0aW86IHVuZGVmaW5lZFxyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGltZ0NETlNlcnZpY2U6IEltZ0NETlNlcnZpY2VcclxuICApIHsgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuaW5pdCgpO1xyXG4gICAgdGhpcy5kZXRlY3RJbWdDcm9wcGVyQ2hhbmdlKCk7XHJcbiAgfVxyXG5cclxuICBpbml0KCkge1xyXG4gICAgdGhpcy5pbWdSb3V0ZSA9IHRoaXMuZ2V0UkFXSW1nUm91dGUoKTtcclxuICAgIHRoaXMuaW1nVHlwZSA9IHRoaXMuZ2V0SW1nVHlwZSgpO1xyXG4gICAgdGhpcy5jcm9wcGVkSW1hZ2UgPSBudWxsO1xyXG4gICAgdGhpcy5zZXREZWZhdXRBc3BlY3RSYXRpbygpO1xyXG4gIH1cclxuXHJcbiAgZ2V0UkFXSW1nUm91dGUoKXtcclxuICAgIHJldHVybiB0aGlzLmltZ0NETlNlcnZpY2UuZ2V0VXJsSW1nKCdyYXcnKSArIHRoaXMuaW1nVG9FZGl0LmZpbGVfbmFtZTtcclxuICB9XHJcblxyXG4gIGdldEltZ1R5cGUoKSB7XHJcbiAgICByZXR1cm4gKHRoaXMuaW1nVG9FZGl0LmZpbGVfbmFtZSA/IHRoaXMuaW1nVG9FZGl0LmZpbGVfbmFtZS5zcGxpdCgnLicpLnBvcCgpIDogdW5kZWZpbmVkKSBhcyBPdXRwdXRGb3JtYXQ7XHJcbiAgfVxyXG5cclxuICBzZXREZWZhdXRBc3BlY3RSYXRpbygpIHtcclxuICAgIGNvbnN0IGhlaWdodCA9IHBhcnNlSW50KHRoaXMuaW1nVG9FZGl0LnJhd19oZWlnaHQpO1xyXG4gICAgY29uc3Qgd2lkdGggPSBwYXJzZUludCh0aGlzLmltZ1RvRWRpdC5yYXdfd2lkdGgpO1xyXG4gICAgdGhpcy5kZWZhdWx0QXNwZWN0UmF0aW8gPSBoZWlnaHQgLyB3aWR0aDtcclxuICAgIHRoaXMucmVzb2x1dGlvbkNvbmZpZ1swXS5jb25maWcuYXNwZWN0UmF0aW8gPSB0aGlzLmRlZmF1bHRBc3BlY3RSYXRpbztcclxuICAgIHRoaXMuaW1nQ3JvcHBlckNvbmZpZy5hc3BlY3RSYXRpbyA9IHRoaXMuZGVmYXVsdEFzcGVjdFJhdGlvO1xyXG4gIH1cclxuXHJcbiAgb25FZGl0Q2xvc2VkKG1zZ0tleT86IHN0cmluZykge1xyXG4gICAgdGhpcy5lZGl0Q2xvc2VkLmVtaXQobXNnS2V5KTtcclxuICB9XHJcblxyXG4gIG9uUmVzdGFydCgpIHtcclxuICAgIHRoaXMuaXNJbWdNb2RpZmllZENoYW5nZS5lbWl0KGZhbHNlKTtcclxuICB9XHJcblxyXG4gIHJlc3RhcnRFZGl0KCkge1xyXG4gICAgdGhpcy5pbml0KCk7XHJcbiAgICB0aGlzLnJlc2V0Q29uZkNyb3BwZXIoKTtcclxuICB9XHJcblxyXG4gIG9uSW1nTW9kaWZpZWQoKSB7XHJcbiAgICB0aGlzLmlzSW1nTW9kaWZpZWQgPSB0cnVlO1xyXG4gICAgdGhpcy5pc0ltZ01vZGlmaWVkQ2hhbmdlLmVtaXQodHJ1ZSk7XHJcbiAgfVxyXG5cclxuICAvLy8vLy8gSW1nIGNyb3BwZXIgbWV0aG9kcyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICAvKiBDcm9wcGVyIG91dHB1dCBldmVudHMgKi9cclxuXHJcbiAgZmlsZUNoYW5nZUV2ZW50KGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuaW1hZ2VDaGFuZ2VkRXZlbnQgPSBldmVudDtcclxuICB9XHJcblxyXG4gIGltYWdlQ3JvcHBlZChldmVudDogSW1hZ2VDcm9wcGVkRXZlbnQpIHtcclxuICAgIHRoaXMuaW1nQ3JvcHBlckNoYW5nZS5uZXh0KCk7XHJcblxyXG4gICAgdGhpcy5jdXJyZW50Q3JvcHBlZEltYWdlID0gZXZlbnQuYmFzZTY0O1xyXG4gICAgdGhpcy5jdXJyZW50Q3JvcHBlZEltYWdlQ2hhbmdlLmVtaXQodGhpcy5jdXJyZW50Q3JvcHBlZEltYWdlKTtcclxuICB9XHJcblxyXG4gIGltYWdlTG9hZGVkKCkge1xyXG4gICAgdGhpcy5zaG93Q3JvcHBlciA9IHRydWU7XHJcbiAgfVxyXG5cclxuICBjcm9wcGVyUmVhZHkoKSB7XHJcbiAgICB0aGlzLmlzQ3JvcHBlclJlYWR5ID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIGxvYWRJbWFnZUZhaWxlZCgpIHtcclxuICAgIHRoaXMub25FZGl0Q2xvc2VkKHRoaXMubXNnRmFpbExvYWQpO1xyXG4gIH1cclxuXHJcbiAgLyogUmVzaXplIGZ1bmN0aW9ucyAqL1xyXG5cclxuICBjaGFuZ2VSZXNvbHV0aW9uU2l6ZShpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnNldEFjdGl2ZUl0ZW0odGhpcy5yZXNvbHV0aW9uQ29uZmlnLCBpbmRleCk7XHJcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLnJlc29sdXRpb25Db25maWdbaW5kZXhdLmNvbmZpZztcclxuICAgIHRoaXMuc2V0Q3JvcHBlclByb3BlcnRpZXMoY29uZmlnKTtcclxuICB9XHJcblxyXG4gIGNvbmZpcm1Dcm9wKCkge1xyXG5cclxuICAgIHNldFRpbWVvdXQoKCkgPT4geyAvLyBBdm9pZCBpbWFnZS1jcm9wcGVyIGVycm9yXHJcbiAgICAgIHRoaXMuaW1nUm91dGUgPSBudWxsO1xyXG4gICAgICB0aGlzLmNyb3BwZWRJbWFnZSA9IHRoaXMuY3VycmVudENyb3BwZWRJbWFnZTtcclxuICAgICAgdGhpcy5za2lwTmV4dEltZ0Nyb3BwZWQgPSAyO1xyXG4gICAgICB0aGlzLmlzSW1nQ3JvcHBlZCA9IGZhbHNlO1xyXG4gICAgfSwgMCk7XHJcblxyXG4gICAgdGhpcy5yZXNldENvbmZDcm9wcGVyKCk7XHJcbiAgICB0aGlzLm9uSW1nTW9kaWZpZWQoKTtcclxuICB9XHJcblxyXG4gIHJlc2V0Q29uZkNyb3BwZXIoKSB7XHJcbiAgICB0aGlzLnNjYWxlID0gMTtcclxuICAgIHRoaXMucm90YXRpb24gPSAwO1xyXG4gICAgdGhpcy5jYW52YXNSb3RhdGlvbiA9IDA7XHJcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHt9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZXRBY3RpdmVJdGVtKGFycmF5OmFueVtdLCBpbmRleDogbnVtYmVyKSB7XHJcbiAgICAvLyBTZXQgYWN0aXZlLWl0ZW0gY2xhc3MgZm9yIHRoZSBkcm9wZG93blxyXG4gICAgYXJyYXkuZm9yRWFjaCgoaXRlbSwgaW5kZXhJdGVtKSA9PiB7XHJcbiAgICAgIGl0ZW0uYWN0aXZlID0gaW5kZXhJdGVtID09PSBpbmRleCA/IHRydWUgOiBmYWxzZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZXRDcm9wcGVyUHJvcGVydGllcyhjb25maWc6IGFueSkge1xyXG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBjb25maWcpIHtcclxuICAgICAgdGhpcy5pbWdDcm9wcGVyQ29uZmlnW3Byb3BlcnR5XSA9IGNvbmZpZ1twcm9wZXJ0eV07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRldGVjdEltZ0Nyb3BwZXJDaGFuZ2UoKSB7XHJcbiAgICB0aGlzLmltZ0Nyb3BwZXJDaGFuZ2VcclxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5za2lwTmV4dEltZ0Nyb3BwZWQtLTtcclxuICAgICAgICBpZiAodGhpcy5za2lwTmV4dEltZ0Nyb3BwZWQgPj0gMCkge1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNraXBOZXh0SW1nQ3JvcHBlZCA9IDA7XHJcbiAgICAgICAgdGhpcy5pc0ltZ0Nyb3BwZWQgPSB0cnVlO1xyXG4gICAgfSlcclxuXHJcbiAgfVxyXG5cclxuICAvKiBSb3RhdGlvbnMgZnVuY3Rpb25zICovXHJcblxyXG4gIHJvdGF0ZUxlZnQoKSB7XHJcbiAgICAgIHRoaXMuY2FudmFzUm90YXRpb24tLTtcclxuICAgICAgdGhpcy5mbGlwQWZ0ZXJSb3RhdGUoKTtcclxuICAgICAgdGhpcy5vbkltZ01vZGlmaWVkKCk7XHJcbiAgfVxyXG5cclxuICByb3RhdGVSaWdodCgpIHtcclxuICAgICAgdGhpcy5jYW52YXNSb3RhdGlvbisrO1xyXG4gICAgICB0aGlzLmZsaXBBZnRlclJvdGF0ZSgpO1xyXG4gICAgICB0aGlzLm9uSW1nTW9kaWZpZWQoKTtcclxuICB9XHJcblxyXG4gIGZsaXBIb3Jpem9udGFsKCkge1xyXG4gICAgICB0aGlzLnRyYW5zZm9ybSA9IHtcclxuICAgICAgICAgIC4uLnRoaXMudHJhbnNmb3JtLFxyXG4gICAgICAgICAgZmxpcEg6ICF0aGlzLnRyYW5zZm9ybS5mbGlwSFxyXG4gICAgICB9O1xyXG4gICAgICB0aGlzLm9uSW1nTW9kaWZpZWQoKTtcclxuICB9XHJcblxyXG4gIGZsaXBWZXJ0aWNhbCgpIHtcclxuICAgICAgdGhpcy50cmFuc2Zvcm0gPSB7XHJcbiAgICAgICAgICAuLi50aGlzLnRyYW5zZm9ybSxcclxuICAgICAgICAgIGZsaXBWOiAhdGhpcy50cmFuc2Zvcm0uZmxpcFZcclxuICAgICAgfTtcclxuICAgICAgdGhpcy5vbkltZ01vZGlmaWVkKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZsaXBBZnRlclJvdGF0ZSgpIHtcclxuICAgIGNvbnN0IGZsaXBwZWRIID0gdGhpcy50cmFuc2Zvcm0uZmxpcEg7XHJcbiAgICBjb25zdCBmbGlwcGVkViA9IHRoaXMudHJhbnNmb3JtLmZsaXBWO1xyXG4gICAgdGhpcy50cmFuc2Zvcm0gPSB7XHJcbiAgICAgICAgLi4udGhpcy50cmFuc2Zvcm0sXHJcbiAgICAgICAgZmxpcEg6IGZsaXBwZWRWLFxyXG4gICAgICAgIGZsaXBWOiBmbGlwcGVkSFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qIFpvb20gZnVuY3Rpb25zICovXHJcblxyXG4gIHpvb21PdXQoKSB7XHJcbiAgICAgIHRoaXMuc2NhbGUgLT0gIHRoaXMuc2NhbGUgPCAwLjI/IDAgOiAuMTtcclxuICAgICAgdGhpcy50cmFuc2Zvcm0gPSB7XHJcbiAgICAgICAgICAuLi50aGlzLnRyYW5zZm9ybSxcclxuICAgICAgICAgIHNjYWxlOiB0aGlzLnNjYWxlXHJcbiAgICAgIH07XHJcbiAgICAgIHRoaXMub25JbWdNb2RpZmllZCgpO1xyXG4gIH1cclxuXHJcbiAgem9vbUluKCkge1xyXG4gICAgICB0aGlzLnNjYWxlICs9IC4xO1xyXG4gICAgICB0aGlzLnRyYW5zZm9ybSA9IHtcclxuICAgICAgICAgIC4uLnRoaXMudHJhbnNmb3JtLFxyXG4gICAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGVcclxuICAgICAgfTtcclxuICAgICAgdGhpcy5vbkltZ01vZGlmaWVkKCk7XHJcbiAgfVxyXG5cclxuICBhcHBseU1ldGhvZChtZXRob2Q6IHN0cmluZykge1xyXG4gICAgdGhpc1ttZXRob2RdKCk7IC8vIGNhbGwgdGhlIG1ldGhvZCBjb250YWlucyBpbiB6b29tQ29uZmlnIG9yIHJvdGF0aW9uQ29uZmlnXHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJpbWctZWRpdG9yX19jb250YWluZXJfX3Rvb2xzQ29udGFpbmVyXCI+XHJcblxyXG4gICAgPGRpdiAqbmdJZj1cImlzSW1nQ3JvcHBlZFwiPlxyXG4gICAgICAgIDxkaXZcclxuICAgICAgICAgIGNsYXNzPVwiaW1nLWVkaXRvcl9fY29udGFpbmVyX190b29sc0NvbnRhaW5lcl9fdG9vbCBpbWctZWRpdG9yX19jb250YWluZXJfX3Rvb2xzQ29udGFpbmVyX190b29sLS1idXR0b25cIlxyXG4gICAgICAgICAgKGNsaWNrKT1cImNvbmZpcm1Dcm9wKClcIlxyXG4gICAgICAgICAgW253YlRvb2xUaXBdPVwiJ0ltZ01hbmFnZXIuSW1nRWRpdG9yLlZhbGlkdFRvb2xUaXAnIHwgdHJhbnNsYXRlXCJcclxuICAgICAgICAgIG53YlRvb2xUaXBQb3NpdGlvbj1cImxlZnRcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXIgZmEtY2hlY2tcIj48L2k+XHJcbiAgICAgICAgICAgIDxwPnt7ICdJbWdNYW5hZ2VyLkltZ0VkaXRvci5WYWxpZCcgfCB0cmFuc2xhdGUgfX08L3A+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tIFJlc29sdXRpb24gLS0+XHJcbiAgICA8ZHJvcGRvd24gZHJvcGRvd25JZD1cImRyb3Bkb3duLXJlc29sdXRpb25cIj5cclxuICAgICAgICA8bmctY29udGFpbmVyIGxhYmVsPlxyXG4gICAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgICAgY2xhc3M9XCJpbWctZWRpdG9yX19jb250YWluZXJfX3Rvb2xzQ29udGFpbmVyX190b29sXCJcclxuICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXIgZmEtY3JvcFwiPjwvaT5cclxuICAgICAgICAgICAgICAgIDxwPnt7ICdJbWdNYW5hZ2VyLkltZ0VkaXRvci5jcm9wJyB8IHRyYW5zbGF0ZSB9fTwvcD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciBpdGVtICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJlc29sdXRpb25Db25maWc7IGxldCBpbmRleCA9IGluZGV4O1wiPlxyXG4gICAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImRyb3Bkb3duLWl0ZW1cIlxyXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydhY3RpdmUtaXRlbSc6IGl0ZW0uYWN0aXZlfVwiXHJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2hhbmdlUmVzb2x1dGlvblNpemUoaW5kZXgpXCI+XHJcbiAgICAgICAgICAgICAgICA8cD57e2l0ZW0ubGFiZWwgfCB0cmFuc2xhdGV9fTwvcD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8L2Ryb3Bkb3duPlxyXG5cclxuICAgIDwhLS0gWm9vbSAtLT5cclxuICAgIDxkcm9wZG93biBkcm9wZG93bklkPVwiZHJvcGRvd24tcm90YXRpb25cIj5cclxuICAgICAgICA8bmctY29udGFpbmVyIGxhYmVsPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW1nLWVkaXRvcl9fY29udGFpbmVyX190b29sc0NvbnRhaW5lcl9fdG9vbFwiIChjbGljayk9XCJ6b29tSW4oKVwiPlxyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXIgZmEtZXhwYW5kLWFycm93cy1hbHRcIj48L2k+XHJcbiAgICAgICAgICAgICAgICA8cD57eyAnSW1nTWFuYWdlci5JbWdFZGl0b3IuZGlzcGxheScgfCB0cmFuc2xhdGUgfX08L3A+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgaXRlbSAqbmdGb3I9XCJsZXQgaXRlbSBvZiB6b29tQ29uZmlnOyBsZXQgaW5kZXggPSBpbmRleDtcIj5cclxuICAgICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiXHJcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydhY3RpdmUtaXRlbSc6IGl0ZW0uYWN0aXZlfVwiXHJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImFwcGx5TWV0aG9kKGl0ZW0ubWV0aG9kKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxpICpuZ0lmPVwiaXRlbS5pY29uXCIgW25nQ2xhc3NdPVwiaXRlbS5pY29uXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgIDxwPnt7aXRlbS5sYWJlbCB8IHRyYW5zbGF0ZX19PC9wPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvZHJvcGRvd24+XHJcblxyXG4gICAgPCEtLSBSb3RhdGlvbiAtLT5cclxuICAgIDxkcm9wZG93biBkcm9wZG93bklkPVwiZHJvcGRvd24tcm90YXRpb25cIiBkcm9wRG93bk1lbnVDbGFzcz1cImltZy1lZGl0b3JfX2NvbnRhaW5lcl9fdG9vbHNDb250YWluZXJfX1JvdGF0aW9uRHJvcGRvd25cIj5cclxuICAgICAgICA8bmctY29udGFpbmVyIGxhYmVsPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW1nLWVkaXRvcl9fY29udGFpbmVyX190b29sc0NvbnRhaW5lcl9fdG9vbFwiIChjbGljayk9XCJyb3RhdGVSaWdodCgpXCI+XHJcbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhciBmYS1yZWRvXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgPHA+e3sgJ0ltZ01hbmFnZXIuSW1nRWRpdG9yLnJvdGF0aW9uJyB8IHRyYW5zbGF0ZSB9fTwvcD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciBpdGVtICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJvdGF0aW9uQ29uZmlnOyBsZXQgaW5kZXggPSBpbmRleDtcIj5cclxuICAgICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiXHJcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydhY3RpdmUtaXRlbSc6IGl0ZW0uYWN0aXZlfVwiXHJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImFwcGx5TWV0aG9kKGl0ZW0ubWV0aG9kKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxpICpuZ0lmPVwiaXRlbS5pY29uXCIgW25nQ2xhc3NdPVwiaXRlbS5pY29uXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgIDxwPnt7aXRlbS5sYWJlbCB8IHRyYW5zbGF0ZX19PC9wPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvZHJvcGRvd24+XHJcblxyXG4gICAgPGRpdlxyXG4gICAgICAgIGNsYXNzPVwiaW1nLWVkaXRvcl9fY29udGFpbmVyX190b29sc0NvbnRhaW5lcl9fdG9vbFwiXHJcbiAgICAgICAgKGNsaWNrKT1cIm9uUmVzdGFydCgpXCJcclxuICAgICAgICBAaW5zZXJ0UmVtb3ZlQW5uaW1cclxuICAgID5cclxuICAgICAgICA8aSBjbGFzcz1cImZhciBmYS1yZXR3ZWV0LWFsdFwiPjwvaT5cclxuICAgICAgICA8cD57eyAnSW1nTWFuYWdlci5JbWdFZGl0b3IucmVzdGFydCcgfCB0cmFuc2xhdGUgfX08L3A+XHJcbiAgICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG48ZGl2IGNsYXNzPVwiaW1nLWVkaXRvcl9faW1hZ2UtY3JvcHBlclwiID5cclxuICAgIDxpbWFnZS1jcm9wcGVyXHJcbiAgICAgICAgW2ltYWdlVVJMXT1cImltZ1JvdXRlXCJcclxuICAgICAgICBbaW1hZ2VCYXNlNjRdPVwiY3JvcHBlZEltYWdlXCJcclxuICAgICAgICBbbWFpbnRhaW5Bc3BlY3RSYXRpb109XCJpbWdDcm9wcGVyQ29uZmlnLm1haW50YWluQXNwZWN0UmF0aW9cIlxyXG4gICAgICAgIFtjb250YWluV2l0aGluQXNwZWN0UmF0aW9dPVwiY29udGFpbldpdGhpbkFzcGVjdFJhdGlvXCJcclxuICAgICAgICBbYXNwZWN0UmF0aW9dPVwiaW1nQ3JvcHBlckNvbmZpZy5hc3BlY3RSYXRpb1wiXHJcbiAgICAgICAgW29ubHlTY2FsZURvd25dPVwidHJ1ZVwiXHJcbiAgICAgICAgW3JvdW5kQ3JvcHBlcl09XCJmYWxzZVwiXHJcbiAgICAgICAgW2NhbnZhc1JvdGF0aW9uXT1cImNhbnZhc1JvdGF0aW9uXCJcclxuICAgICAgICBbdHJhbnNmb3JtXT1cInRyYW5zZm9ybVwiXHJcbiAgICAgICAgW2FsaWduSW1hZ2VdPVwiJ2NlbnRlcidcIlxyXG4gICAgICAgIFtzdHlsZS5kaXNwbGF5XT1cInNob3dDcm9wcGVyID8gbnVsbCA6ICdub25lJ1wiXHJcbiAgICAgICAgW2Zvcm1hdF09XCJpbWdUeXBlXCJcclxuICAgICAgICBbYmFja2dyb3VuZENvbG9yXT1cIid3aGl0ZSdcIlxyXG4gICAgICAgIChpbWFnZUNyb3BwZWQpPVwiaW1hZ2VDcm9wcGVkKCRldmVudClcIlxyXG4gICAgICAgIChpbWFnZUxvYWRlZCk9XCJpbWFnZUxvYWRlZCgpXCJcclxuICAgICAgICAoY3JvcHBlclJlYWR5KT1cImNyb3BwZXJSZWFkeSgpXCJcclxuICAgICAgICAobG9hZEltYWdlRmFpbGVkKT1cImxvYWRJbWFnZUZhaWxlZCgpXCJcclxuICAgID48L2ltYWdlLWNyb3BwZXI+XHJcbjwvZGl2PlxyXG4iXX0=
@@ -0,0 +1,129 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { ImgManagerService } from '../../services/img-manager.service';
3
+ import { easeInOut } from '../../animations/easeInOut/ease-in-out.animation';
4
+ import { RenamePictureService } from '../../services/rename-picture.service';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "../../services/img-manager.service";
7
+ import * as i2 from "../../services/rename-picture.service";
8
+ import * as i3 from "@angular/common";
9
+ import * as i4 from "ngx-scrollbar";
10
+ import * as i5 from "./info-section/info-section.component";
11
+ import * as i6 from "./cropper/cropper.component";
12
+ import * as i7 from "../../directives/loading.directive";
13
+ import * as i8 from "@ngx-translate/core";
14
+ export class ImgEditorComponent {
15
+ imgManagerService;
16
+ renamePictureService;
17
+ stateDisplayed;
18
+ imgToEdit;
19
+ editClosed = new EventEmitter();
20
+ isLoading = false;
21
+ isImgModified = false;
22
+ isNameModified = false;
23
+ currentCroppedImage = ''; // Img modified return in base64 by the cropper
24
+ previousName;
25
+ msgFailSave = 'ImgManager.ImgEditor.msgFailSave';
26
+ msgFailLoad = 'ImgManager.ImgEditor.msgFailLoad';
27
+ msgSuccessEdit = "Les modifications de l'image ont bien été enregistrées.";
28
+ constructor(imgManagerService, renamePictureService) {
29
+ this.imgManagerService = imgManagerService;
30
+ this.renamePictureService = renamePictureService;
31
+ }
32
+ ngOnInit() {
33
+ this.previousName = this.imgToEdit.display_name;
34
+ }
35
+ onSave() {
36
+ if (this.isLoading) {
37
+ return;
38
+ }
39
+ this.isLoading = true;
40
+ if (!this.isImgModified && !this.isNameModified) {
41
+ this.isLoading = false;
42
+ this.onEditClosed();
43
+ }
44
+ const obsReplaceImg = this.imgManagerService.replaceImg(this.currentCroppedImage, this.imgToEdit.id_file);
45
+ const obsChangeImgName = this.renamePictureService.changeImageName(this.imgToEdit.display_name, this.imgToEdit.id_file);
46
+ if (this.isImgModified && this.isNameModified) {
47
+ this.renameAndReplaceImg(obsChangeImgName, obsReplaceImg);
48
+ return;
49
+ }
50
+ if (this.isImgModified) {
51
+ obsReplaceImg.subscribe({
52
+ next: data => {
53
+ this.isLoading = false;
54
+ this.onEditClosed(this.msgSuccessEdit);
55
+ },
56
+ error: error => {
57
+ this.isLoading = false;
58
+ this.currentCroppedImage = '';
59
+ this.onEditClosed(this.msgFailSave);
60
+ }
61
+ });
62
+ return;
63
+ }
64
+ if (this.isNameModified) {
65
+ obsChangeImgName.subscribe({
66
+ next: data => {
67
+ this.isLoading = false;
68
+ this.previousName = this.imgToEdit.display_name;
69
+ this.onEditClosed(this.msgSuccessEdit);
70
+ },
71
+ error: error => {
72
+ this.isLoading = false;
73
+ this.imgToEdit.display_name = this.previousName;
74
+ this.onEditClosed(this.msgFailSave);
75
+ }
76
+ });
77
+ }
78
+ this.isNameModified = false;
79
+ }
80
+ onEditClosed(msgKey) {
81
+ this.editClosed.emit(msgKey);
82
+ }
83
+ onRestartEdit() {
84
+ this.isImgModified = false;
85
+ this.isNameModified = false;
86
+ this.imgToEdit.display_name = this.previousName;
87
+ }
88
+ onCancel() {
89
+ this.onEditClosed('');
90
+ }
91
+ onImgCropped(imgBase64) {
92
+ this.currentCroppedImage = imgBase64;
93
+ }
94
+ renameAndReplaceImg(obsChangeImgName, obsReplaceImg) {
95
+ // Avoid to use forkjoin, because it can create conflict and loose the img
96
+ obsChangeImgName.subscribe({
97
+ next: res1 => {
98
+ obsReplaceImg.subscribe({
99
+ next: res2 => {
100
+ this.onEditClosed(this.msgSuccessEdit);
101
+ },
102
+ error: error => {
103
+ this.onEditClosed(this.msgFailSave);
104
+ }
105
+ });
106
+ },
107
+ error: error => {
108
+ this.onEditClosed(this.msgFailSave);
109
+ }
110
+ });
111
+ }
112
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: ImgEditorComponent, deps: [{ token: i1.ImgManagerService }, { token: i2.RenamePictureService }], target: i0.ɵɵFactoryTarget.Component });
113
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.5", type: ImgEditorComponent, selector: "img-editor", inputs: { stateDisplayed: "stateDisplayed", imgToEdit: "imgToEdit" }, outputs: { editClosed: "editClosed" }, ngImport: i0, template: "<div class=\"img-editor\" [@easeInOut]=\"'in'\">\r\n\r\n <!-- Button Action Section -->\r\n\r\n <div class=\"img-editor__infoSection__actions\">\r\n <div>\r\n <button\r\n type=\"button\"\r\n class=\"button img-editor__infoSection__actions__cancel\"\r\n (click)=\"onCancel()\"\r\n [disabled]=\"isLoading || (!isImgModified && !isNameModified)\"\r\n >\r\n {{ 'ImgManager.ImgLib.cancel' | translate }}\r\n </button>\r\n <div\r\n class=\"button danger button img-editor__infoSection__actions__save\"\r\n [ngClass]=\"{'img-editor__infoSection__actions__save--disable': isLoading}\"\r\n (click)=\"onSave()\"\r\n >\r\n {{ 'ImgManager.ImgEditor.saveBtn' | translate }}\r\n <span btnLoadingAnim *ngIf=\"isLoading\" class=\"btnLoadingAnnimation\"></span>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n <ng-scrollbar\r\n class=\"img-editor__scroll\"\r\n [ngClass]=\"{\r\n 'img-editor__scroll--full': stateDisplayed === 'full',\r\n 'img-editor__scroll--smallDisplay': stateDisplayed === 'small',\r\n 'img-editor__scroll--window': stateDisplayed === 'window'\r\n }\"\r\n >\r\n <div class=\"columns\">\r\n <!-- Left section -->\r\n <div class=\"column is-one-third img-editor__infoSection\">\r\n\r\n <info-section\r\n [imgToEdit]=\"imgToEdit\"\r\n [(isNameModified)]=\"isNameModified\"\r\n >\r\n </info-section>\r\n </div>\r\n\r\n\r\n <!-- Right section -->\r\n <div class=\"column img-editor__container\">\r\n <cropper\r\n [imgToEdit]=\"imgToEdit\"\r\n [(isImgModified)]=\"isImgModified\"\r\n (currentCroppedImageChange)=\"onImgCropped($event)\"\r\n (editClosed)=\"onEditClosed($event)\">\r\n </cropper>\r\n </div>\r\n </div>\r\n </ng-scrollbar>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.NgScrollbar, selector: "ng-scrollbar", inputs: ["disabled", "sensorDisabled", "pointerEventsDisabled", "viewportPropagateMouseMove", "autoHeightDisabled", "autoWidthDisabled", "viewClass", "trackClass", "thumbClass", "minThumbSize", "trackClickScrollDuration", "pointerEventsMethod", "track", "visibility", "appearance", "position", "sensorDebounce", "scrollAuditTime"], outputs: ["updated"], exportAs: ["ngScrollbar"] }, { kind: "component", type: i5.EditorInfoSectionComponent, selector: "info-section", inputs: ["imgToEdit", "isNameModified"], outputs: ["isNameModifiedChange"] }, { kind: "component", type: i6.CropperComponent, selector: "cropper", inputs: ["imgToEdit", "isImgModified"], outputs: ["isImgModifiedChange", "editClosed", "currentCroppedImageChange"] }, { kind: "directive", type: i7.LoadingDirective, selector: "[btnLoadingAnim]" }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }], animations: [
114
+ easeInOut
115
+ ] });
116
+ }
117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: ImgEditorComponent, decorators: [{
118
+ type: Component,
119
+ args: [{ selector: 'img-editor', animations: [
120
+ easeInOut
121
+ ], template: "<div class=\"img-editor\" [@easeInOut]=\"'in'\">\r\n\r\n <!-- Button Action Section -->\r\n\r\n <div class=\"img-editor__infoSection__actions\">\r\n <div>\r\n <button\r\n type=\"button\"\r\n class=\"button img-editor__infoSection__actions__cancel\"\r\n (click)=\"onCancel()\"\r\n [disabled]=\"isLoading || (!isImgModified && !isNameModified)\"\r\n >\r\n {{ 'ImgManager.ImgLib.cancel' | translate }}\r\n </button>\r\n <div\r\n class=\"button danger button img-editor__infoSection__actions__save\"\r\n [ngClass]=\"{'img-editor__infoSection__actions__save--disable': isLoading}\"\r\n (click)=\"onSave()\"\r\n >\r\n {{ 'ImgManager.ImgEditor.saveBtn' | translate }}\r\n <span btnLoadingAnim *ngIf=\"isLoading\" class=\"btnLoadingAnnimation\"></span>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n <ng-scrollbar\r\n class=\"img-editor__scroll\"\r\n [ngClass]=\"{\r\n 'img-editor__scroll--full': stateDisplayed === 'full',\r\n 'img-editor__scroll--smallDisplay': stateDisplayed === 'small',\r\n 'img-editor__scroll--window': stateDisplayed === 'window'\r\n }\"\r\n >\r\n <div class=\"columns\">\r\n <!-- Left section -->\r\n <div class=\"column is-one-third img-editor__infoSection\">\r\n\r\n <info-section\r\n [imgToEdit]=\"imgToEdit\"\r\n [(isNameModified)]=\"isNameModified\"\r\n >\r\n </info-section>\r\n </div>\r\n\r\n\r\n <!-- Right section -->\r\n <div class=\"column img-editor__container\">\r\n <cropper\r\n [imgToEdit]=\"imgToEdit\"\r\n [(isImgModified)]=\"isImgModified\"\r\n (currentCroppedImageChange)=\"onImgCropped($event)\"\r\n (editClosed)=\"onEditClosed($event)\">\r\n </cropper>\r\n </div>\r\n </div>\r\n </ng-scrollbar>\r\n</div>\r\n" }]
122
+ }], ctorParameters: () => [{ type: i1.ImgManagerService }, { type: i2.RenamePictureService }], propDecorators: { stateDisplayed: [{
123
+ type: Input
124
+ }], imgToEdit: [{
125
+ type: Input
126
+ }], editClosed: [{
127
+ type: Output
128
+ }] } });
129
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1nLWVkaXRvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93ei1pbWctbWFuYWdlci9zcmMvbGliL2NvbXBvbmVudHMvaW1nLWVkaXRvci9pbWctZWRpdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3d6LWltZy1tYW5hZ2VyL3NyYy9saWIvY29tcG9uZW50cy9pbWctZWRpdG9yL2ltZy1lZGl0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFHOUYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDdkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQzdFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDOzs7Ozs7Ozs7O0FBUzdFLE1BQU0sT0FBTyxrQkFBa0I7SUFvQm5CO0lBQ0E7SUFsQlYsY0FBYyxDQUFDO0lBRWYsU0FBUyxDQUFnQjtJQUVmLFVBQVUsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBRTFDLFNBQVMsR0FBWSxLQUFLLENBQUM7SUFDM0IsYUFBYSxHQUFZLEtBQUssQ0FBQztJQUMvQixjQUFjLEdBQVksS0FBSyxDQUFDO0lBQ2hDLG1CQUFtQixHQUFXLEVBQUUsQ0FBQyxDQUFDLCtDQUErQztJQUN6RSxZQUFZLENBQVM7SUFFN0IsV0FBVyxHQUFXLGtDQUFrQyxDQUFDO0lBQ3pELFdBQVcsR0FBVyxrQ0FBa0MsQ0FBQztJQUN6RCxjQUFjLEdBQVcseURBQXlELENBQUE7SUFFbEYsWUFDVSxpQkFBb0MsRUFDcEMsb0JBQTBDO1FBRDFDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFD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dXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBBZnRlclZpZXdJbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEltZ1BpY3R1cmVEVE8gfSBmcm9tICcuLi8uLi9kdG8vaW1nLW1hbmFnZXIuZHRvJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZm9ya0pvaW4gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgSW1nTWFuYWdlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9pbWctbWFuYWdlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgZWFzZUluT3V0IH0gZnJvbSAnLi4vLi4vYW5pbWF0aW9ucy9lYXNlSW5PdXQvZWFzZS1pbi1vdXQuYW5pbWF0aW9uJztcclxuaW1wb3J0IHsgUmVuYW1lUGljdHVyZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yZW5hbWUtcGljdHVyZS5zZXJ2aWNlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnaW1nLWVkaXRvcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2ltZy1lZGl0b3IuY29tcG9uZW50Lmh0bWwnLFxyXG4gIGFuaW1hdGlvbnM6IFtcclxuICAgIGVhc2VJbk91dFxyXG4gIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIEltZ0VkaXRvckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgc3RhdGVEaXNwbGF5ZWQ7XHJcbiAgQElucHV0KClcclxuICBpbWdUb0VkaXQ6IEltZ1BpY3R1cmVEVE87XHJcblxyXG4gIEBPdXRwdXQoKSBlZGl0Q2xvc2VkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICBpc0xvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBpc0ltZ01vZGlmaWVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgaXNOYW1lTW9kaWZpZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBjdXJyZW50Q3JvcHBlZEltYWdlOiBzdHJpbmcgPSAnJzsgLy8gSW1nIG1vZGlmaWVkIHJldHVybiBpbiBiYXNlNjQgYnkgdGhlIGNyb3BwZXJcclxuICBwcml2YXRlIHByZXZpb3VzTmFtZTogc3RyaW5nO1xyXG5cclxuICBtc2dGYWlsU2F2ZTogc3RyaW5nID0gJ0ltZ01hbmFnZXIuSW1nRWRpdG9yLm1zZ0ZhaWxTYXZlJztcclxuICBtc2dGYWlsTG9hZDogc3RyaW5nID0gJ0ltZ01hbmFnZXIuSW1nRWRpdG9yLm1zZ0ZhaWxMb2FkJztcclxuICBtc2dTdWNjZXNzRWRpdDogc3RyaW5nID0gXCJMZXMgbW9kaWZpY2F0aW9ucyBkZSBsJ2ltYWdlIG9udCBiaWVuIMOpdMOpIGVucmVnaXN0csOpZXMuXCJcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGltZ01hbmFnZXJTZXJ2aWNlOiBJbWdNYW5hZ2VyU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVuYW1lUGljdHVyZVNlcnZpY2U6IFJlbmFtZVBpY3R1cmVTZXJ2aWNlXHJcbiAgICApIHsgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMucHJldmlvdXNOYW1lID0gdGhpcy5pbWdUb0VkaXQuZGlzcGxheV9uYW1lO1xyXG4gIH1cclxuXHJcbiAgb25TYXZlKCkge1xyXG4gICAgaWYgKHRoaXMuaXNMb2FkaW5nKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcclxuXHJcbiAgICBpZiAoIXRoaXMuaXNJbWdNb2RpZmllZCAgJiYgIXRoaXMuaXNOYW1lTW9kaWZpZWQpIHtcclxuICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgdGhpcy5vbkVkaXRDbG9zZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBvYnNSZXBsYWNlSW1nID0gdGhpcy5pbWdNYW5hZ2VyU2VydmljZS5yZXBsYWNlSW1nKHRoaXMuY3VycmVudENyb3BwZWRJbWFnZSwgdGhpcy5pbWdUb0VkaXQuaWRfZmlsZSk7XHJcbiAgICBjb25zdCBvYnNDaGFuZ2VJbWdOYW1lID0gdGhpcy5yZW5hbWVQaWN0dXJlU2VydmljZS5jaGFuZ2VJbWFnZU5hbWUodGhpcy5pbWdUb0VkaXQuZGlzcGxheV9uYW1lLCB0aGlzLmltZ1RvRWRpdC5pZF9maWxlKTtcclxuXHJcbiAgICBpZih0aGlzLmlzSW1nTW9kaWZpZWQgJiYgdGhpcy5pc05hbWVNb2RpZmllZCkge1xyXG4gICAgICB0aGlzLnJlbmFtZUFuZFJlcGxhY2VJbWcob2JzQ2hhbmdlSW1nTmFtZSwgb2JzUmVwbGFjZUltZyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZih0aGlzLmlzSW1nTW9kaWZpZWQpe1xyXG4gICAgICBvYnNSZXBsYWNlSW1nLnN1YnNjcmliZSh7XHJcbiAgICAgICAgbmV4dDogZGF0YSA9PiB7XHJcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLm9uRWRpdENsb3NlZCh0aGlzLm1zZ1N1Y2Nlc3NFZGl0KTtcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IGVycm9yID0+IHtcclxuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuY3VycmVudENyb3BwZWRJbWFnZSA9ICcnO1xyXG4gICAgICAgIHRoaXMub25FZGl0Q2xvc2VkKHRoaXMubXNnRmFpbFNhdmUpO1xyXG4gICAgICB9fSk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5pc05hbWVNb2RpZmllZCkge1xyXG4gICAgICBvYnNDaGFuZ2VJbWdOYW1lLnN1YnNjcmliZSh7XHJcbiAgICAgICAgbmV4dDogZGF0YSA9PiB7XHJcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnByZXZpb3VzTmFtZSA9IHRoaXMuaW1nVG9FZGl0LmRpc3BsYXlfbmFtZTtcclxuICAgICAgICB0aGlzLm9uRWRpdENsb3NlZCh0aGlzLm1zZ1N1Y2Nlc3NFZGl0KTtcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IGVycm9yID0+IHtcclxuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuaW1nVG9FZGl0LmRpc3BsYXlfbmFtZSA9IHRoaXMucHJldmlvdXNOYW1lO1xyXG4gICAgICAgIHRoaXMub25FZGl0Q2xvc2VkKHRoaXMubXNnRmFpbFNhdmUpO1xyXG4gICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgdGhpcy5pc05hbWVNb2RpZmllZCA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgb25FZGl0Q2xvc2VkKG1zZ0tleT86IHN0cmluZykge1xyXG4gICAgdGhpcy5lZGl0Q2xvc2VkLmVtaXQobXNnS2V5KTtcclxuICB9XHJcblxyXG4gIG9uUmVzdGFydEVkaXQoKSB7XHJcbiAgICB0aGlzLmlzSW1nTW9kaWZpZWQgPSBmYWxzZTtcclxuICAgIHRoaXMuaXNOYW1lTW9kaWZpZWQgPSBmYWxzZTtcclxuICAgIHRoaXMuaW1nVG9FZGl0LmRpc3BsYXlfbmFtZSA9IHRoaXMucHJldmlvdXNOYW1lO1xyXG4gIH1cclxuXHJcbiAgb25DYW5jZWwoKSB7XHJcbiAgICB0aGlzLm9uRWRpdENsb3NlZCgnJyk7XHJcbiAgfVxyXG5cclxuICBvbkltZ0Nyb3BwZWQoaW1nQmFzZTY0OiBzdHJpbmcpIHtcclxuICAgIHRoaXMuY3VycmVudENyb3BwZWRJbWFnZSA9IGltZ0Jhc2U2NDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVuYW1lQW5kUmVwbGFjZUltZyhvYnNDaGFuZ2VJbWdOYW1lOiBPYnNlcnZhYmxlPGFueT4sIG9ic1JlcGxhY2VJbWc6IE9ic2VydmFibGU8YW55Pikge1xyXG4gICAgLy8gQXZvaWQgdG8gdXNlIGZvcmtqb2luLCBiZWNhdXNlIGl0IGNhbiBjcmVhdGUgY29uZmxpY3QgYW5kIGxvb3NlIHRoZSBpbWdcclxuICAgIG9ic0NoYW5nZUltZ05hbWUuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogcmVzMSA9PiB7XHJcbiAgICAgICAgb2JzUmVwbGFjZUltZy5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgbmV4dDogcmVzMiA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMub25FZGl0Q2xvc2VkKHRoaXMubXNnU3VjY2Vzc0VkaXQpO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIGVycm9yOiBlcnJvciA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMub25FZGl0Q2xvc2VkKHRoaXMubXNnRmFpbFNhdmUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogZXJyb3IgPT4ge1xyXG4gICAgICAgIHRoaXMub25FZGl0Q2xvc2VkKHRoaXMubXNnRmFpbFNhdmUpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImltZy1lZGl0b3JcIiBbQGVhc2VJbk91dF09XCInaW4nXCI+XHJcblxyXG4gICAgPCEtLSBCdXR0b24gQWN0aW9uIFNlY3Rpb24gLS0+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImltZy1lZGl0b3JfX2luZm9TZWN0aW9uX19hY3Rpb25zXCI+XHJcbiAgICAgIDxkaXY+XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBjbGFzcz1cImJ1dHRvbiBpbWctZWRpdG9yX19pbmZvU2VjdGlvbl9fYWN0aW9uc19fY2FuY2VsXCJcclxuICAgICAgICAgIChjbGljayk9XCJvbkNhbmNlbCgpXCJcclxuICAgICAgICAgIFtkaXNhYmxlZF09XCJpc0xvYWRpbmcgfHwgKCFpc0ltZ01vZGlmaWVkICAmJiAhaXNOYW1lTW9kaWZpZWQpXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICB7eyAnSW1nTWFuYWdlci5JbWdMaWIuY2FuY2VsJyB8IHRyYW5zbGF0ZSB9fVxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDxkaXZcclxuICAgICAgICAgIGNsYXNzPVwiYnV0dG9uIGRhbmdlciBidXR0b24gaW1nLWVkaXRvcl9faW5mb1NlY3Rpb25fX2FjdGlvbnNfX3NhdmVcIlxyXG4gICAgICAgICAgW25nQ2xhc3NdPVwieydpbWctZWRpdG9yX19pbmZvU2VjdGlvbl9fYWN0aW9uc19fc2F2ZS0tZGlzYWJsZSc6IGlzTG9hZGluZ31cIlxyXG4gICAgICAgICAgKGNsaWNrKT1cIm9uU2F2ZSgpXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICB7eyAnSW1nTWFuYWdlci5JbWdFZGl0b3Iuc2F2ZUJ0bicgfCB0cmFuc2xhdGUgfX1cclxuICAgICAgICAgIDxzcGFuIGJ0bkxvYWRpbmdBbmltICpuZ0lmPVwiaXNMb2FkaW5nXCIgY2xhc3M9XCJidG5Mb2FkaW5nQW5uaW1hdGlvblwiPjwvc3Bhbj5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPG5nLXNjcm9sbGJhclxyXG4gICAgICAgIGNsYXNzPVwiaW1nLWVkaXRvcl9fc2Nyb2xsXCJcclxuICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICdpbWctZWRpdG9yX19zY3JvbGwtLWZ1bGwnOiBzdGF0ZURpc3BsYXllZCA9PT0gJ2Z1bGwnLFxyXG4gICAgICAgICAgICAnaW1nLWVkaXRvcl9fc2Nyb2xsLS1zbWFsbERpc3BsYXknOiBzdGF0ZURpc3BsYXllZCA9PT0gJ3NtYWxsJyxcclxuICAgICAgICAgICAgJ2ltZy1lZGl0b3JfX3Njcm9sbC0td2luZG93Jzogc3RhdGVEaXNwbGF5ZWQgPT09ICd3aW5kb3cnXHJcbiAgICAgICAgfVwiXHJcbiAgICA+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1uc1wiPlxyXG4gICAgICAgIDwhLS0gTGVmdCBzZWN0aW9uIC0tPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaXMtb25lLXRoaXJkIGltZy1lZGl0b3JfX2luZm9TZWN0aW9uXCI+XHJcblxyXG4gICAgICAgICAgICA8aW5mby1zZWN0aW9uXHJcbiAgICAgICAgICAgICAgW2ltZ1RvRWRpdF09XCJpbWdUb0VkaXRcIlxyXG4gICAgICAgICAgICAgIFsoaXNOYW1lTW9kaWZpZWQpXT1cImlzTmFtZU1vZGlmaWVkXCJcclxuICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgIDwvaW5mby1zZWN0aW9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuXHJcbiAgICAgICAgPCEtLSBSaWdodCBzZWN0aW9uIC0tPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaW1nLWVkaXRvcl9fY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgIDxjcm9wcGVyXHJcbiAgICAgICAgICAgICAgW2ltZ1RvRWRpdF09XCJpbWdUb0VkaXRcIlxyXG4gICAgICAgICAgICAgIFsoaXNJbWdNb2RpZmllZCldPVwiaXNJbWdNb2RpZmllZFwiXHJcbiAgICAgICAgICAgICAgKGN1cnJlbnRDcm9wcGVkSW1hZ2VDaGFuZ2UpPVwib25JbWdDcm9wcGVkKCRldmVudClcIlxyXG4gICAgICAgICAgICAgIChlZGl0Q2xvc2VkKT1cIm9uRWRpdENsb3NlZCgkZXZlbnQpXCI+XHJcbiAgICAgICAgICAgIDwvY3JvcHBlcj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICAgPC9uZy1zY3JvbGxiYXI+XHJcbjwvZGl2PlxyXG4iXX0=