@wizishop/img-manager 18.2.0 → 18.2.2-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.
- package/esm2022/lib/components/canva-btn/canva-btn.component.mjs +73 -0
- package/esm2022/lib/components/images-view/images-actions-handler.mjs +168 -0
- package/esm2022/lib/components/images-view/images-view.component.mjs +391 -0
- package/esm2022/lib/components/images-view/mosaic-view/img-card/img-card.component.mjs +70 -0
- package/esm2022/lib/components/images-view/mosaic-view/mosaic-view.component.mjs +73 -0
- package/esm2022/lib/components/images-view/table-view/table-view.component.mjs +48 -0
- package/esm2022/lib/components/img-editor/cropper/cropper.component.mjs +313 -0
- package/esm2022/lib/components/img-editor/img-editor.component.mjs +129 -0
- package/esm2022/lib/components/img-editor/info-section/info-section.component.mjs +58 -0
- package/esm2022/lib/components/img-selection/img-selection.component.mjs +58 -0
- package/esm2022/lib/components/img-tabs/img-tabs.component.mjs +128 -0
- package/esm2022/lib/components/img-upload/img-upload.component.mjs +133 -0
- package/esm2022/lib/components/loader/loader.component.mjs +21 -0
- package/esm2022/lib/components/pexels-lib/pexels-lib.component.mjs +211 -0
- package/esm2022/lib/components/shared/alert/alert.component.mjs +26 -0
- package/esm2022/lib/components/shared/checkbox/checkbox.component.mjs +56 -0
- package/esm2022/lib/components/shared/dropdown/dropdown.component.mjs +21 -0
- package/esm2022/lib/components/shared/input-search/input-search.component.mjs +53 -0
- package/esm2022/lib/components/shared/pagination/page-selector/page-selector.component.mjs +50 -0
- package/esm2022/lib/components/shared/pagination/pagination.component.mjs +49 -0
- package/esm2022/lib/components/shared/select/select.component.mjs +117 -0
- package/esm2022/lib/components/shared/table/table.component.mjs +124 -0
- package/esm2022/lib/components/upload-list/upload-list.component.mjs +85 -0
- package/esm2022/lib/directives/abstract-debounce/abstract-debounce.directive.mjs +41 -0
- package/{esm2020 → esm2022}/lib/directives/abstract-debounce/debounce-keyup.directive.mjs +5 -5
- package/esm2022/lib/directives/auto-hide.directive.mjs +51 -0
- package/esm2022/lib/directives/copy-to-clipboard.directive.mjs +36 -0
- package/esm2022/lib/directives/drag-drop.directive.mjs +55 -0
- package/esm2022/lib/directives/loading.directive.mjs +43 -0
- package/esm2022/lib/directives/table/checkBoxRow.directive.mjs +130 -0
- package/esm2022/lib/directives/table/column.directive.mjs +50 -0
- package/esm2022/lib/directives/table/columnHeader.directive.mjs +215 -0
- package/esm2022/lib/directives/table/raw.directive.mjs +34 -0
- package/esm2022/lib/directives/zindex-toggle.directive.mjs +45 -0
- package/esm2022/lib/dto/canva-create-design.dto.mjs +9 -0
- package/esm2022/lib/dto/canva.dto.mjs +6 -0
- package/esm2022/lib/dto/config/apis/api.dto.mjs +11 -0
- package/esm2022/lib/dto/config/external/external-config.dto.mjs +5 -0
- package/esm2022/lib/dto/wizi-block-media.dto.mjs +7 -0
- package/esm2022/lib/pipes/images/img-src.pipe.mjs +29 -0
- package/{esm2020 → esm2022}/lib/pipes/number-to-array.pipe.mjs +4 -4
- package/esm2022/lib/pipes/pagination/array-total-pages/array-pages.pipe.mjs +28 -0
- package/esm2022/lib/pipes/pagination/large-number-of-page/large-number-of-page.pipe.mjs +53 -0
- package/esm2022/lib/pipes/pagination/text/custom-text.pipe.mjs +36 -0
- package/esm2022/lib/pipes/pagination/total-pages/is-last-page.pipe.mjs +25 -0
- package/{esm2020 → esm2022}/lib/pipes/select/select-filters.pipe.mjs +4 -4
- package/esm2022/lib/services/alert.service.mjs +53 -0
- package/{esm2020 → esm2022}/lib/services/api.service.mjs +4 -4
- package/esm2022/lib/services/canva.service.mjs +165 -0
- package/esm2022/lib/services/config/img-cdn.service.mjs +21 -0
- package/esm2022/lib/services/dom.service.mjs +31 -0
- package/{esm2020 → esm2022}/lib/services/icon.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/services/image-not-found.service.mjs +4 -4
- package/esm2022/lib/services/img-event.service.mjs +33 -0
- package/esm2022/lib/services/img-manager.service.mjs +134 -0
- package/esm2022/lib/services/img-selection.service.mjs +75 -0
- package/esm2022/lib/services/pexels.service.mjs +66 -0
- package/esm2022/lib/services/rename-picture.service.mjs +66 -0
- package/esm2022/lib/services/snackbar.service.mjs +67 -0
- package/esm2022/lib/services/table/filters-table.service.mjs +61 -0
- package/esm2022/lib/services/upload.service.mjs +20 -0
- package/esm2022/lib/services/user-settings.service.mjs +23 -0
- package/esm2022/lib/wz-img-manager.component.mjs +209 -0
- package/{esm2020 → esm2022}/lib/wz-img-manager.module.mjs +61 -61
- package/{fesm2020 → fesm2022}/wizishop-img-manager.mjs +1018 -830
- package/fesm2022/wizishop-img-manager.mjs.map +1 -0
- package/lib/components/canva-btn/canva-btn.component.d.ts +1 -1
- package/lib/components/images-view/images-actions-handler.d.ts +2 -1
- package/lib/components/images-view/images-view.component.d.ts +4 -9
- package/lib/components/images-view/mosaic-view/img-card/img-card.component.d.ts +1 -1
- package/lib/components/images-view/mosaic-view/mosaic-view.component.d.ts +1 -1
- package/lib/components/img-editor/cropper/cropper.component.d.ts +1 -1
- package/lib/components/img-editor/img-editor.component.d.ts +1 -1
- package/lib/components/img-editor/info-section/info-section.component.d.ts +1 -1
- package/lib/components/img-selection/img-selection.component.d.ts +4 -5
- package/lib/components/img-tabs/img-tabs.component.d.ts +1 -1
- package/lib/components/img-upload/img-upload.component.d.ts +1 -1
- package/lib/components/loader/loader.component.d.ts +1 -1
- package/lib/components/pexels-lib/pexels-lib.component.d.ts +1 -1
- package/lib/components/shared/alert/alert.component.d.ts +1 -1
- package/lib/components/shared/checkbox/checkbox.component.d.ts +1 -1
- package/lib/components/shared/dropdown/dropdown.component.d.ts +1 -1
- package/lib/components/shared/input-search/input-search.component.d.ts +1 -1
- package/lib/components/shared/pagination/page-selector/page-selector.component.d.ts +1 -1
- package/lib/components/shared/pagination/pagination.component.d.ts +1 -1
- package/lib/components/shared/select/select.component.d.ts +1 -1
- package/lib/components/shared/table/table.component.d.ts +1 -1
- package/lib/components/upload-list/upload-list.component.d.ts +1 -1
- package/lib/directives/abstract-debounce/abstract-debounce.directive.d.ts +1 -1
- package/lib/directives/auto-hide.directive.d.ts +1 -1
- package/lib/directives/copy-to-clipboard.directive.d.ts +1 -1
- package/lib/directives/table/checkBoxRow.directive.d.ts +1 -1
- package/lib/directives/table/column.directive.d.ts +1 -1
- package/lib/directives/table/columnHeader.directive.d.ts +1 -1
- package/lib/directives/zindex-toggle.directive.d.ts +1 -1
- package/lib/wz-img-manager.component.d.ts +3 -3
- package/package.json +6 -12
- package/wizishop-img-manager-18.2.2-beta.tgz +0 -0
- package/wz-img-manager.scss +77 -60
- package/esm2020/lib/components/canva-btn/canva-btn.component.mjs +0 -67
- package/esm2020/lib/components/images-view/images-actions-handler.mjs +0 -154
- package/esm2020/lib/components/images-view/images-view.component.mjs +0 -369
- package/esm2020/lib/components/images-view/mosaic-view/img-card/img-card.component.mjs +0 -66
- package/esm2020/lib/components/images-view/mosaic-view/mosaic-view.component.mjs +0 -71
- package/esm2020/lib/components/images-view/table-view/table-view.component.mjs +0 -48
- package/esm2020/lib/components/img-editor/cropper/cropper.component.mjs +0 -307
- package/esm2020/lib/components/img-editor/img-editor.component.mjs +0 -124
- package/esm2020/lib/components/img-editor/info-section/info-section.component.mjs +0 -54
- package/esm2020/lib/components/img-selection/img-selection.component.mjs +0 -53
- package/esm2020/lib/components/img-tabs/img-tabs.component.mjs +0 -122
- package/esm2020/lib/components/img-upload/img-upload.component.mjs +0 -126
- package/esm2020/lib/components/loader/loader.component.mjs +0 -21
- package/esm2020/lib/components/pexels-lib/pexels-lib.component.mjs +0 -203
- package/esm2020/lib/components/shared/alert/alert.component.mjs +0 -27
- package/esm2020/lib/components/shared/checkbox/checkbox.component.mjs +0 -52
- package/esm2020/lib/components/shared/dropdown/dropdown.component.mjs +0 -21
- package/esm2020/lib/components/shared/input-search/input-search.component.mjs +0 -54
- package/esm2020/lib/components/shared/pagination/page-selector/page-selector.component.mjs +0 -49
- package/esm2020/lib/components/shared/pagination/pagination.component.mjs +0 -49
- package/esm2020/lib/components/shared/select/select.component.mjs +0 -110
- package/esm2020/lib/components/shared/table/table.component.mjs +0 -116
- package/esm2020/lib/components/upload-list/upload-list.component.mjs +0 -79
- package/esm2020/lib/directives/abstract-debounce/abstract-debounce.directive.mjs +0 -37
- package/esm2020/lib/directives/auto-hide.directive.mjs +0 -48
- package/esm2020/lib/directives/copy-to-clipboard.directive.mjs +0 -37
- package/esm2020/lib/directives/drag-drop.directive.mjs +0 -57
- package/esm2020/lib/directives/loading.directive.mjs +0 -42
- package/esm2020/lib/directives/table/checkBoxRow.directive.mjs +0 -114
- package/esm2020/lib/directives/table/column.directive.mjs +0 -45
- package/esm2020/lib/directives/table/columnHeader.directive.mjs +0 -204
- package/esm2020/lib/directives/table/raw.directive.mjs +0 -31
- package/esm2020/lib/directives/zindex-toggle.directive.mjs +0 -42
- package/esm2020/lib/dto/canva-create-design.dto.mjs +0 -4
- package/esm2020/lib/dto/canva.dto.mjs +0 -4
- package/esm2020/lib/dto/config/apis/api.dto.mjs +0 -9
- package/esm2020/lib/dto/config/external/external-config.dto.mjs +0 -3
- package/esm2020/lib/dto/wizi-block-media.dto.mjs +0 -3
- package/esm2020/lib/pipes/images/img-src.pipe.mjs +0 -28
- package/esm2020/lib/pipes/pagination/array-total-pages/array-pages.pipe.mjs +0 -28
- package/esm2020/lib/pipes/pagination/large-number-of-page/large-number-of-page.pipe.mjs +0 -53
- package/esm2020/lib/pipes/pagination/text/custom-text.pipe.mjs +0 -35
- package/esm2020/lib/pipes/pagination/total-pages/is-last-page.pipe.mjs +0 -25
- package/esm2020/lib/services/alert.service.mjs +0 -50
- package/esm2020/lib/services/canva.service.mjs +0 -159
- package/esm2020/lib/services/config/img-cdn.service.mjs +0 -23
- package/esm2020/lib/services/dom.service.mjs +0 -33
- package/esm2020/lib/services/img-event.service.mjs +0 -35
- package/esm2020/lib/services/img-manager.service.mjs +0 -136
- package/esm2020/lib/services/img-selection.service.mjs +0 -76
- package/esm2020/lib/services/pexels.service.mjs +0 -62
- package/esm2020/lib/services/rename-picture.service.mjs +0 -63
- package/esm2020/lib/services/snackbar.service.mjs +0 -64
- package/esm2020/lib/services/table/filters-table.service.mjs +0 -60
- package/esm2020/lib/services/upload.service.mjs +0 -22
- package/esm2020/lib/services/user-settings.service.mjs +0 -25
- package/esm2020/lib/wz-img-manager.component.mjs +0 -192
- package/fesm2015/wizishop-img-manager.mjs +0 -4035
- package/fesm2015/wizishop-img-manager.mjs.map +0 -1
- package/fesm2020/wizishop-img-manager.mjs.map +0 -1
- package/wizishop-img-manager-18.2.0.tgz +0 -0
- /package/{esm2020 → esm2022}/lib/animations/easeInOut/ease-in-out.animation.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/animations/insertRemove/insert-remove.animation.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/animations/listAnnimation/list.animation.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/shared/select/call-to-action.model.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/shared/select/select-items.dto.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/ImgManagerDisplayConfig.dto.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/config/image-cdn/image-cdn-config.dto.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/config/img-manager.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/export-dtos.api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/img-editor-config.dto.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/img-manager.dto.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/pexels-img.dto.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/picture-name-update.dto.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/stateDisplayed.dto.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/dto/tabDisplayed.dto.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JvcHBlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93ei1pbWctbWFuYWdlci9zcmMvbGliL2NvbXBvbmVudHMvaW1nLWVkaXRvci9jcm9wcGVyL2Nyb3BwZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvd3otaW1nLW1hbmFnZXIvc3JjL2xpYi9jb21wb25lbnRzL2ltZy1lZGl0b3IvY3JvcHBlci9jcm9wcGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFFMUYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMERBQTBELENBQUM7QUFHeEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBDQUEwQyxDQUFDOzs7Ozs7OztBQVN6RSxNQUFNLE9BQU8sZ0JBQWdCO0lBZ0pqQjtJQTdJVixTQUFTLENBQWdCO0lBRXpCLElBQ0ksYUFBYSxDQUFDLGFBQXNCO1FBQ3RDLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckIsQ0FBQztJQUNILENBQUM7SUFDRCxJQUFJLGFBQWE7UUFDZixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUNPLGNBQWMsR0FBWSxLQUFLLENBQUM7SUFHeEMsbUJBQW1CLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztJQUdsRCxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUdoQyx5QkFBeUIsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO0lBRXZELFdBQVcsR0FBVyxrQ0FBa0MsQ0FBQztJQUV6RCxjQUFjLEdBQVksS0FBSyxDQUFDO0lBQ2hDLGNBQWMsR0FBWSxLQUFLLENBQUMsQ0FBQyxpRkFBaUY7SUFDbEgsbUJBQW1CLEdBQVcsRUFBRSxDQUFDLENBQUMsZ0NBQWdDO0lBQ2xFLFNBQVMsR0FBWSxLQUFLLENBQUM7SUFDM0IsU0FBUyxHQUFZLEtBQUssQ0FBQztJQUUzQixhQUFhLEdBQVksS0FBSyxDQUFDO0lBQy9CLElBQUksWUFBWSxDQUFDLFlBQXFCO1FBQ3BDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsYUFBYSxHQUFHLFlBQVksQ0FBQztRQUNwQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDUixDQUFDO0lBRUQsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO0lBQzVCLENBQUM7SUFDRCxnQkFBZ0IsR0FBa0IsSUFBSSxPQUFPLEVBQVEsQ0FBQztJQUN0RCxrQkFBa0IsR0FBVyxDQUFDLENBQUM7SUFFL0IsMkJBQTJCO0lBQzNCLE9BQU8sQ0FBZTtJQUN0QixRQUFRLENBQVM7SUFDakIsaUJBQWlCLEdBQVEsRUFBRSxDQUFDO0lBQzVCLFlBQVksR0FBUSxFQUFFLENBQUM7SUFDdkIsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUNuQixRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNWLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDcEIsd0JBQXdCLEdBQUcsS0FBSyxDQUFDO0lBQ2pDLFNBQVMsR0FBbUIsRUFBRSxDQUFDO0lBRS9CLGtCQUFrQixDQUFTO0lBRTNCLGdCQUFnQjtJQUNoQixnQkFBZ0IsR0FBeUI7UUFDdkM7WUFDRSxLQUFLLEVBQUUsb0NBQW9DO1lBQzNDLE1BQU0sRUFBRTtnQkFDTixtQkFBbUIsRUFBRSxJQUFJO2FBQzFCO1NBQ0Y7UUFDRDtZQUNFLEtBQUssRUFBRSxrQ0FBa0M7WUFDekMsTUFBTSxFQUFFO2dCQUNOLG1CQUFtQixFQUFFLEtBQUs7YUFDM0I7WUFDRCxNQUFNLEVBQUUsSUFBSTtTQUNiO1FBQ0Q7WUFDRSxLQUFLLEVBQUUsb0NBQW9DO1lBQzNDLE1BQU0sRUFBRTtnQkFDTixtQkFBbUIsRUFBRSxJQUFJO2dCQUN6QixXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUM7YUFDbkI7U0FDRjtRQUNEO1lBQ0UsS0FBSyxFQUFFLHNDQUFzQztZQUM3QyxNQUFNLEVBQUU7Z0JBQ04sbUJBQW1CLEVBQUUsSUFBSTtnQkFDekIsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDO2FBQ25CO1NBQ0Y7UUFDRDtZQUNFLEtBQUssRUFBRSx1Q0FBdUM7WUFDOUMsTUFBTSxFQUFFO2dCQUNOLG1CQUFtQixFQUFFLElBQUk7Z0JBQ3pCLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQzthQUNuQjtTQUNGO0tBQ0YsQ0FBQztJQUVGLGNBQWMsR0FBeUI7UUFDckM7WUFDRSxLQUFLLEVBQUUsc0NBQXNDO1lBQzdDLElBQUksRUFBRSxpQkFBaUI7WUFDdkIsTUFBTSxFQUFFLGFBQWE7WUFDckIsTUFBTSxFQUFFLElBQUk7U0FDYjtRQUNEO1lBQ0UsS0FBSyxFQUFFLDBDQUEwQztZQUNqRCxJQUFJLEVBQUUsaUJBQWlCO1lBQ3ZCLE1BQU0sRUFBRSxZQUFZO1NBQ3JCO1FBQ0Q7WUFDRSxLQUFLLEVBQUUsc0NBQXNDO1lBQzdDLElBQUksRUFBRSxpQkFBaUI7WUFDdkIsTUFBTSxFQUFFLGNBQWM7U0FDdkI7UUFDRDtZQUNFLEtBQUssRUFBRSx1Q0FBdUM7WUFDOUMsSUFBSSxFQUFFLHFCQUFxQjtZQUMzQixNQUFNLEVBQUUsZ0JBQWdCO1NBQ3pCO0tBQ0YsQ0FBQztJQUVGLFVBQVUsR0FBeUI7UUFDakM7WUFDRSxLQUFLLEVBQUUsa0NBQWtDO1lBQ3pDLElBQUksRUFBRSxvQkFBb0I7WUFDMUIsTUFBTSxFQUFFLFFBQVE7WUFDaEIsTUFBTSxFQUFFLElBQUk7U0FDYjtRQUNEO1lBQ0UsS0FBSyxFQUFFLG9DQUFvQztZQUMzQyxJQUFJLEVBQUUscUJBQXFCO1lBQzNCLE1BQU0sRUFBRSxTQUFTO1NBQ2xCO0tBQ0YsQ0FBQztJQUVGLHdCQUF3QjtJQUN4QixnQkFBZ0IsR0FBb0I7UUFDbEMsbUJBQW1CLEVBQUUsS0FBSztRQUMxQixXQUFXLEVBQUUsU0FBUztLQUN2QixDQUFBO0lBRUQsWUFDVSxhQUE0QjtRQUE1QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtJQUNsQyxDQUFDO0lBRUwsUUFBUTtRQUNOLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNaLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxJQUFJO1FBQ0YsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVELGNBQWM7UUFDWixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO0lBQ3hFLENBQUM7SUFFRCxVQUFVO1FBQ1IsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBaUIsQ0FBQztJQUM1RyxDQUFDO0lBRUQsb0JBQW9CO1FBQ2xCLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ25ELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztRQUN0RSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztJQUM5RCxDQUFDO0lBRUQsWUFBWSxDQUFDLE1BQWU7UUFDMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELFNBQVM7UUFDUCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1osSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELGFBQWE7UUFDWCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxtSUFBbUk7SUFFbkksMkJBQTJCO0lBRTNCLGVBQWUsQ0FBQyxLQUFVO1FBQ3hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7SUFDakMsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUF3QjtRQUNuQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFN0IsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDeEMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQzFCLENBQUM7SUFFRCxZQUFZO1FBQ1YsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7SUFDN0IsQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQsc0JBQXNCO0lBRXRCLG9CQUFvQixDQUFDLEtBQWE7UUFDaEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDakQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUNuRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVELFdBQVc7UUFFVCxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7WUFDckIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUM7WUFDN0MsSUFBSSxDQUFDLGtCQUFrQixHQUFHLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUM1QixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFTixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVELGdCQUFnQjtRQUNkLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7UUFDbEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUM7UUFDeEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVPLGFBQWEsQ0FBQyxLQUFXLEVBQUUsS0FBYTtRQUM5Qyx5Q0FBeUM7UUFDekMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRTtZQUNoQyxJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLG9CQUFvQixDQUFDLE1BQVc7UUFDdEMsS0FBSyxNQUFNLFFBQVEsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JELENBQUM7SUFDSCxDQUFDO0lBRU8sc0JBQXNCO1FBQzVCLElBQUksQ0FBQyxnQkFBZ0I7YUFDbEIsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzFCLElBQUksSUFBSSxDQUFDLGtCQUFrQixJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxPQUFPO1lBQ1QsQ0FBQztZQUNELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUE7SUFFSixDQUFDO0lBRUQseUJBQXlCO0lBRXpCLFVBQVU7UUFDTixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQsV0FBVztRQUNQLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxjQUFjO1FBQ1YsSUFBSSxDQUFDLFNBQVMsR0FBRztZQUNiLEdBQUcsSUFBSSxDQUFDLFNBQVM7WUFDakIsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLO1NBQy9CLENBQUM7UUFDRixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUVELFlBQVk7UUFDUixJQUFJLENBQUMsU0FBUyxHQUFHO1lBQ2IsR0FBRyxJQUFJLENBQUMsU0FBUztZQUNqQixLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUs7U0FDL0IsQ0FBQztRQUNGLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRU8sZUFBZTtRQUNyQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUN0QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUN0QyxJQUFJLENBQUMsU0FBUyxHQUFHO1lBQ2IsR0FBRyxJQUFJLENBQUMsU0FBUztZQUNqQixLQUFLLEVBQUUsUUFBUTtZQUNmLEtBQUssRUFBRSxRQUFRO1NBQ2xCLENBQUM7SUFDSixDQUFDO0lBRUQsb0JBQW9CO0lBRXBCLE9BQU87UUFDSCxJQUFJLENBQUMsS0FBSyxJQUFLLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFBLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN4QyxJQUFJLENBQUMsU0FBUyxHQUFHO1lBQ2IsR0FBRyxJQUFJLENBQUMsU0FBUztZQUNqQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7U0FDcEIsQ0FBQztRQUNGLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQsTUFBTTtRQUNGLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxTQUFTLEdBQUc7WUFDYixHQUFHLElBQUksQ0FBQyxTQUFTO1lBQ2pCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztTQUNwQixDQUFDO1FBQ0YsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxXQUFXLENBQUMsTUFBYztRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLDJEQUEyRDtJQUM3RSxDQUFDO3VHQWhWVSxnQkFBZ0I7MkZBQWhCLGdCQUFnQiw4UENmN0IsNnRJQXVHQSxnNkNENUZjO1lBQ1YsWUFBWTtTQUNiOzsyRkFFVSxnQkFBZ0I7a0JBUDVCLFNBQVM7K0JBQ0UsU0FBUyxjQUVQO3dCQUNWLFlBQVk7cUJBQ2I7a0ZBS0QsU0FBUztzQkFEUixLQUFLO2dCQUlGLGFBQWE7c0JBRGhCLEtBQUs7Z0JBYU4sbUJBQW1CO3NCQURsQixNQUFNO2dCQUlQLFVBQVU7c0JBRFQsTUFBTTtnQkFJUCx5QkFBeUI7c0JBRHhCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgSW1hZ2VDcm9wcGVkRXZlbnQsIEltYWdlVHJhbnNmb3JtLCBPdXRwdXRGb3JtYXQgfSBmcm9tICduZ3gtaW1hZ2UtY3JvcHBlcic7XHJcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgaW5zZXJ0UmVtb3ZlIH0gZnJvbSAnLi4vLi4vLi4vYW5pbWF0aW9ucy9pbnNlcnRSZW1vdmUvaW5zZXJ0LXJlbW92ZS5hbmltYXRpb24nO1xyXG5pbXBvcnQgeyBDcm9wcGVyQ29uZmlnRFRPLCBJbWdDcm9wcGVyQ29uZmlnRFRPIH0gZnJvbSAnLi4vLi4vLi4vZHRvL2ltZy1lZGl0b3ItY29uZmlnLmR0byc7XHJcbmltcG9ydCB7IEltZ1BpY3R1cmVEVE8gfSBmcm9tICcuLi8uLi8uLi9kdG8vaW1nLW1hbmFnZXIuZHRvJztcclxuaW1wb3J0IHsgSW1nQ0ROU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2NvbmZpZy9pbWctY2RuLnNlcnZpY2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdjcm9wcGVyJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vY3JvcHBlci5jb21wb25lbnQuaHRtbCcsXHJcbiAgYW5pbWF0aW9uczogW1xyXG4gICAgaW5zZXJ0UmVtb3ZlXHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQ3JvcHBlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgaW1nVG9FZGl0OiBJbWdQaWN0dXJlRFRPO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHNldCBpc0ltZ01vZGlmaWVkKGlzSW1nTW9kaWZpZWQ6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuX2lzSW1nTW9kaWZpZWQgPSBpc0ltZ01vZGlmaWVkO1xyXG4gICAgaWYgKCFpc0ltZ01vZGlmaWVkKSB7XHJcbiAgICAgIHRoaXMucmVzdGFydEVkaXQoKTtcclxuICAgIH1cclxuICB9XHJcbiAgZ2V0IGlzSW1nTW9kaWZpZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5faXNJbWdNb2RpZmllZDtcclxuICB9XHJcbiAgcHJpdmF0ZSBfaXNJbWdNb2RpZmllZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBAT3V0cHV0KClcclxuICBpc0ltZ01vZGlmaWVkQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xyXG5cclxuICBAT3V0cHV0KClcclxuICBlZGl0Q2xvc2VkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICBAT3V0cHV0KClcclxuICBjdXJyZW50Q3JvcHBlZEltYWdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+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=
|