@lenne.tech/ng-base 18.1.2 → 22.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +55 -0
- package/LICENSE +2 -2
- package/README.md +237 -44
- package/fesm2022/lenne.tech-ng-base-ai.mjs +767 -0
- package/fesm2022/lenne.tech-ng-base-ai.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-auth-provide.mjs +939 -0
- package/fesm2022/lenne.tech-ng-base-auth-provide.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-auth.mjs +454 -0
- package/fesm2022/lenne.tech-ng-base-auth.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs +825 -0
- package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs +351 -0
- package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs +1046 -0
- package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs +4 -0
- package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs +179 -0
- package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-bug-provide.mjs +26 -0
- package/fesm2022/lenne.tech-ng-base-bug-provide.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs +62 -0
- package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-bug-server.mjs +818 -0
- package/fesm2022/lenne.tech-ng-base-bug-server.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-bug.mjs +196 -0
- package/fesm2022/lenne.tech-ng-base-bug.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-files-ui.mjs +445 -0
- package/fesm2022/lenne.tech-ng-base-files-ui.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-files.mjs +474 -0
- package/fesm2022/lenne.tech-ng-base-files.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-server.mjs +408 -0
- package/fesm2022/lenne.tech-ng-base-server.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-share.mjs +76 -0
- package/fesm2022/lenne.tech-ng-base-share.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-sync.mjs +1096 -0
- package/fesm2022/lenne.tech-ng-base-sync.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-testing.mjs +171 -0
- package/fesm2022/lenne.tech-ng-base-testing.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-ui-provide.mjs +124 -0
- package/fesm2022/lenne.tech-ng-base-ui-provide.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-ui.mjs +34611 -0
- package/fesm2022/lenne.tech-ng-base-ui.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base-utils.mjs +287 -0
- package/fesm2022/lenne.tech-ng-base-utils.mjs.map +1 -0
- package/fesm2022/lenne.tech-ng-base.mjs +615 -902
- package/fesm2022/lenne.tech-ng-base.mjs.map +1 -1
- package/i18n/auth/de.json +17 -0
- package/i18n/auth/en.json +17 -0
- package/i18n/bug/de.json +85 -0
- package/i18n/bug/en.json +85 -0
- package/i18n/de.json +8 -0
- package/i18n/en.json +8 -0
- package/i18n/files/de.json +27 -0
- package/i18n/files/en.json +27 -0
- package/i18n/share/de.json +8 -0
- package/i18n/share/en.json +8 -0
- package/i18n/ui/de.json +38 -0
- package/i18n/ui/en.json +38 -0
- package/package.json +127 -58
- package/types/lenne.tech-ng-base-ai.d.ts +830 -0
- package/types/lenne.tech-ng-base-auth-provide.d.ts +603 -0
- package/types/lenne.tech-ng-base-auth.d.ts +320 -0
- package/types/lenne.tech-ng-base-bug-provide.d.ts +272 -0
- package/types/lenne.tech-ng-base-bug-rolldown-runtime-C25Le4-w.d.ts +1 -0
- package/types/lenne.tech-ng-base-bug-server.d.ts +316 -0
- package/types/lenne.tech-ng-base-bug.d.ts +202 -0
- package/types/lenne.tech-ng-base-files-ui.d.ts +116 -0
- package/types/lenne.tech-ng-base-files.d.ts +288 -0
- package/types/lenne.tech-ng-base-server.d.ts +262 -0
- package/types/lenne.tech-ng-base-share.d.ts +21 -0
- package/types/lenne.tech-ng-base-sync.d.ts +380 -0
- package/types/lenne.tech-ng-base-testing.d.ts +327 -0
- package/types/lenne.tech-ng-base-ui-provide.d.ts +65 -0
- package/types/lenne.tech-ng-base-ui.d.ts +7732 -0
- package/types/lenne.tech-ng-base-utils.d.ts +150 -0
- package/types/lenne.tech-ng-base.d.ts +503 -0
- package/ui/styles/components/accordion.css +3 -0
- package/ui/styles/components/alert-dialog.css +4 -0
- package/ui/styles/components/alert.css +3 -0
- package/ui/styles/components/aspect-ratio.css +3 -0
- package/ui/styles/components/attachment.css +4 -0
- package/ui/styles/components/autocomplete.css +4 -0
- package/ui/styles/components/avatar.css +3 -0
- package/ui/styles/components/badge.css +3 -0
- package/ui/styles/components/breadcrumb.css +3 -0
- package/ui/styles/components/bubble.css +3 -0
- package/ui/styles/components/button-group.css +3 -0
- package/ui/styles/components/button.css +3 -0
- package/ui/styles/components/calendar.css +5 -0
- package/ui/styles/components/card.css +3 -0
- package/ui/styles/components/checkbox.css +3 -0
- package/ui/styles/components/code-block.css +4 -0
- package/ui/styles/components/collapsible.css +3 -0
- package/ui/styles/components/combobox.css +5 -0
- package/ui/styles/components/command.css +5 -0
- package/ui/styles/components/context-menu.css +3 -0
- package/ui/styles/components/date-picker.css +7 -0
- package/ui/styles/components/dialog.css +4 -0
- package/ui/styles/components/drawer.css +3 -0
- package/ui/styles/components/dropdown-menu.css +3 -0
- package/ui/styles/components/empty.css +3 -0
- package/ui/styles/components/field.css +5 -0
- package/ui/styles/components/hover-card.css +3 -0
- package/ui/styles/components/index.css +91 -0
- package/ui/styles/components/input-group.css +6 -0
- package/ui/styles/components/input-otp.css +3 -0
- package/ui/styles/components/input.css +3 -0
- package/ui/styles/components/item.css +4 -0
- package/ui/styles/components/kbd.css +3 -0
- package/ui/styles/components/label.css +3 -0
- package/ui/styles/components/lt-breadcrumb.css +3 -0
- package/ui/styles/components/lt-bug-attachments.css +5 -0
- package/ui/styles/components/lt-bug-journey-timeline.css +5 -0
- package/ui/styles/components/lt-bug-report-dialog.css +15 -0
- package/ui/styles/components/lt-bug-report.css +4 -0
- package/ui/styles/components/lt-color-mode-button.css +3 -0
- package/ui/styles/components/lt-confirm-dialog.css +4 -0
- package/ui/styles/components/lt-data-view.css +5 -0
- package/ui/styles/components/lt-date-picker.css +3 -0
- package/ui/styles/components/lt-date-time-picker.css +5 -0
- package/ui/styles/components/lt-enter-action.css +2 -0
- package/ui/styles/components/lt-footer.css +3 -0
- package/ui/styles/components/lt-form-field.css +4 -0
- package/ui/styles/components/lt-header.css +5 -0
- package/ui/styles/components/lt-imports.css +21 -0
- package/ui/styles/components/lt-navigation-menu.css +3 -0
- package/ui/styles/components/lt-notice.css +3 -0
- package/ui/styles/components/lt-overlay-defaults.css +3 -0
- package/ui/styles/components/lt-page-card.css +3 -0
- package/ui/styles/components/lt-page-title.css +2 -0
- package/ui/styles/components/lt-password-input.css +4 -0
- package/ui/styles/components/lt-readonly-field.css +2 -0
- package/ui/styles/components/lt-select.css +4 -0
- package/ui/styles/components/lt-text-field.css +5 -0
- package/ui/styles/components/lt-toolbar-item.css +2 -0
- package/ui/styles/components/lt-toolbar.css +3 -0
- package/ui/styles/components/lt-tus-upload-component.css +5 -0
- package/ui/styles/components/marker.css +3 -0
- package/ui/styles/components/menubar.css +3 -0
- package/ui/styles/components/message-scroller.css +4 -0
- package/ui/styles/components/message.css +3 -0
- package/ui/styles/components/native-select.css +3 -0
- package/ui/styles/components/navigation-menu.css +3 -0
- package/ui/styles/components/pagination.css +4 -0
- package/ui/styles/components/popover.css +3 -0
- package/ui/styles/components/progress.css +3 -0
- package/ui/styles/components/questionnaire.css +4 -0
- package/ui/styles/components/radio-group.css +3 -0
- package/ui/styles/components/resizable.css +3 -0
- package/ui/styles/components/select.css +3 -0
- package/ui/styles/components/separator.css +3 -0
- package/ui/styles/components/sheet.css +4 -0
- package/ui/styles/components/sidebar.css +9 -0
- package/ui/styles/components/skeleton.css +3 -0
- package/ui/styles/components/slider.css +3 -0
- package/ui/styles/components/sonner.css +4 -0
- package/ui/styles/components/spinner.css +3 -0
- package/ui/styles/components/switch.css +3 -0
- package/ui/styles/components/table.css +3 -0
- package/ui/styles/components/tabs.css +4 -0
- package/ui/styles/components/textarea.css +3 -0
- package/ui/styles/components/toggle-group.css +4 -0
- package/ui/styles/components/toggle.css +3 -0
- package/ui/styles/components/tooltip.css +3 -0
- package/ui/styles/components/trace.css +3 -0
- package/ui/styles/components/typography.css +3 -0
- package/ui/styles/components/utils.css +2 -0
- package/ui/styles/core.css +137 -0
- package/ui/styles/palette.css +94 -0
- package/ui/styles/theme.css +14 -0
- package/ui/styles/transitions.css +131 -0
- package/base-cms/index.d.ts +0 -5
- package/base-cms/interfaces/base-cms-module-config.interface.d.ts +0 -16
- package/base-cms/pages/base-cms/base-cms.component.d.ts +0 -92
- package/base-cms/public-api.d.ts +0 -5
- package/base-components/components/breadcrumb/breadcrumb.component.d.ts +0 -10
- package/base-components/components/change-password/change-password.component.d.ts +0 -24
- package/base-components/components/checkbox/checkbox.component.d.ts +0 -12
- package/base-components/components/delete-account/delete-account.component.d.ts +0 -15
- package/base-components/components/fab-button/fab-button.component.d.ts +0 -16
- package/base-components/components/input/input.component.d.ts +0 -27
- package/base-components/components/loading-bar/loading-bar.component.d.ts +0 -17
- package/base-components/components/model-form/model-form-base.component.d.ts +0 -64
- package/base-components/components/model-form/model-form.component.d.ts +0 -139
- package/base-components/components/model-form-sub/model-form-sub.component.d.ts +0 -56
- package/base-components/components/model-table/model-table.component.d.ts +0 -115
- package/base-components/components/refence-input/refence-input.component.d.ts +0 -84
- package/base-components/components/select/select.component.d.ts +0 -25
- package/base-components/components/skeleton-loader/skeleton-loader.component.d.ts +0 -10
- package/base-components/components/tags/tags.component.d.ts +0 -60
- package/base-components/components/textarea/textarea.component.d.ts +0 -21
- package/base-components/components/toast/toast.component.d.ts +0 -19
- package/base-components/components/upload-image/upload-image.component.d.ts +0 -111
- package/base-components/directives/back-button.directive.d.ts +0 -9
- package/base-components/directives/context-menu.directive.d.ts +0 -22
- package/base-components/directives/sort.directive.d.ts +0 -15
- package/base-components/directives/stop-propagation.directive.d.ts +0 -10
- package/base-components/index.d.ts +0 -5
- package/base-components/pipes/ellipses.pipe.d.ts +0 -10
- package/base-components/public-api.d.ts +0 -26
- package/base-prototype/index.d.ts +0 -5
- package/base-prototype/pages/email-verification/email-verification.component.d.ts +0 -18
- package/base-prototype/pages/forgot-password/forgot-password.component.d.ts +0 -26
- package/base-prototype/pages/login/login.component.d.ts +0 -33
- package/base-prototype/pages/profile/profile.component.d.ts +0 -24
- package/base-prototype/pages/register/register.component.d.ts +0 -31
- package/base-prototype/pages/set-password/set-password.component.d.ts +0 -29
- package/base-prototype/public-api.d.ts +0 -9
- package/esm2022/base-cms/interfaces/base-cms-module-config.interface.mjs +0 -3
- package/esm2022/base-cms/lenne.tech-ng-base-base-cms.mjs +0 -5
- package/esm2022/base-cms/pages/base-cms/base-cms.component.mjs +0 -238
- package/esm2022/base-cms/public-api.mjs +0 -8
- package/esm2022/base-components/components/breadcrumb/breadcrumb.component.mjs +0 -23
- package/esm2022/base-components/components/change-password/change-password.component.mjs +0 -97
- package/esm2022/base-components/components/checkbox/checkbox.component.mjs +0 -38
- package/esm2022/base-components/components/delete-account/delete-account.component.mjs +0 -59
- package/esm2022/base-components/components/fab-button/fab-button.component.mjs +0 -24
- package/esm2022/base-components/components/input/input.component.mjs +0 -75
- package/esm2022/base-components/components/loading-bar/loading-bar.component.mjs +0 -37
- package/esm2022/base-components/components/model-form/model-form-base.component.mjs +0 -145
- package/esm2022/base-components/components/model-form/model-form.component.mjs +0 -591
- package/esm2022/base-components/components/model-form-sub/model-form-sub.component.mjs +0 -117
- package/esm2022/base-components/components/model-table/model-table.component.mjs +0 -478
- package/esm2022/base-components/components/refence-input/refence-input.component.mjs +0 -278
- package/esm2022/base-components/components/select/select.component.mjs +0 -62
- package/esm2022/base-components/components/skeleton-loader/skeleton-loader.component.mjs +0 -33
- package/esm2022/base-components/components/tags/tags.component.mjs +0 -227
- package/esm2022/base-components/components/textarea/textarea.component.mjs +0 -79
- package/esm2022/base-components/components/toast/toast.component.mjs +0 -69
- package/esm2022/base-components/components/upload-image/upload-image.component.mjs +0 -346
- package/esm2022/base-components/directives/back-button.directive.mjs +0 -25
- package/esm2022/base-components/directives/context-menu.directive.mjs +0 -112
- package/esm2022/base-components/directives/sort.directive.mjs +0 -61
- package/esm2022/base-components/directives/stop-propagation.directive.mjs +0 -24
- package/esm2022/base-components/lenne.tech-ng-base-base-components.mjs +0 -5
- package/esm2022/base-components/pipes/ellipses.pipe.mjs +0 -23
- package/esm2022/base-components/public-api.mjs +0 -30
- package/esm2022/base-prototype/lenne.tech-ng-base-base-prototype.mjs +0 -5
- package/esm2022/base-prototype/pages/email-verification/email-verification.component.mjs +0 -60
- package/esm2022/base-prototype/pages/forgot-password/forgot-password.component.mjs +0 -78
- package/esm2022/base-prototype/pages/login/login.component.mjs +0 -114
- package/esm2022/base-prototype/pages/profile/profile.component.mjs +0 -87
- package/esm2022/base-prototype/pages/register/register.component.mjs +0 -100
- package/esm2022/base-prototype/pages/set-password/set-password.component.mjs +0 -91
- package/esm2022/base-prototype/public-api.mjs +0 -11
- package/esm2022/lenne.tech-ng-base.mjs +0 -5
- package/esm2022/public-api.mjs +0 -25
- package/esm2022/shared/classes/auth.class.mjs +0 -14
- package/esm2022/shared/classes/basic-user.class.mjs +0 -49
- package/esm2022/shared/classes/graphql-enum.class.mjs +0 -10
- package/esm2022/shared/classes/graphql-meta.class.mjs +0 -345
- package/esm2022/shared/classes/graphql-type.class.mjs +0 -14
- package/esm2022/shared/classes/helper.class.mjs +0 -307
- package/esm2022/shared/classes/sort.class.mjs +0 -38
- package/esm2022/shared/classes/standard.class.mjs +0 -40
- package/esm2022/shared/decorators/debounce.decorator.mjs +0 -12
- package/esm2022/shared/enums/comparison-operator.enum.mjs +0 -16
- package/esm2022/shared/enums/graphql-request-type.enum.mjs +0 -10
- package/esm2022/shared/enums/logical-operator.enum.mjs +0 -10
- package/esm2022/shared/enums/skeleton-type.enum.mjs +0 -7
- package/esm2022/shared/enums/sort-order.enum.mjs +0 -6
- package/esm2022/shared/enums/toast-type.enum.mjs +0 -8
- package/esm2022/shared/functions/ws-client.function.mjs +0 -39
- package/esm2022/shared/interfaces/base-module-config.interface.mjs +0 -3
- package/esm2022/shared/interfaces/breadcrumb.interface.mjs +0 -2
- package/esm2022/shared/interfaces/can-component-deactivate.interface.mjs +0 -2
- package/esm2022/shared/interfaces/cms-enum-values.interface.mjs +0 -2
- package/esm2022/shared/interfaces/cms-field-config.interface.mjs +0 -2
- package/esm2022/shared/interfaces/cms-model-config.interface.mjs +0 -2
- package/esm2022/shared/interfaces/cms-table-field.interface.mjs +0 -2
- package/esm2022/shared/interfaces/combined-filter-input.interface.mjs +0 -2
- package/esm2022/shared/interfaces/compress-options.interface.mjs +0 -2
- package/esm2022/shared/interfaces/cropping-options.interface.mjs +0 -2
- package/esm2022/shared/interfaces/field-object.interface.mjs +0 -2
- package/esm2022/shared/interfaces/field.interface.mjs +0 -2
- package/esm2022/shared/interfaces/filter-input.interface.mjs +0 -2
- package/esm2022/shared/interfaces/find-args.interface.mjs +0 -2
- package/esm2022/shared/interfaces/graphql-crud-type.interface.mjs +0 -2
- package/esm2022/shared/interfaces/graphql-fields-object.interface.mjs +0 -2
- package/esm2022/shared/interfaces/graphql-options.interface.mjs +0 -2
- package/esm2022/shared/interfaces/graphql-plus-options.interfacen.mjs +0 -2
- package/esm2022/shared/interfaces/graphql-type-collection.interface.mjs +0 -2
- package/esm2022/shared/interfaces/login-config.interface.mjs +0 -2
- package/esm2022/shared/interfaces/register-config.interface.mjs +0 -2
- package/esm2022/shared/interfaces/single-filter-input.interface.mjs +0 -2
- package/esm2022/shared/interfaces/sort-input.interface.mjs +0 -2
- package/esm2022/shared/interfaces/time-components.interface.mjs +0 -2
- package/esm2022/shared/interfaces/toast.interface.mjs +0 -2
- package/esm2022/shared/lenne.tech-ng-base-shared.mjs +0 -5
- package/esm2022/shared/public-api.mjs +0 -74
- package/esm2022/shared/services/auth.service.mjs +0 -152
- package/esm2022/shared/services/breadcrumb.service.mjs +0 -69
- package/esm2022/shared/services/cms.service.mjs +0 -82
- package/esm2022/shared/services/file.service.mjs +0 -86
- package/esm2022/shared/services/forms.service.mjs +0 -61
- package/esm2022/shared/services/graphql-meta.service.mjs +0 -132
- package/esm2022/shared/services/graphql-plus.service.mjs +0 -93
- package/esm2022/shared/services/graphql.service.mjs +0 -510
- package/esm2022/shared/services/image.service.mjs +0 -102
- package/esm2022/shared/services/loader.service.mjs +0 -78
- package/esm2022/shared/services/navigation.service.mjs +0 -38
- package/esm2022/shared/services/scroll.service.mjs +0 -207
- package/esm2022/shared/services/storage.service.mjs +0 -149
- package/esm2022/shared/services/toast.service.mjs +0 -39
- package/esm2022/shared/services/user.service.mjs +0 -160
- package/esm2022/shared/services/ws.service.mjs +0 -17
- package/esm2022/shared/types/graphql-fields.type.mjs +0 -2
- package/esm2022/shared/types/storage.type.mjs +0 -2
- package/esm2022/shared/validators/email.validator.mjs +0 -7
- package/esm2022/shared/validators/match.validator.mjs +0 -22
- package/esm2022/shared/validators/secure-password.validator.mjs +0 -7
- package/esm2022/src/base.module.mjs +0 -64
- package/esm2022/src/decorators/auto-unsubscribe.decorator.mjs +0 -23
- package/esm2022/src/directives/lazy-load.directive.mjs +0 -48
- package/esm2022/src/directives/match-height.directive.mjs +0 -92
- package/esm2022/src/directives/resizable.directive.mjs +0 -92
- package/esm2022/src/factories/apollo-options.factory.mjs +0 -108
- package/esm2022/src/functions/extract-files.function.mjs +0 -87
- package/esm2022/src/guards/auth.guard.mjs +0 -91
- package/esm2022/src/guards/can-deactivate.guard.mjs +0 -16
- package/esm2022/src/guards/logout.guard.mjs +0 -34
- package/esm2022/src/pipes/date-ago.pipe.mjs +0 -64
- package/esm2022/src/pipes/safe-html.pipe.mjs +0 -22
- package/esm2022/src/services/fullscreen.service.mjs +0 -51
- package/esm2022/src/services/seo.service.mjs +0 -109
- package/esm2022/src/services/theme.service.mjs +0 -44
- package/fesm2022/lenne.tech-ng-base-base-cms.mjs +0 -251
- package/fesm2022/lenne.tech-ng-base-base-cms.mjs.map +0 -1
- package/fesm2022/lenne.tech-ng-base-base-components.mjs +0 -2917
- package/fesm2022/lenne.tech-ng-base-base-components.mjs.map +0 -1
- package/fesm2022/lenne.tech-ng-base-base-prototype.mjs +0 -505
- package/fesm2022/lenne.tech-ng-base-base-prototype.mjs.map +0 -1
- package/fesm2022/lenne.tech-ng-base-shared.mjs +0 -2863
- package/fesm2022/lenne.tech-ng-base-shared.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/public-api.d.ts +0 -17
- package/shared/classes/auth.class.d.ts +0 -10
- package/shared/classes/basic-user.class.d.ts +0 -27
- package/shared/classes/graphql-enum.class.d.ts +0 -7
- package/shared/classes/graphql-meta.class.d.ts +0 -66
- package/shared/classes/graphql-type.class.d.ts +0 -13
- package/shared/classes/helper.class.d.ts +0 -99
- package/shared/classes/sort.class.d.ts +0 -12
- package/shared/classes/standard.class.d.ts +0 -32
- package/shared/decorators/debounce.decorator.d.ts +0 -1
- package/shared/enums/comparison-operator.enum.d.ts +0 -14
- package/shared/enums/graphql-request-type.enum.d.ts +0 -8
- package/shared/enums/logical-operator.enum.d.ts +0 -8
- package/shared/enums/skeleton-type.enum.d.ts +0 -5
- package/shared/enums/sort-order.enum.d.ts +0 -4
- package/shared/enums/toast-type.enum.d.ts +0 -6
- package/shared/functions/ws-client.function.d.ts +0 -5
- package/shared/index.d.ts +0 -5
- package/shared/interfaces/base-module-config.interface.d.ts +0 -61
- package/shared/interfaces/breadcrumb.interface.d.ts +0 -4
- package/shared/interfaces/can-component-deactivate.interface.d.ts +0 -7
- package/shared/interfaces/cms-enum-values.interface.d.ts +0 -4
- package/shared/interfaces/cms-field-config.interface.d.ts +0 -45
- package/shared/interfaces/cms-model-config.interface.d.ts +0 -14
- package/shared/interfaces/cms-table-field.interface.d.ts +0 -10
- package/shared/interfaces/combined-filter-input.interface.d.ts +0 -9
- package/shared/interfaces/compress-options.interface.d.ts +0 -15
- package/shared/interfaces/cropping-options.interface.d.ts +0 -12
- package/shared/interfaces/field-object.interface.d.ts +0 -6
- package/shared/interfaces/field.interface.d.ts +0 -5
- package/shared/interfaces/filter-input.interface.d.ts +0 -9
- package/shared/interfaces/find-args.interface.d.ts +0 -11
- package/shared/interfaces/graphql-crud-type.interface.d.ts +0 -7
- package/shared/interfaces/graphql-fields-object.interface.d.ts +0 -6
- package/shared/interfaces/graphql-options.interface.d.ts +0 -11
- package/shared/interfaces/graphql-plus-options.interfacen.d.ts +0 -9
- package/shared/interfaces/graphql-type-collection.interface.d.ts +0 -7
- package/shared/interfaces/login-config.interface.d.ts +0 -6
- package/shared/interfaces/register-config.interface.d.ts +0 -4
- package/shared/interfaces/single-filter-input.interface.d.ts +0 -11
- package/shared/interfaces/sort-input.interface.d.ts +0 -5
- package/shared/interfaces/time-components.interface.d.ts +0 -6
- package/shared/interfaces/toast.interface.d.ts +0 -8
- package/shared/public-api.d.ts +0 -65
- package/shared/services/auth.service.d.ts +0 -44
- package/shared/services/breadcrumb.service.d.ts +0 -32
- package/shared/services/cms.service.d.ts +0 -27
- package/shared/services/file.service.d.ts +0 -22
- package/shared/services/forms.service.d.ts +0 -14
- package/shared/services/graphql-meta.service.d.ts +0 -45
- package/shared/services/graphql-plus.service.d.ts +0 -27
- package/shared/services/graphql.service.d.ts +0 -71
- package/shared/services/image.service.d.ts +0 -27
- package/shared/services/loader.service.d.ts +0 -32
- package/shared/services/navigation.service.d.ts +0 -15
- package/shared/services/scroll.service.d.ts +0 -85
- package/shared/services/storage.service.d.ts +0 -49
- package/shared/services/toast.service.d.ts +0 -15
- package/shared/services/user.service.d.ts +0 -77
- package/shared/services/ws.service.d.ts +0 -8
- package/shared/types/graphql-fields.type.d.ts +0 -5
- package/shared/types/storage.type.d.ts +0 -4
- package/shared/validators/email.validator.d.ts +0 -1
- package/shared/validators/match.validator.d.ts +0 -4
- package/shared/validators/secure-password.validator.d.ts +0 -1
- package/src/base.module.d.ts +0 -16
- package/src/decorators/auto-unsubscribe.decorator.d.ts +0 -5
- package/src/directives/lazy-load.directive.d.ts +0 -17
- package/src/directives/match-height.directive.d.ts +0 -20
- package/src/directives/resizable.directive.d.ts +0 -26
- package/src/factories/apollo-options.factory.d.ts +0 -16
- package/src/functions/extract-files.function.d.ts +0 -15
- package/src/guards/auth.guard.d.ts +0 -27
- package/src/guards/can-deactivate.guard.d.ts +0 -10
- package/src/guards/logout.guard.d.ts +0 -16
- package/src/pipes/date-ago.pipe.d.ts +0 -34
- package/src/pipes/safe-html.pipe.d.ts +0 -13
- package/src/services/fullscreen.service.d.ts +0 -18
- package/src/services/seo.service.d.ts +0 -50
- package/src/services/theme.service.d.ts +0 -17
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
|
2
|
-
import { ToastType } from '@lenne.tech/ng-base/shared';
|
|
3
|
-
import { ImageCropperComponent } from 'ngx-image-cropper';
|
|
4
|
-
import { NgClass } from '@angular/common';
|
|
5
|
-
import { StopPropagationDirective } from '../../directives/stop-propagation.directive';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
import * as i1 from "@angular/common/http";
|
|
8
|
-
import * as i2 from "@lenne.tech/ng-base/shared";
|
|
9
|
-
export class UploadImageComponent {
|
|
10
|
-
httpClient;
|
|
11
|
-
authService;
|
|
12
|
-
fileService;
|
|
13
|
-
toastService;
|
|
14
|
-
fileInput;
|
|
15
|
-
id;
|
|
16
|
-
name;
|
|
17
|
-
infoText;
|
|
18
|
-
label;
|
|
19
|
-
supportText = 'Supports: JPEG, JPG, PNG';
|
|
20
|
-
required = false;
|
|
21
|
-
defaultDragText = 'Drag & Drop';
|
|
22
|
-
defaultReleaseText = 'Release to Upload';
|
|
23
|
-
preButtonText = 'or';
|
|
24
|
-
buttonText = 'browse';
|
|
25
|
-
validExtensions = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp'];
|
|
26
|
-
control;
|
|
27
|
-
url = 'http://localhost:3000';
|
|
28
|
-
uploadPath = '/files/upload';
|
|
29
|
-
deletePath = '/files/';
|
|
30
|
-
path = '/files/';
|
|
31
|
-
compressOptions;
|
|
32
|
-
maxSize;
|
|
33
|
-
uploadDirectly = false;
|
|
34
|
-
croppingImage = false;
|
|
35
|
-
croppingOptions;
|
|
36
|
-
objectPath;
|
|
37
|
-
mode = 'file';
|
|
38
|
-
imageUploaded = new EventEmitter();
|
|
39
|
-
imageDeleted = new EventEmitter();
|
|
40
|
-
fileChanged = new EventEmitter();
|
|
41
|
-
dragActive = false;
|
|
42
|
-
dragText = 'Drag & Drop';
|
|
43
|
-
selectedFile;
|
|
44
|
-
croppedFile;
|
|
45
|
-
fileUrl;
|
|
46
|
-
loading = false;
|
|
47
|
-
croppedInProgress = false;
|
|
48
|
-
fileEvent;
|
|
49
|
-
cOptions;
|
|
50
|
-
constructor(httpClient, authService, fileService, toastService) {
|
|
51
|
-
this.httpClient = httpClient;
|
|
52
|
-
this.authService = authService;
|
|
53
|
-
this.fileService = fileService;
|
|
54
|
-
this.toastService = toastService;
|
|
55
|
-
}
|
|
56
|
-
ngOnInit() {
|
|
57
|
-
// Set default options for cropping
|
|
58
|
-
this.cOptions = {
|
|
59
|
-
maintainAspectRatio: true,
|
|
60
|
-
aspectRatio: 4 / 3,
|
|
61
|
-
onlyScaleDown: false,
|
|
62
|
-
imageQuality: 92,
|
|
63
|
-
autoCrop: true,
|
|
64
|
-
alignImage: 'center',
|
|
65
|
-
format: 'jpeg',
|
|
66
|
-
...this.croppingOptions,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* The dragOver function is called when the user drags a file over the dropzone. It prevents the default action of the
|
|
71
|
-
* event, and sets the dragText to 'Release to Upload' and the dragActive to true
|
|
72
|
-
*
|
|
73
|
-
* @param event - any - This is the event that is triggered when the user drags a file over the dropzone.
|
|
74
|
-
*/
|
|
75
|
-
dragOver(event) {
|
|
76
|
-
event.preventDefault();
|
|
77
|
-
this.dragText = this.defaultReleaseText;
|
|
78
|
-
this.dragActive = true;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* When the user drags a file over the drop zone, the dragActive variable is set to true, which will change the color of
|
|
82
|
-
* the drop zone to green
|
|
83
|
-
*
|
|
84
|
-
* @param event - The event object that is passed to the dragLeave event.
|
|
85
|
-
*/
|
|
86
|
-
dragLeave(event) {
|
|
87
|
-
this.dragText = this.defaultDragText;
|
|
88
|
-
this.dragActive = false;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* The function takes an event as a parameter, prevents the default action of the event, sets the URL of the image to the
|
|
92
|
-
* file that was dragged and dropped, sets the text of the drag and drop area to the default text, and sets the
|
|
93
|
-
* dragActive variable to false
|
|
94
|
-
*
|
|
95
|
-
* @param event - any - This is the event that is triggered when the user drags and drops a file.
|
|
96
|
-
*/
|
|
97
|
-
drop(event) {
|
|
98
|
-
event.preventDefault();
|
|
99
|
-
this.fileInput.nativeElement.files = event.dataTransfer.files;
|
|
100
|
-
const e = new Event('change');
|
|
101
|
-
this.fileInput.nativeElement.dispatchEvent(e);
|
|
102
|
-
this.dragText = 'Drag & Drop';
|
|
103
|
-
this.dragActive = false;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* It takes a file as an argument, checks if the file type is valid, and if it is, it creates a new FileReader object,
|
|
107
|
-
* sets the onload function to set the fileUrl to the result of the fileReader, sets the selectedFile to the file, and
|
|
108
|
-
* calls the upload function
|
|
109
|
-
*
|
|
110
|
-
* @param file - any - this is the file that is selected by the user.
|
|
111
|
-
*/
|
|
112
|
-
setUrl(file) {
|
|
113
|
-
const fileReader = new FileReader();
|
|
114
|
-
fileReader.onload = (result) => {
|
|
115
|
-
this.loading = true;
|
|
116
|
-
this.fileUrl = fileReader.result;
|
|
117
|
-
this.selectedFile = file;
|
|
118
|
-
this.upload();
|
|
119
|
-
};
|
|
120
|
-
fileReader.readAsDataURL(file);
|
|
121
|
-
}
|
|
122
|
-
checkFile(file) {
|
|
123
|
-
if (this.maxSize && file.size > this.maxSize) {
|
|
124
|
-
this.toastService.show({
|
|
125
|
-
id: 'image-invalid-size',
|
|
126
|
-
type: ToastType.ERROR,
|
|
127
|
-
title: 'Fehlgeschlagen',
|
|
128
|
-
description: 'Die Datei ist zu groß. Die Datei darf nicht größer als ' +
|
|
129
|
-
(this.maxSize / (1024 * 1024)).toFixed(2) +
|
|
130
|
-
'MB sein.',
|
|
131
|
-
}, 3500);
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
if (this.validExtensions.includes(file?.type)) {
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
this.toastService.show({
|
|
140
|
-
id: 'image-invalid-format',
|
|
141
|
-
type: ToastType.ERROR,
|
|
142
|
-
title: 'Fehlgeschlagen',
|
|
143
|
-
description: 'Das Format der Datei wird nicht unterstützt.',
|
|
144
|
-
}, 3500);
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* The function takes an event as an argument, and then sets the url of the file to the first file in the event's
|
|
151
|
-
* target's files array
|
|
152
|
-
*
|
|
153
|
-
* @param event - any - The event that is triggered when the user selects a file.
|
|
154
|
-
*/
|
|
155
|
-
selectFile(event) {
|
|
156
|
-
if (!this.checkFile(event.target.files[0])) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
if (this.croppingImage) {
|
|
160
|
-
this.croppedInProgress = true;
|
|
161
|
-
this.fileEvent = event;
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
this.setUrl(event.target.files[0]);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* We create a new FormData object, append the selected file to it, and then send it to the server
|
|
169
|
-
*/
|
|
170
|
-
async upload() {
|
|
171
|
-
// Prepare file data
|
|
172
|
-
let file = this.selectedFile;
|
|
173
|
-
if (this.compressOptions) {
|
|
174
|
-
file = await this.fileService.compress(file, this.compressOptions);
|
|
175
|
-
}
|
|
176
|
-
const fileData = {
|
|
177
|
-
field: this.objectPath ? this.objectPath + '.' + this.id : this.id,
|
|
178
|
-
file,
|
|
179
|
-
base64: await this.getBase64(file),
|
|
180
|
-
};
|
|
181
|
-
// Emit file data
|
|
182
|
-
this.fileChanged.emit(fileData);
|
|
183
|
-
// Set control value and upload directly if required
|
|
184
|
-
if (this.uploadDirectly) {
|
|
185
|
-
const result = await this.fileService.upload(this.url, this.uploadPath, this.selectedFile);
|
|
186
|
-
if (result?.id) {
|
|
187
|
-
this.control.setValue(result.id);
|
|
188
|
-
this.imageUploaded.emit(result.id);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
this.control.setValue(this.mode === 'base64' ? fileData.base64 : this.selectedFile);
|
|
193
|
-
}
|
|
194
|
-
// Final processes
|
|
195
|
-
this.control.markAsTouched();
|
|
196
|
-
this.loading = false;
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* It deletes the file from the server and sets the selectedFile and fileUrl to null
|
|
200
|
-
*
|
|
201
|
-
* @param [id] - The id of the file to delete.
|
|
202
|
-
*/
|
|
203
|
-
async deleteFile(id) {
|
|
204
|
-
if (!this.uploadDirectly) {
|
|
205
|
-
this.selectedFile = null;
|
|
206
|
-
this.fileUrl = null;
|
|
207
|
-
this.control.setValue('');
|
|
208
|
-
this.control.markAsTouched();
|
|
209
|
-
this.fileChanged.emit({
|
|
210
|
-
field: this.objectPath ? this.objectPath + '.' + this.id : this.id,
|
|
211
|
-
file: null,
|
|
212
|
-
base64: null,
|
|
213
|
-
});
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
this.loading = true;
|
|
217
|
-
this.selectedFile = null;
|
|
218
|
-
this.fileUrl = null;
|
|
219
|
-
if (id) {
|
|
220
|
-
const result = await this.fileService.delete(this.url, this.deletePath, id);
|
|
221
|
-
if (result) {
|
|
222
|
-
this.selectedFile = null;
|
|
223
|
-
this.fileUrl = null;
|
|
224
|
-
this.control.setValue('');
|
|
225
|
-
this.imageDeleted.emit();
|
|
226
|
-
this.loading = false;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Convert a file into a BASE64 encoded string
|
|
232
|
-
*/
|
|
233
|
-
getBase64(file) {
|
|
234
|
-
return new Promise((resolve, reject) => {
|
|
235
|
-
if (!file) {
|
|
236
|
-
return resolve(null);
|
|
237
|
-
}
|
|
238
|
-
const reader = new FileReader();
|
|
239
|
-
reader.readAsDataURL(file);
|
|
240
|
-
reader.onload = () => {
|
|
241
|
-
if (!reader.result) {
|
|
242
|
-
return reject(new Error('Conversion failed'));
|
|
243
|
-
}
|
|
244
|
-
resolve(reader.result.toString());
|
|
245
|
-
};
|
|
246
|
-
reader.onerror = (error) => {
|
|
247
|
-
reject(error);
|
|
248
|
-
};
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
base64ToFile(base64, fileName, fileType) {
|
|
252
|
-
return new Promise((resolve, reject) => {
|
|
253
|
-
fetch(base64)
|
|
254
|
-
.then((res) => res.blob())
|
|
255
|
-
.then((blob) => {
|
|
256
|
-
resolve(new File([blob], fileName, { type: fileType }));
|
|
257
|
-
}, (err) => {
|
|
258
|
-
reject(err);
|
|
259
|
-
});
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
async imageCropped($event, fileEvent) {
|
|
263
|
-
const file = fileEvent.target.files[0];
|
|
264
|
-
this.croppedFile = await this.base64ToFile($event.base64, file.name, file.type);
|
|
265
|
-
}
|
|
266
|
-
finishedCropping() {
|
|
267
|
-
this.fileEvent = null;
|
|
268
|
-
this.setUrl(this.croppedFile);
|
|
269
|
-
this.croppedInProgress = false;
|
|
270
|
-
this.croppedFile = null;
|
|
271
|
-
}
|
|
272
|
-
loadImageFailed() {
|
|
273
|
-
this.toastService.show({
|
|
274
|
-
id: 'image-invalid-cropped',
|
|
275
|
-
type: ToastType.ERROR,
|
|
276
|
-
title: 'Fehlgeschlagen',
|
|
277
|
-
description: 'Es ist ein Fehler aufgetreten. Bitte probieren Sie es später erneut oder wenden Sie sich an den Support.',
|
|
278
|
-
}, 3500);
|
|
279
|
-
}
|
|
280
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: UploadImageComponent, deps: [{ token: i1.HttpClient }, { token: i2.AuthService }, { token: i2.FileService }, { token: i2.ToastService }], target: i0.ɵɵFactoryTarget.Component });
|
|
281
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.2", type: UploadImageComponent, isStandalone: true, selector: "base-upload-image", inputs: { id: "id", name: "name", infoText: "infoText", label: "label", supportText: "supportText", required: "required", defaultDragText: "defaultDragText", defaultReleaseText: "defaultReleaseText", preButtonText: "preButtonText", buttonText: "buttonText", validExtensions: "validExtensions", control: "control", url: "url", uploadPath: "uploadPath", deletePath: "deletePath", path: "path", compressOptions: "compressOptions", maxSize: "maxSize", uploadDirectly: "uploadDirectly", croppingImage: "croppingImage", croppingOptions: "croppingOptions", objectPath: "objectPath", mode: "mode" }, outputs: { imageUploaded: "imageUploaded", imageDeleted: "imageDeleted", fileChanged: "fileChanged" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"form-group mt-3\" [ngClass]=\"{ 'is-invalid': control?.invalid && control?.touched }\">\n <div class=\"d-flex justify-content-between align-items-center\">\n @if (label) {\n <label [for]=\"id\" class=\"form-label\" [ngClass]=\"{ required: required }\">{{ label }}</label>\n }\n @if (infoText) {\n <i class=\"bi bi-info-circle\" [ngbTooltip]=\"infoText\" placement=\"start\"></i>\n }\n </div>\n\n <div\n [id]=\"objectPath ? objectPath + '.' + id : id\"\n class=\"drag-area\"\n (dragover)=\"dragOver($event)\"\n (dragleave)=\"dragLeave($event)\"\n (drop)=\"drop($event)\"\n [ngClass]=\"{ active: dragActive, pointer: !loading, 'is-invalid': control?.invalid && control?.touched }\"\n (click)=\"!croppedInProgress && !loading && fileInput.click()\"\n >\n @if (loading) {\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n }\n\n @if (selectedFile && !fileEvent && !croppedInProgress && !loading) {\n @if (selectedFile) {\n <img [src]=\"fileUrl\" />\n }\n <button class=\"btn btn-danger\" type=\"button\" (click)=\"deleteFile()\" baseStopPropagation>L\u00F6schen</button>\n }\n\n @if (control?.value && !fileEvent && !selectedFile && !loading && !croppedInProgress) {\n <img [src]=\"control?.value.startsWith('data:') ? control?.value : url + path + control?.value\" />\n <button class=\"btn btn-danger\" type=\"button\" (click)=\"deleteFile(control?.value)\" baseStopPropagation>\n L\u00F6schen\n </button>\n }\n\n @if (!selectedFile && !control?.value && !loading && !fileEvent) {\n <div class=\"icon\">\n <i class=\"bi bi-images\"></i>\n </div>\n <span class=\"header\">{{ dragText }}</span>\n <span class=\"header\"\n >{{ preButtonText }}\n <span class=\"button\" (click)=\"fileInput.click()\" baseStopPropagation>{{ buttonText }}</span></span\n >\n <span class=\"support\" [innerText]=\"supportText\"></span>\n }\n\n <input type=\"file\" (change)=\"selectFile($event)\" [attr.accept]=\"validExtensions?.join(',')\" hidden #fileInput />\n\n @if (croppedInProgress && fileEvent) {\n <image-cropper\n [imageChangedEvent]=\"fileEvent\"\n [maintainAspectRatio]=\"cOptions.maintainAspectRatio\"\n [aspectRatio]=\"cOptions.aspectRatio\"\n [alignImage]=\"cOptions.alignImage\"\n [resizeToWidth]=\"cOptions.resizeToWidth\"\n [resizeToHeight]=\"cOptions.resizeToHeight\"\n [autoCrop]=\"cOptions.autoCrop\"\n [imageQuality]=\"cOptions.imageQuality\"\n [onlyScaleDown]=\"cOptions.onlyScaleDown\"\n [format]=\"cOptions.format\"\n (imageCropped)=\"imageCropped($event, fileEvent)\"\n (loadImageFailed)=\"loadImageFailed()\"\n ></image-cropper>\n <button class=\"btn btn-primary mt-2\" type=\"button\" (click)=\"finishedCropping()\" baseStopPropagation>\n Zuschneiden\n </button>\n }\n </div>\n\n @if (control?.invalid && (control?.dirty || control?.touched)) {\n <div class=\"invalid-feedback m-2\">\n @if (control?.errors?.['required']) {\n <div>Dieses Feld ist ein Pflichtfeld.</div>\n }\n </div>\n }\n </div>\n", styles: [":host{--base-upload-image-area-bg: #ffffff;--base-upload-image-area-border-color: #e1e1e1;--base-upload-image-area-height: 400px}.is-invalid .drag-area{border-color:var(--bs-danger)}.is-invalid .invalid-feedback{display:block}.required:after{content:\" *\"}.drag-area{height:var(--base-upload-image-area-height);border:2px dashed var(--base-upload-image-area-border-color);background-color:var(--base-upload-image-area-bg);display:flex;flex-direction:column;justify-content:center;align-items:center;margin:10px auto;padding:20px}.drag-area img{height:100%;max-height:280px;max-width:100%;object-fit:scale-down}.drag-area .btn-danger{margin-top:auto}.drag-area .icon{font-size:50px;color:var(--bs-primary)}.drag-area .header{font-size:20px;font-weight:500}.drag-area .support{font-size:12px;color:#e1e1e1;margin:10px 0 15px}.drag-area .button{font-size:20px;font-weight:500;color:var(--bs-primary);cursor:pointer}.active{border:2px solid var(--bs-primary)}.pointer{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "cropperFrameAriaLabel", "output", "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: "directive", type: StopPropagationDirective, selector: "[baseStopPropagation]" }] });
|
|
282
|
-
}
|
|
283
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: UploadImageComponent, decorators: [{
|
|
284
|
-
type: Component,
|
|
285
|
-
args: [{ selector: 'base-upload-image', standalone: true, imports: [
|
|
286
|
-
NgClass,
|
|
287
|
-
ImageCropperComponent,
|
|
288
|
-
StopPropagationDirective
|
|
289
|
-
], template: "<div class=\"form-group mt-3\" [ngClass]=\"{ 'is-invalid': control?.invalid && control?.touched }\">\n <div class=\"d-flex justify-content-between align-items-center\">\n @if (label) {\n <label [for]=\"id\" class=\"form-label\" [ngClass]=\"{ required: required }\">{{ label }}</label>\n }\n @if (infoText) {\n <i class=\"bi bi-info-circle\" [ngbTooltip]=\"infoText\" placement=\"start\"></i>\n }\n </div>\n\n <div\n [id]=\"objectPath ? objectPath + '.' + id : id\"\n class=\"drag-area\"\n (dragover)=\"dragOver($event)\"\n (dragleave)=\"dragLeave($event)\"\n (drop)=\"drop($event)\"\n [ngClass]=\"{ active: dragActive, pointer: !loading, 'is-invalid': control?.invalid && control?.touched }\"\n (click)=\"!croppedInProgress && !loading && fileInput.click()\"\n >\n @if (loading) {\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n }\n\n @if (selectedFile && !fileEvent && !croppedInProgress && !loading) {\n @if (selectedFile) {\n <img [src]=\"fileUrl\" />\n }\n <button class=\"btn btn-danger\" type=\"button\" (click)=\"deleteFile()\" baseStopPropagation>L\u00F6schen</button>\n }\n\n @if (control?.value && !fileEvent && !selectedFile && !loading && !croppedInProgress) {\n <img [src]=\"control?.value.startsWith('data:') ? control?.value : url + path + control?.value\" />\n <button class=\"btn btn-danger\" type=\"button\" (click)=\"deleteFile(control?.value)\" baseStopPropagation>\n L\u00F6schen\n </button>\n }\n\n @if (!selectedFile && !control?.value && !loading && !fileEvent) {\n <div class=\"icon\">\n <i class=\"bi bi-images\"></i>\n </div>\n <span class=\"header\">{{ dragText }}</span>\n <span class=\"header\"\n >{{ preButtonText }}\n <span class=\"button\" (click)=\"fileInput.click()\" baseStopPropagation>{{ buttonText }}</span></span\n >\n <span class=\"support\" [innerText]=\"supportText\"></span>\n }\n\n <input type=\"file\" (change)=\"selectFile($event)\" [attr.accept]=\"validExtensions?.join(',')\" hidden #fileInput />\n\n @if (croppedInProgress && fileEvent) {\n <image-cropper\n [imageChangedEvent]=\"fileEvent\"\n [maintainAspectRatio]=\"cOptions.maintainAspectRatio\"\n [aspectRatio]=\"cOptions.aspectRatio\"\n [alignImage]=\"cOptions.alignImage\"\n [resizeToWidth]=\"cOptions.resizeToWidth\"\n [resizeToHeight]=\"cOptions.resizeToHeight\"\n [autoCrop]=\"cOptions.autoCrop\"\n [imageQuality]=\"cOptions.imageQuality\"\n [onlyScaleDown]=\"cOptions.onlyScaleDown\"\n [format]=\"cOptions.format\"\n (imageCropped)=\"imageCropped($event, fileEvent)\"\n (loadImageFailed)=\"loadImageFailed()\"\n ></image-cropper>\n <button class=\"btn btn-primary mt-2\" type=\"button\" (click)=\"finishedCropping()\" baseStopPropagation>\n Zuschneiden\n </button>\n }\n </div>\n\n @if (control?.invalid && (control?.dirty || control?.touched)) {\n <div class=\"invalid-feedback m-2\">\n @if (control?.errors?.['required']) {\n <div>Dieses Feld ist ein Pflichtfeld.</div>\n }\n </div>\n }\n </div>\n", styles: [":host{--base-upload-image-area-bg: #ffffff;--base-upload-image-area-border-color: #e1e1e1;--base-upload-image-area-height: 400px}.is-invalid .drag-area{border-color:var(--bs-danger)}.is-invalid .invalid-feedback{display:block}.required:after{content:\" *\"}.drag-area{height:var(--base-upload-image-area-height);border:2px dashed var(--base-upload-image-area-border-color);background-color:var(--base-upload-image-area-bg);display:flex;flex-direction:column;justify-content:center;align-items:center;margin:10px auto;padding:20px}.drag-area img{height:100%;max-height:280px;max-width:100%;object-fit:scale-down}.drag-area .btn-danger{margin-top:auto}.drag-area .icon{font-size:50px;color:var(--bs-primary)}.drag-area .header{font-size:20px;font-weight:500}.drag-area .support{font-size:12px;color:#e1e1e1;margin:10px 0 15px}.drag-area .button{font-size:20px;font-weight:500;color:var(--bs-primary);cursor:pointer}.active{border:2px solid var(--bs-primary)}.pointer{cursor:pointer}\n"] }]
|
|
290
|
-
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.AuthService }, { type: i2.FileService }, { type: i2.ToastService }], propDecorators: { fileInput: [{
|
|
291
|
-
type: ViewChild,
|
|
292
|
-
args: ['fileInput']
|
|
293
|
-
}], id: [{
|
|
294
|
-
type: Input
|
|
295
|
-
}], name: [{
|
|
296
|
-
type: Input
|
|
297
|
-
}], infoText: [{
|
|
298
|
-
type: Input
|
|
299
|
-
}], label: [{
|
|
300
|
-
type: Input
|
|
301
|
-
}], supportText: [{
|
|
302
|
-
type: Input
|
|
303
|
-
}], required: [{
|
|
304
|
-
type: Input
|
|
305
|
-
}], defaultDragText: [{
|
|
306
|
-
type: Input
|
|
307
|
-
}], defaultReleaseText: [{
|
|
308
|
-
type: Input
|
|
309
|
-
}], preButtonText: [{
|
|
310
|
-
type: Input
|
|
311
|
-
}], buttonText: [{
|
|
312
|
-
type: Input
|
|
313
|
-
}], validExtensions: [{
|
|
314
|
-
type: Input
|
|
315
|
-
}], control: [{
|
|
316
|
-
type: Input
|
|
317
|
-
}], url: [{
|
|
318
|
-
type: Input
|
|
319
|
-
}], uploadPath: [{
|
|
320
|
-
type: Input
|
|
321
|
-
}], deletePath: [{
|
|
322
|
-
type: Input
|
|
323
|
-
}], path: [{
|
|
324
|
-
type: Input
|
|
325
|
-
}], compressOptions: [{
|
|
326
|
-
type: Input
|
|
327
|
-
}], maxSize: [{
|
|
328
|
-
type: Input
|
|
329
|
-
}], uploadDirectly: [{
|
|
330
|
-
type: Input
|
|
331
|
-
}], croppingImage: [{
|
|
332
|
-
type: Input
|
|
333
|
-
}], croppingOptions: [{
|
|
334
|
-
type: Input
|
|
335
|
-
}], objectPath: [{
|
|
336
|
-
type: Input
|
|
337
|
-
}], mode: [{
|
|
338
|
-
type: Input
|
|
339
|
-
}], imageUploaded: [{
|
|
340
|
-
type: Output
|
|
341
|
-
}], imageDeleted: [{
|
|
342
|
-
type: Output
|
|
343
|
-
}], fileChanged: [{
|
|
344
|
-
type: Output
|
|
345
|
-
}] } });
|
|
346
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLWltYWdlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWJhc2UvYmFzZS1jb21wb25lbnRzL2NvbXBvbmVudHMvdXBsb2FkLWltYWdlL3VwbG9hZC1pbWFnZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1iYXNlL2Jhc2UtY29tcG9uZW50cy9jb21wb25lbnRzL3VwbG9hZC1pbWFnZS91cGxvYWQtaW1hZ2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdEcsT0FBTyxFQU1MLFNBQVMsRUFDVixNQUFNLDRCQUE0QixDQUFDO0FBQ3BDLE9BQU8sRUFBcUIscUJBQXFCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3RSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNkNBQTZDLENBQUM7Ozs7QUFhdkYsTUFBTSxPQUFPLG9CQUFvQjtJQTBDckI7SUFDQTtJQUNBO0lBQ0E7SUE1Q2MsU0FBUyxDQUFhO0lBRXJDLEVBQUUsQ0FBUztJQUNYLElBQUksQ0FBUztJQUNiLFFBQVEsQ0FBUztJQUNqQixLQUFLLENBQVU7SUFDZixXQUFXLEdBQUcsMEJBQTBCLENBQUM7SUFDekMsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUNqQixlQUFlLEdBQUcsYUFBYSxDQUFDO0lBQ2hDLGtCQUFrQixHQUFHLG1CQUFtQixDQUFDO0lBQ3pDLGFBQWEsR0FBRyxJQUFJLENBQUM7SUFDckIsVUFBVSxHQUFHLFFBQVEsQ0FBQztJQUN0QixlQUFlLEdBQUcsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUN6RSxPQUFPLENBQU07SUFDYixHQUFHLEdBQUcsdUJBQXVCLENBQUM7SUFDOUIsVUFBVSxHQUFHLGVBQWUsQ0FBQztJQUM3QixVQUFVLEdBQUcsU0FBUyxDQUFDO0lBQ3ZCLElBQUksR0FBRyxTQUFTLENBQUM7SUFDakIsZUFBZSxDQUFrQjtJQUNqQyxPQUFPLENBQVM7SUFDaEIsY0FBYyxHQUFHLEtBQUssQ0FBQztJQUN2QixhQUFhLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLGVBQWUsQ0FBa0I7SUFDakMsVUFBVSxDQUFTO0lBQ25CLElBQUksR0FBc0IsTUFBTSxDQUFDO0lBRWhDLGFBQWEsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBQ25DLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBQ2xDLFdBQVcsR0FBRyxJQUFJLFlBQVksRUFBK0QsQ0FBQztJQUV4RyxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQ25CLFFBQVEsR0FBRyxhQUFhLENBQUM7SUFDekIsWUFBWSxDQUFPO0lBQ25CLFdBQVcsQ0FBTztJQUNsQixPQUFPLENBQVM7SUFDaEIsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUNoQixpQkFBaUIsR0FBRyxLQUFLLENBQUM7SUFDMUIsU0FBUyxDQUFNO0lBQ2YsUUFBUSxDQUFrQjtJQUUxQixZQUNVLFVBQXNCLEVBQ3RCLFdBQXdCLEVBQ3hCLFdBQXdCLEVBQ3hCLFlBQTBCO1FBSDFCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsaUJBQVksR0FBWixZQUFZLENBQWM7SUFDakMsQ0FBQztJQUVKLFFBQVE7UUFDTixtQ0FBbUM7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRztZQUNkLG1CQUFtQixFQUFFLElBQUk7WUFDekIsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDO1lBQ2xCLGFBQWEsRUFBRSxLQUFLO1lBQ3BCLFlBQVksRUFBRSxFQUFFO1lBQ2hCLFFBQVEsRUFBRSxJQUFJO1lBQ2QsVUFBVSxFQUFFLFFBQVE7WUFDcEIsTUFBTSxFQUFFLE1BQU07WUFDZCxHQUFHLElBQUksQ0FBQyxlQUFlO1NBQ3hCLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxRQUFRLENBQUMsS0FBVTtRQUNqQixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFDeEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsU0FBUyxDQUFDLEtBQVU7UUFDbEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxJQUFJLENBQUMsS0FBVTtRQUNiLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUM7UUFDOUQsTUFBTSxDQUFDLEdBQUcsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTlDLElBQUksQ0FBQyxRQUFRLEdBQUcsYUFBYSxDQUFDO1FBQzlCLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxNQUFNLENBQUMsSUFBVTtRQUNmLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUM7UUFDcEMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQzdCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLE1BQWdCLENBQUM7WUFDM0MsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFDekIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hCLENBQUMsQ0FBQztRQUNGLFVBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELFNBQVMsQ0FBQyxJQUFVO1FBQ2xCLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUM3QyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FDcEI7Z0JBQ0UsRUFBRSxFQUFFLG9CQUFvQjtnQkFDeEIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxLQUFLO2dCQUNyQixLQUFLLEVBQUUsZ0JBQWdCO2dCQUN2QixXQUFXLEVBQ1QseURBQXlEO29CQUN6RCxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO29CQUN6QyxVQUFVO2FBQ2IsRUFDRCxJQUFJLENBQ0wsQ0FBQztZQUNGLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUM5QyxPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FDcEI7b0JBQ0UsRUFBRSxFQUFFLHNCQUFzQjtvQkFDMUIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxLQUFLO29CQUNyQixLQUFLLEVBQUUsZ0JBQWdCO29CQUN2QixXQUFXLEVBQUUsOENBQThDO2lCQUM1RCxFQUNELElBQUksQ0FDTCxDQUFDO2dCQUNGLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxVQUFVLENBQUMsS0FBVTtRQUNuQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDM0MsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1lBQzlCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsTUFBTTtRQUNWLG9CQUFvQjtRQUNwQixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQzdCLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDckUsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHO1lBQ2YsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ2xFLElBQUk7WUFDSixNQUFNLEVBQUUsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQztTQUNuQyxDQUFDO1FBRUYsaUJBQWlCO1FBQ2pCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWhDLG9EQUFvRDtRQUNwRCxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDM0YsSUFBSSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNqQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDckMsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN0RixDQUFDO1FBRUQsa0JBQWtCO1FBQ2xCLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQVc7UUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztZQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztZQUNwQixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO2dCQUNwQixLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ2xFLElBQUksRUFBRSxJQUFJO2dCQUNWLE1BQU0sRUFBRSxJQUFJO2FBQ2IsQ0FBQyxDQUFDO1lBQ0gsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNwQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUVwQixJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ1AsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDNUUsSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDWCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztnQkFDekIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7Z0JBQ3BCLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUMxQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztZQUN2QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNPLFNBQVMsQ0FBQyxJQUFJO1FBQ3RCLE9BQU8sSUFBSSxPQUFPLENBQVMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDN0MsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNWLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3ZCLENBQUM7WUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0IsTUFBTSxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ25CLE9BQU8sTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztnQkFDaEQsQ0FBQztnQkFDRCxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3BDLENBQUMsQ0FBQztZQUNGLE1BQU0sQ0FBQyxPQUFPLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDekIsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hCLENBQUMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFlBQVksQ0FBQyxNQUFjLEVBQUUsUUFBZ0IsRUFBRSxRQUFnQjtRQUM3RCxPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQzNDLEtBQUssQ0FBQyxNQUFNLENBQUM7aUJBQ1YsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7aUJBQ3pCLElBQUksQ0FDSCxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNQLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDMUQsQ0FBQyxFQUNELENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ04sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2QsQ0FBQyxDQUNGLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQXlCLEVBQUUsU0FBYztRQUMxRCxNQUFNLElBQUksR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xGLENBQUM7SUFFRCxnQkFBZ0I7UUFDZCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDO1FBQy9CLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQzFCLENBQUM7SUFFRCxlQUFlO1FBQ2IsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQ3BCO1lBQ0UsRUFBRSxFQUFFLHVCQUF1QjtZQUMzQixJQUFJLEVBQUUsU0FBUyxDQUFDLEtBQUs7WUFDckIsS0FBSyxFQUFFLGdCQUFnQjtZQUN2QixXQUFXLEVBQ1QsMEdBQTBHO1NBQzdHLEVBQ0QsSUFBSSxDQUNMLENBQUM7SUFDSixDQUFDO3VHQTdTVSxvQkFBb0I7MkZBQXBCLG9CQUFvQiw0MkJDekJqQywrM0dBb0ZBLGdoQ0RoRUksT0FBTyxvRkFDUCxxQkFBcUIsd3dCQUNyQix3QkFBd0I7OzJGQUdmLG9CQUFvQjtrQkFYaEMsU0FBUzsrQkFDRSxtQkFBbUIsY0FHakIsSUFBSSxXQUNQO3dCQUNQLE9BQU87d0JBQ1AscUJBQXFCO3dCQUNyQix3QkFBd0I7cUJBQ3pCOzhKQUd1QixTQUFTO3NCQUFoQyxTQUFTO3VCQUFDLFdBQVc7Z0JBRWIsRUFBRTtzQkFBVixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUVJLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHtcbiAgQXV0aFNlcnZpY2UsXG4gIENvbXByZXNzT3B0aW9ucyxcbiAgQ3JvcHBpbmdPcHRpb25zLFxuICBGaWxlU2VydmljZSxcbiAgVG9hc3RTZXJ2aWNlLFxuICBUb2FzdFR5cGVcbn0gZnJvbSAnQGxlbm5lLnRlY2gvbmctYmFzZS9zaGFyZWQnO1xuaW1wb3J0IHsgSW1hZ2VDcm9wcGVkRXZlbnQsIEltYWdlQ3JvcHBlckNvbXBvbmVudCB9IGZyb20gJ25neC1pbWFnZS1jcm9wcGVyJztcbmltcG9ydCB7IE5nQ2xhc3MgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgU3RvcFByb3BhZ2F0aW9uRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy9zdG9wLXByb3BhZ2F0aW9uLmRpcmVjdGl2ZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2Jhc2UtdXBsb2FkLWltYWdlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3VwbG9hZC1pbWFnZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3VwbG9hZC1pbWFnZS5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgTmdDbGFzcyxcbiAgICBJbWFnZUNyb3BwZXJDb21wb25lbnQsXG4gICAgU3RvcFByb3BhZ2F0aW9uRGlyZWN0aXZlXG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgVXBsb2FkSW1hZ2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBAVmlld0NoaWxkKCdmaWxlSW5wdXQnKSBmaWxlSW5wdXQ6IEVsZW1lbnRSZWY7XG5cbiAgQElucHV0KCkgaWQ6IHN0cmluZztcbiAgQElucHV0KCkgbmFtZTogc3RyaW5nO1xuICBASW5wdXQoKSBpbmZvVGV4dDogc3RyaW5nO1xuICBASW5wdXQoKSBsYWJlbD86IHN0cmluZztcbiAgQElucHV0KCkgc3VwcG9ydFRleHQgPSAnU3VwcG9ydHM6IEpQRUcsIEpQRywgUE5HJztcbiAgQElucHV0KCkgcmVxdWlyZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgZGVmYXVsdERyYWdUZXh0ID0gJ0RyYWcgJiBEcm9wJztcbiAgQElucHV0KCkgZGVmYXVsdFJlbGVhc2VUZXh0ID0gJ1JlbGVhc2UgdG8gVXBsb2FkJztcbiAgQElucHV0KCkgcHJlQnV0dG9uVGV4dCA9ICdvcic7XG4gIEBJbnB1dCgpIGJ1dHRvblRleHQgPSAnYnJvd3NlJztcbiAgQElucHV0KCkgdmFsaWRFeHRlbnNpb25zID0gWydpbWFnZS9qcGVnJywgJ2ltYWdlL2pwZycsICdpbWFnZS9wbmcnLCAnaW1hZ2Uvd2VicCddO1xuICBASW5wdXQoKSBjb250cm9sOiBhbnk7XG4gIEBJbnB1dCgpIHVybCA9ICdodHRwOi8vbG9jYWxob3N0OjMwMDAnO1xuICBASW5wdXQoKSB1cGxvYWRQYXRoID0gJy9maWxlcy91cGxvYWQnO1xuICBASW5wdXQoKSBkZWxldGVQYXRoID0gJy9maWxlcy8nO1xuICBASW5wdXQoKSBwYXRoID0gJy9maWxlcy8nO1xuICBASW5wdXQoKSBjb21wcmVzc09wdGlvbnM6IENvbXByZXNzT3B0aW9ucztcbiAgQElucHV0KCkgbWF4U2l6ZTogbnVtYmVyO1xuICBASW5wdXQoKSB1cGxvYWREaXJlY3RseSA9IGZhbHNlO1xuICBASW5wdXQoKSBjcm9wcGluZ0ltYWdlID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNyb3BwaW5nT3B0aW9uczogQ3JvcHBpbmdPcHRpb25zO1xuICBASW5wdXQoKSBvYmplY3RQYXRoOiBzdHJpbmc7XG4gIEBJbnB1dCgpIG1vZGU6ICdmaWxlJyB8ICdiYXNlNjQnID0gJ2ZpbGUnO1xuXG4gIEBPdXRwdXQoKSBpbWFnZVVwbG9hZGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgaW1hZ2VEZWxldGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgZmlsZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgZmllbGQ6IHN0cmluZzsgZmlsZTogRmlsZSB8IG51bGw7IGJhc2U2NDogc3RyaW5nIHwgbnVsbCB9PigpO1xuXG4gIGRyYWdBY3RpdmUgPSBmYWxzZTtcbiAgZHJhZ1RleHQgPSAnRHJhZyAmIERyb3AnO1xuICBzZWxlY3RlZEZpbGU6IEZpbGU7XG4gIGNyb3BwZWRGaWxlOiBGaWxlO1xuICBmaWxlVXJsOiBzdHJpbmc7XG4gIGxvYWRpbmcgPSBmYWxzZTtcbiAgY3JvcHBlZEluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgZmlsZUV2ZW50OiBhbnk7XG4gIGNPcHRpb25zOiBDcm9wcGluZ09wdGlvbnM7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBodHRwQ2xpZW50OiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgYXV0aFNlcnZpY2U6IEF1dGhTZXJ2aWNlLFxuICAgIHByaXZhdGUgZmlsZVNlcnZpY2U6IEZpbGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgdG9hc3RTZXJ2aWNlOiBUb2FzdFNlcnZpY2VcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCkge1xuICAgIC8vIFNldCBkZWZhdWx0IG9wdGlvbnMgZm9yIGNyb3BwaW5nXG4gICAgdGhpcy5jT3B0aW9ucyA9IHtcbiAgICAgIG1haW50YWluQXNwZWN0UmF0aW86IHRydWUsXG4gICAgICBhc3BlY3RSYXRpbzogNCAvIDMsXG4gICAgICBvbmx5U2NhbGVEb3duOiBmYWxzZSxcbiAgICAgIGltYWdlUXVhbGl0eTogOTIsXG4gICAgICBhdXRvQ3JvcDogdHJ1ZSxcbiAgICAgIGFsaWduSW1hZ2U6ICdjZW50ZXInLFxuICAgICAgZm9ybWF0OiAnanBlZycsXG4gICAgICAuLi50aGlzLmNyb3BwaW5nT3B0aW9ucyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBkcmFnT3ZlciBmdW5jdGlvbiBpcyBjYWxsZWQgd2hlbiB0aGUgdXNlciBkcmFncyBhIGZpbGUgb3ZlciB0aGUgZHJvcHpvbmUuIEl0IHByZXZlbnRzIHRoZSBkZWZhdWx0IGFjdGlvbiBvZiB0aGVcbiAgICogZXZlbnQsIGFuZCBzZXRzIHRoZSBkcmFnVGV4dCB0byAnUmVsZWFzZSB0byBVcGxvYWQnIGFuZCB0aGUgZHJhZ0FjdGl2ZSB0byB0cnVlXG4gICAqXG4gICAqIEBwYXJhbSBldmVudCAtIGFueSAtIFRoaXMgaXMgdGhlIGV2ZW50IHRoYXQgaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIHVzZXIgZHJhZ3MgYSBmaWxlIG92ZXIgdGhlIGRyb3B6b25lLlxuICAgKi9cbiAgZHJhZ092ZXIoZXZlbnQ6IGFueSkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5kcmFnVGV4dCA9IHRoaXMuZGVmYXVsdFJlbGVhc2VUZXh0O1xuICAgIHRoaXMuZHJhZ0FjdGl2ZSA9IHRydWU7XG4gIH1cblxuICAvKipcbiAgICogV2hlbiB0aGUgdXNlciBkcmFncyBhIGZpbGUgb3ZlciB0aGUgZHJvcCB6b25lLCB0aGUgZHJhZ0FjdGl2ZSB2YXJpYWJsZSBpcyBzZXQgdG8gdHJ1ZSwgd2hpY2ggd2lsbCBjaGFuZ2UgdGhlIGNvbG9yIG9mXG4gICAqIHRoZSBkcm9wIHpvbmUgdG8gZ3JlZW5cbiAgICpcbiAgICogQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IG9iamVjdCB0aGF0IGlzIHBhc3NlZCB0byB0aGUgZHJhZ0xlYXZlIGV2ZW50LlxuICAgKi9cbiAgZHJhZ0xlYXZlKGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLmRyYWdUZXh0ID0gdGhpcy5kZWZhdWx0RHJhZ1RleHQ7XG4gICAgdGhpcy5kcmFnQWN0aXZlID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGZ1bmN0aW9uIHRha2VzIGFuIGV2ZW50IGFzIGEgcGFyYW1ldGVyLCBwcmV2ZW50cyB0aGUgZGVmYXVsdCBhY3Rpb24gb2YgdGhlIGV2ZW50LCBzZXRzIHRoZSBVUkwgb2YgdGhlIGltYWdlIHRvIHRoZVxuICAgKiBmaWxlIHRoYXQgd2FzIGRyYWdnZWQgYW5kIGRyb3BwZWQsIHNldHMgdGhlIHRleHQgb2YgdGhlIGRyYWcgYW5kIGRyb3AgYXJlYSB0byB0aGUgZGVmYXVsdCB0ZXh0LCBhbmQgc2V0cyB0aGVcbiAgICogZHJhZ0FjdGl2ZSB2YXJpYWJsZSB0byBmYWxzZVxuICAgKlxuICAgKiBAcGFyYW0gZXZlbnQgLSBhbnkgLSBUaGlzIGlzIHRoZSBldmVudCB0aGF0IGlzIHRyaWdnZXJlZCB3aGVuIHRoZSB1c2VyIGRyYWdzIGFuZCBkcm9wcyBhIGZpbGUuXG4gICAqL1xuICBkcm9wKGV2ZW50OiBhbnkpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuZmlsZUlucHV0Lm5hdGl2ZUVsZW1lbnQuZmlsZXMgPSBldmVudC5kYXRhVHJhbnNmZXIuZmlsZXM7XG4gICAgY29uc3QgZSA9IG5ldyBFdmVudCgnY2hhbmdlJyk7XG4gICAgdGhpcy5maWxlSW5wdXQubmF0aXZlRWxlbWVudC5kaXNwYXRjaEV2ZW50KGUpO1xuXG4gICAgdGhpcy5kcmFnVGV4dCA9ICdEcmFnICYgRHJvcCc7XG4gICAgdGhpcy5kcmFnQWN0aXZlID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogSXQgdGFrZXMgYSBmaWxlIGFzIGFuIGFyZ3VtZW50LCBjaGVja3MgaWYgdGhlIGZpbGUgdHlwZSBpcyB2YWxpZCwgYW5kIGlmIGl0IGlzLCBpdCBjcmVhdGVzIGEgbmV3IEZpbGVSZWFkZXIgb2JqZWN0LFxuICAgKiBzZXRzIHRoZSBvbmxvYWQgZnVuY3Rpb24gdG8gc2V0IHRoZSBmaWxlVXJsIHRvIHRoZSByZXN1bHQgb2YgdGhlIGZpbGVSZWFkZXIsIHNldHMgdGhlIHNlbGVjdGVkRmlsZSB0byB0aGUgZmlsZSwgYW5kXG4gICAqIGNhbGxzIHRoZSB1cGxvYWQgZnVuY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIGZpbGUgLSBhbnkgLSB0aGlzIGlzIHRoZSBmaWxlIHRoYXQgaXMgc2VsZWN0ZWQgYnkgdGhlIHVzZXIuXG4gICAqL1xuICBzZXRVcmwoZmlsZTogRmlsZSkge1xuICAgIGNvbnN0IGZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgIGZpbGVSZWFkZXIub25sb2FkID0gKHJlc3VsdCkgPT4ge1xuICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuZmlsZVVybCA9IGZpbGVSZWFkZXIucmVzdWx0IGFzIHN0cmluZztcbiAgICAgIHRoaXMuc2VsZWN0ZWRGaWxlID0gZmlsZTtcbiAgICAgIHRoaXMudXBsb2FkKCk7XG4gICAgfTtcbiAgICBmaWxlUmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7XG4gIH1cblxuICBjaGVja0ZpbGUoZmlsZTogRmlsZSkge1xuICAgIGlmICh0aGlzLm1heFNpemUgJiYgZmlsZS5zaXplID4gdGhpcy5tYXhTaXplKSB7XG4gICAgICB0aGlzLnRvYXN0U2VydmljZS5zaG93KFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICdpbWFnZS1pbnZhbGlkLXNpemUnLFxuICAgICAgICAgIHR5cGU6IFRvYXN0VHlwZS5FUlJPUixcbiAgICAgICAgICB0aXRsZTogJ0ZlaGxnZXNjaGxhZ2VuJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICdEaWUgRGF0ZWkgaXN0IHp1IGdyb8OfLiBEaWUgRGF0ZWkgZGFyZiBuaWNodCBncsO2w59lciBhbHMgJyArXG4gICAgICAgICAgICAodGhpcy5tYXhTaXplIC8gKDEwMjQgKiAxMDI0KSkudG9GaXhlZCgyKSArXG4gICAgICAgICAgICAnTUIgc2Vpbi4nLFxuICAgICAgICB9LFxuICAgICAgICAzNTAwXG4gICAgICApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy52YWxpZEV4dGVuc2lvbnMuaW5jbHVkZXMoZmlsZT8udHlwZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnRvYXN0U2VydmljZS5zaG93KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnaW1hZ2UtaW52YWxpZC1mb3JtYXQnLFxuICAgICAgICAgICAgdHlwZTogVG9hc3RUeXBlLkVSUk9SLFxuICAgICAgICAgICAgdGl0bGU6ICdGZWhsZ2VzY2hsYWdlbicsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0RhcyBGb3JtYXQgZGVyIERhdGVpIHdpcmQgbmljaHQgdW50ZXJzdMO8dHp0LicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICAzNTAwXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIGZ1bmN0aW9uIHRha2VzIGFuIGV2ZW50IGFzIGFuIGFyZ3VtZW50LCBhbmQgdGhlbiBzZXRzIHRoZSB1cmwgb2YgdGhlIGZpbGUgdG8gdGhlIGZpcnN0IGZpbGUgaW4gdGhlIGV2ZW50J3NcbiAgICogdGFyZ2V0J3MgZmlsZXMgYXJyYXlcbiAgICpcbiAgICogQHBhcmFtIGV2ZW50IC0gYW55IC0gVGhlIGV2ZW50IHRoYXQgaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIHVzZXIgc2VsZWN0cyBhIGZpbGUuXG4gICAqL1xuICBzZWxlY3RGaWxlKGV2ZW50OiBhbnkpIHtcbiAgICBpZiAoIXRoaXMuY2hlY2tGaWxlKGV2ZW50LnRhcmdldC5maWxlc1swXSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jcm9wcGluZ0ltYWdlKSB7XG4gICAgICB0aGlzLmNyb3BwZWRJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgIHRoaXMuZmlsZUV2ZW50ID0gZXZlbnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0VXJsKGV2ZW50LnRhcmdldC5maWxlc1swXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdlIGNyZWF0ZSBhIG5ldyBGb3JtRGF0YSBvYmplY3QsIGFwcGVuZCB0aGUgc2VsZWN0ZWQgZmlsZSB0byBpdCwgYW5kIHRoZW4gc2VuZCBpdCB0byB0aGUgc2VydmVyXG4gICAqL1xuICBhc3luYyB1cGxvYWQoKSB7XG4gICAgLy8gUHJlcGFyZSBmaWxlIGRhdGFcbiAgICBsZXQgZmlsZSA9IHRoaXMuc2VsZWN0ZWRGaWxlO1xuICAgIGlmICh0aGlzLmNvbXByZXNzT3B0aW9ucykge1xuICAgICAgZmlsZSA9IGF3YWl0IHRoaXMuZmlsZVNlcnZpY2UuY29tcHJlc3MoZmlsZSwgdGhpcy5jb21wcmVzc09wdGlvbnMpO1xuICAgIH1cbiAgICBjb25zdCBmaWxlRGF0YSA9IHtcbiAgICAgIGZpZWxkOiB0aGlzLm9iamVjdFBhdGggPyB0aGlzLm9iamVjdFBhdGggKyAnLicgKyB0aGlzLmlkIDogdGhpcy5pZCxcbiAgICAgIGZpbGUsXG4gICAgICBiYXNlNjQ6IGF3YWl0IHRoaXMuZ2V0QmFzZTY0KGZpbGUpLFxuICAgIH07XG5cbiAgICAvLyBFbWl0IGZpbGUgZGF0YVxuICAgIHRoaXMuZmlsZUNoYW5nZWQuZW1pdChmaWxlRGF0YSk7XG5cbiAgICAvLyBTZXQgY29udHJvbCB2YWx1ZSBhbmQgdXBsb2FkIGRpcmVjdGx5IGlmIHJlcXVpcmVkXG4gICAgaWYgKHRoaXMudXBsb2FkRGlyZWN0bHkpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZmlsZVNlcnZpY2UudXBsb2FkKHRoaXMudXJsLCB0aGlzLnVwbG9hZFBhdGgsIHRoaXMuc2VsZWN0ZWRGaWxlKTtcbiAgICAgIGlmIChyZXN1bHQ/LmlkKSB7XG4gICAgICAgIHRoaXMuY29udHJvbC5zZXRWYWx1ZShyZXN1bHQuaWQpO1xuICAgICAgICB0aGlzLmltYWdlVXBsb2FkZWQuZW1pdChyZXN1bHQuaWQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbnRyb2wuc2V0VmFsdWUodGhpcy5tb2RlID09PSAnYmFzZTY0JyA/IGZpbGVEYXRhLmJhc2U2NCA6IHRoaXMuc2VsZWN0ZWRGaWxlKTtcbiAgICB9XG5cbiAgICAvLyBGaW5hbCBwcm9jZXNzZXNcbiAgICB0aGlzLmNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0IGRlbGV0ZXMgdGhlIGZpbGUgZnJvbSB0aGUgc2VydmVyIGFuZCBzZXRzIHRoZSBzZWxlY3RlZEZpbGUgYW5kIGZpbGVVcmwgdG8gbnVsbFxuICAgKlxuICAgKiBAcGFyYW0gW2lkXSAtIFRoZSBpZCBvZiB0aGUgZmlsZSB0byBkZWxldGUuXG4gICAqL1xuICBhc3luYyBkZWxldGVGaWxlKGlkPzogc3RyaW5nKSB7XG4gICAgaWYgKCF0aGlzLnVwbG9hZERpcmVjdGx5KSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRmlsZSA9IG51bGw7XG4gICAgICB0aGlzLmZpbGVVcmwgPSBudWxsO1xuICAgICAgdGhpcy5jb250cm9sLnNldFZhbHVlKCcnKTtcbiAgICAgIHRoaXMuY29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgICB0aGlzLmZpbGVDaGFuZ2VkLmVtaXQoe1xuICAgICAgICBmaWVsZDogdGhpcy5vYmplY3RQYXRoID8gdGhpcy5vYmplY3RQYXRoICsgJy4nICsgdGhpcy5pZCA6IHRoaXMuaWQsXG4gICAgICAgIGZpbGU6IG51bGwsXG4gICAgICAgIGJhc2U2NDogbnVsbCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgdGhpcy5zZWxlY3RlZEZpbGUgPSBudWxsO1xuICAgIHRoaXMuZmlsZVVybCA9IG51bGw7XG5cbiAgICBpZiAoaWQpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZmlsZVNlcnZpY2UuZGVsZXRlKHRoaXMudXJsLCB0aGlzLmRlbGV0ZVBhdGgsIGlkKTtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEZpbGUgPSBudWxsO1xuICAgICAgICB0aGlzLmZpbGVVcmwgPSBudWxsO1xuICAgICAgICB0aGlzLmNvbnRyb2wuc2V0VmFsdWUoJycpO1xuICAgICAgICB0aGlzLmltYWdlRGVsZXRlZC5lbWl0KCk7XG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgZmlsZSBpbnRvIGEgQkFTRTY0IGVuY29kZWQgc3RyaW5nXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0QmFzZTY0KGZpbGUpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxzdHJpbmc+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGlmICghZmlsZSkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcbiAgICAgIHJlYWRlci5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgIGlmICghcmVhZGVyLnJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdDb252ZXJzaW9uIGZhaWxlZCcpKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHJlYWRlci5yZXN1bHQudG9TdHJpbmcoKSk7XG4gICAgICB9O1xuICAgICAgcmVhZGVyLm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBiYXNlNjRUb0ZpbGUoYmFzZTY0OiBzdHJpbmcsIGZpbGVOYW1lOiBzdHJpbmcsIGZpbGVUeXBlOiBzdHJpbmcpOiBQcm9taXNlPEZpbGU+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8RmlsZT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZmV0Y2goYmFzZTY0KVxuICAgICAgICAudGhlbigocmVzKSA9PiByZXMuYmxvYigpKVxuICAgICAgICAudGhlbihcbiAgICAgICAgICAoYmxvYikgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgRmlsZShbYmxvYl0sIGZpbGVOYW1lLCB7IHR5cGU6IGZpbGVUeXBlIH0pKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIChlcnIpID0+IHtcbiAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGltYWdlQ3JvcHBlZCgkZXZlbnQ6IEltYWdlQ3JvcHBlZEV2ZW50LCBmaWxlRXZlbnQ6IGFueSkge1xuICAgIGNvbnN0IGZpbGUgPSBmaWxlRXZlbnQudGFyZ2V0LmZpbGVzWzBdO1xuICAgIHRoaXMuY3JvcHBlZEZpbGUgPSBhd2FpdCB0aGlzLmJhc2U2NFRvRmlsZSgkZXZlbnQuYmFzZTY0LCBmaWxlLm5hbWUsIGZpbGUudHlwZSk7XG4gIH1cblxuICBmaW5pc2hlZENyb3BwaW5nKCkge1xuICAgIHRoaXMuZmlsZUV2ZW50ID0gbnVsbDtcbiAgICB0aGlzLnNldFVybCh0aGlzLmNyb3BwZWRGaWxlKTtcbiAgICB0aGlzLmNyb3BwZWRJblByb2dyZXNzID0gZmFsc2U7XG4gICAgdGhpcy5jcm9wcGVkRmlsZSA9IG51bGw7XG4gIH1cblxuICBsb2FkSW1hZ2VGYWlsZWQoKSB7XG4gICAgdGhpcy50b2FzdFNlcnZpY2Uuc2hvdyhcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdpbWFnZS1pbnZhbGlkLWNyb3BwZWQnLFxuICAgICAgICB0eXBlOiBUb2FzdFR5cGUuRVJST1IsXG4gICAgICAgIHRpdGxlOiAnRmVobGdlc2NobGFnZW4nLFxuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnRXMgaXN0IGVpbiBGZWhsZXIgYXVmZ2V0cmV0ZW4uIEJpdHRlIHByb2JpZXJlbiBTaWUgZXMgc3DDpHRlciBlcm5ldXQgb2RlciB3ZW5kZW4gU2llIHNpY2ggYW4gZGVuIFN1cHBvcnQuJyxcbiAgICAgIH0sXG4gICAgICAzNTAwXG4gICAgKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgbXQtM1wiIFtuZ0NsYXNzXT1cInsgJ2lzLWludmFsaWQnOiBjb250cm9sPy5pbnZhbGlkICYmIGNvbnRyb2w/LnRvdWNoZWQgfVwiPlxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgIEBpZiAobGFiZWwpIHtcbiAgICAgIDxsYWJlbCBbZm9yXT1cImlkXCIgY2xhc3M9XCJmb3JtLWxhYmVsXCIgW25nQ2xhc3NdPVwieyByZXF1aXJlZDogcmVxdWlyZWQgfVwiPnt7IGxhYmVsIH19PC9sYWJlbD5cbiAgICB9XG4gICAgQGlmIChpbmZvVGV4dCkge1xuICAgICAgPGkgY2xhc3M9XCJiaSBiaS1pbmZvLWNpcmNsZVwiIFtuZ2JUb29sdGlwXT1cImluZm9UZXh0XCIgcGxhY2VtZW50PVwic3RhcnRcIj48L2k+XG4gICAgfVxuICA8L2Rpdj5cblxuICA8ZGl2XG4gICAgW2lkXT1cIm9iamVjdFBhdGggPyBvYmplY3RQYXRoICsgJy4nICsgaWQgOiBpZFwiXG4gICAgY2xhc3M9XCJkcmFnLWFyZWFcIlxuICAgIChkcmFnb3Zlcik9XCJkcmFnT3ZlcigkZXZlbnQpXCJcbiAgICAoZHJhZ2xlYXZlKT1cImRyYWdMZWF2ZSgkZXZlbnQpXCJcbiAgICAoZHJvcCk9XCJkcm9wKCRldmVudClcIlxuICAgIFtuZ0NsYXNzXT1cInsgYWN0aXZlOiBkcmFnQWN0aXZlLCBwb2ludGVyOiAhbG9hZGluZywgJ2lzLWludmFsaWQnOiBjb250cm9sPy5pbnZhbGlkICYmIGNvbnRyb2w/LnRvdWNoZWQgfVwiXG4gICAgKGNsaWNrKT1cIiFjcm9wcGVkSW5Qcm9ncmVzcyAmJiAhbG9hZGluZyAmJiBmaWxlSW5wdXQuY2xpY2soKVwiXG4gICAgPlxuICAgIEBpZiAobG9hZGluZykge1xuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyLWJvcmRlciB0ZXh0LXByaW1hcnlcIiByb2xlPVwic3RhdHVzXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj5Mb2FkaW5nLi4uPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIH1cblxuICAgIEBpZiAoc2VsZWN0ZWRGaWxlICYmICFmaWxlRXZlbnQgJiYgIWNyb3BwZWRJblByb2dyZXNzICYmICFsb2FkaW5nKSB7XG4gICAgICBAaWYgKHNlbGVjdGVkRmlsZSkge1xuICAgICAgICA8aW1nIFtzcmNdPVwiZmlsZVVybFwiIC8+XG4gICAgICB9XG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImRlbGV0ZUZpbGUoKVwiIGJhc2VTdG9wUHJvcGFnYXRpb24+TMO2c2NoZW48L2J1dHRvbj5cbiAgICB9XG5cbiAgICBAaWYgKGNvbnRyb2w/LnZhbHVlICYmICFmaWxlRXZlbnQgJiYgIXNlbGVjdGVkRmlsZSAmJiAhbG9hZGluZyAmJiAhY3JvcHBlZEluUHJvZ3Jlc3MpIHtcbiAgICAgIDxpbWcgW3NyY109XCJjb250cm9sPy52YWx1ZS5zdGFydHNXaXRoKCdkYXRhOicpID8gY29udHJvbD8udmFsdWUgOiB1cmwgKyBwYXRoICsgY29udHJvbD8udmFsdWVcIiAvPlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJkZWxldGVGaWxlKGNvbnRyb2w/LnZhbHVlKVwiIGJhc2VTdG9wUHJvcGFnYXRpb24+XG4gICAgICAgIEzDtnNjaGVuXG4gICAgICA8L2J1dHRvbj5cbiAgICB9XG5cbiAgICBAaWYgKCFzZWxlY3RlZEZpbGUgJiYgIWNvbnRyb2w/LnZhbHVlICYmICFsb2FkaW5nICYmICFmaWxlRXZlbnQpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJpY29uXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiYmkgYmktaW1hZ2VzXCI+PC9pPlxuICAgICAgPC9kaXY+XG4gICAgICA8c3BhbiBjbGFzcz1cImhlYWRlclwiPnt7IGRyYWdUZXh0IH19PC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJoZWFkZXJcIlxuICAgICAgICA+e3sgcHJlQnV0dG9uVGV4dCB9fVxuICAgICAgICA8c3BhbiBjbGFzcz1cImJ1dHRvblwiIChjbGljayk9XCJmaWxlSW5wdXQuY2xpY2soKVwiIGJhc2VTdG9wUHJvcGFnYXRpb24+e3sgYnV0dG9uVGV4dCB9fTwvc3Bhbj48L3NwYW5cbiAgICAgICAgPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInN1cHBvcnRcIiBbaW5uZXJUZXh0XT1cInN1cHBvcnRUZXh0XCI+PC9zcGFuPlxuICAgICAgfVxuXG4gICAgICA8aW5wdXQgdHlwZT1cImZpbGVcIiAoY2hhbmdlKT1cInNlbGVjdEZpbGUoJGV2ZW50KVwiIFthdHRyLmFjY2VwdF09XCJ2YWxpZEV4dGVuc2lvbnM/LmpvaW4oJywnKVwiIGhpZGRlbiAjZmlsZUlucHV0IC8+XG5cbiAgICAgIEBpZiAoY3JvcHBlZEluUHJvZ3Jlc3MgJiYgZmlsZUV2ZW50KSB7XG4gICAgICAgIDxpbWFnZS1jcm9wcGVyXG4gICAgICAgICAgW2ltYWdlQ2hhbmdlZEV2ZW50XT1cImZpbGVFdmVudFwiXG4gICAgICAgICAgW21haW50YWluQXNwZWN0UmF0aW9dPVwiY09wdGlvbnMubWFpbnRhaW5Bc3BlY3RSYXRpb1wiXG4gICAgICAgICAgW2FzcGVjdFJhdGlvXT1cImNPcHRpb25zLmFzcGVjdFJhdGlvXCJcbiAgICAgICAgICBbYWxpZ25JbWFnZV09XCJjT3B0aW9ucy5hbGlnbkltYWdlXCJcbiAgICAgICAgICBbcmVzaXplVG9XaWR0aF09XCJjT3B0aW9ucy5yZXNpemVUb1dpZHRoXCJcbiAgICAgICAgICBbcmVzaXplVG9IZWlnaHRdPVwiY09wdGlvbnMucmVzaXplVG9IZWlnaHRcIlxuICAgICAgICAgIFthdXRvQ3JvcF09XCJjT3B0aW9ucy5hdXRvQ3JvcFwiXG4gICAgICAgICAgW2ltYWdlUXVhbGl0eV09XCJjT3B0aW9ucy5pbWFnZVF1YWxpdHlcIlxuICAgICAgICAgIFtvbmx5U2NhbGVEb3duXT1cImNPcHRpb25zLm9ubHlTY2FsZURvd25cIlxuICAgICAgICAgIFtmb3JtYXRdPVwiY09wdGlvbnMuZm9ybWF0XCJcbiAgICAgICAgICAoaW1hZ2VDcm9wcGVkKT1cImltYWdlQ3JvcHBlZCgkZXZlbnQsIGZpbGVFdmVudClcIlxuICAgICAgICAgIChsb2FkSW1hZ2VGYWlsZWQpPVwibG9hZEltYWdlRmFpbGVkKClcIlxuICAgICAgICA+PC9pbWFnZS1jcm9wcGVyPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IG10LTJcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImZpbmlzaGVkQ3JvcHBpbmcoKVwiIGJhc2VTdG9wUHJvcGFnYXRpb24+XG4gICAgICAgICAgWnVzY2huZWlkZW5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICB9XG4gICAgPC9kaXY+XG5cbiAgICBAaWYgKGNvbnRyb2w/LmludmFsaWQgJiYgKGNvbnRyb2w/LmRpcnR5IHx8IGNvbnRyb2w/LnRvdWNoZWQpKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtLTJcIj5cbiAgICAgICAgQGlmIChjb250cm9sPy5lcnJvcnM/LlsncmVxdWlyZWQnXSkge1xuICAgICAgICAgIDxkaXY+RGllc2VzIEZlbGQgaXN0IGVpbiBQZmxpY2h0ZmVsZC48L2Rpdj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cbiJdfQ==
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Directive, HostListener } from '@angular/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
import * as i1 from "@lenne.tech/ng-base/shared";
|
|
4
|
-
export class BackButtonDirective {
|
|
5
|
-
navigation;
|
|
6
|
-
constructor(navigation) {
|
|
7
|
-
this.navigation = navigation;
|
|
8
|
-
}
|
|
9
|
-
onClick() {
|
|
10
|
-
this.navigation.back();
|
|
11
|
-
}
|
|
12
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: BackButtonDirective, deps: [{ token: i1.NavigationService }], target: i0.ɵɵFactoryTarget.Directive });
|
|
13
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.2", type: BackButtonDirective, isStandalone: true, selector: "[baseBackButton]", host: { listeners: { "click": "onClick()" } }, ngImport: i0 });
|
|
14
|
-
}
|
|
15
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: BackButtonDirective, decorators: [{
|
|
16
|
-
type: Directive,
|
|
17
|
-
args: [{
|
|
18
|
-
selector: '[baseBackButton]',
|
|
19
|
-
standalone: true,
|
|
20
|
-
}]
|
|
21
|
-
}], ctorParameters: () => [{ type: i1.NavigationService }], propDecorators: { onClick: [{
|
|
22
|
-
type: HostListener,
|
|
23
|
-
args: ['click']
|
|
24
|
-
}] } });
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFjay1idXR0b24uZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctYmFzZS9iYXNlLWNvbXBvbmVudHMvZGlyZWN0aXZlcy9iYWNrLWJ1dHRvbi5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7OztBQU94RCxNQUFNLE9BQU8sbUJBQW1CO0lBQ1Y7SUFBcEIsWUFBb0IsVUFBNkI7UUFBN0IsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7SUFBRyxDQUFDO0lBR3JELE9BQU87UUFDTCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3pCLENBQUM7dUdBTlUsbUJBQW1COzJGQUFuQixtQkFBbUI7OzJGQUFuQixtQkFBbUI7a0JBSi9CLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGtCQUFrQjtvQkFDNUIsVUFBVSxFQUFFLElBQUk7aUJBQ2pCO3NGQUtDLE9BQU87c0JBRE4sWUFBWTt1QkFBQyxPQUFPIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBIb3N0TGlzdGVuZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5hdmlnYXRpb25TZXJ2aWNlIH0gZnJvbSAnQGxlbm5lLnRlY2gvbmctYmFzZS9zaGFyZWQnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbYmFzZUJhY2tCdXR0b25dJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgQmFja0J1dHRvbkRpcmVjdGl2ZSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbmF2aWdhdGlvbjogTmF2aWdhdGlvblNlcnZpY2UpIHt9XG5cbiAgQEhvc3RMaXN0ZW5lcignY2xpY2snKVxuICBvbkNsaWNrKCk6IHZvaWQge1xuICAgIHRoaXMubmF2aWdhdGlvbi5iYWNrKCk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { Directive, Input, Output } from '@angular/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
/**
|
|
4
|
-
* Directive vor context menu
|
|
5
|
-
* See https://stackblitz.com/edit/angular-custom-context-menu
|
|
6
|
-
*/
|
|
7
|
-
export class ContextMenuDirective {
|
|
8
|
-
el;
|
|
9
|
-
contextMenuData;
|
|
10
|
-
ltContextMenu;
|
|
11
|
-
xGap = 0;
|
|
12
|
-
yGap = 0;
|
|
13
|
-
overflowSpace = 10;
|
|
14
|
-
selectors = '*';
|
|
15
|
-
clickedElement = null;
|
|
16
|
-
previousDisplayStatus = null;
|
|
17
|
-
constructor(el) {
|
|
18
|
-
this.el = el;
|
|
19
|
-
}
|
|
20
|
-
ngOnInit() {
|
|
21
|
-
if (this.ltContextMenu) {
|
|
22
|
-
this.previousDisplayStatus = this.ltContextMenu.style.display;
|
|
23
|
-
}
|
|
24
|
-
// Add a click listener to the window,
|
|
25
|
-
// so that we can close the context menu on left click
|
|
26
|
-
window.addEventListener('click', () => {
|
|
27
|
-
this.showContextMenu(null, false);
|
|
28
|
-
});
|
|
29
|
-
// Close context menu when escape is pressed
|
|
30
|
-
window.addEventListener('keydown', (e) => {
|
|
31
|
-
if (e.code === 'Escape') {
|
|
32
|
-
this.showContextMenu(null, false);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
// Add an event listener to listen to the 'contextmenu' event
|
|
36
|
-
this.el.nativeElement.addEventListener('contextmenu', (e) => {
|
|
37
|
-
// Prevent the default context menu to popup
|
|
38
|
-
if (e.preventDefault) {
|
|
39
|
-
e.preventDefault();
|
|
40
|
-
}
|
|
41
|
-
// Shows our own context menu
|
|
42
|
-
this.showContextMenu(e, true);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
// Shows or hides our custom context menu, which is specified as a input
|
|
46
|
-
showContextMenu(event, show) {
|
|
47
|
-
const cm = this.ltContextMenu;
|
|
48
|
-
if (cm) {
|
|
49
|
-
// Try to open context menu
|
|
50
|
-
if (show && event && event instanceof MouseEvent) {
|
|
51
|
-
// Get valid clicked structureElement
|
|
52
|
-
const clickedElement = event?.target?.closest(this.selectors);
|
|
53
|
-
if (clickedElement) {
|
|
54
|
-
this.clickedElement = clickedElement;
|
|
55
|
-
setTimeout(() => {
|
|
56
|
-
// Set display status
|
|
57
|
-
cm.style.display = 'block';
|
|
58
|
-
// Calculate top position
|
|
59
|
-
let top = event.y + this.yGap;
|
|
60
|
-
if (top + cm.offsetHeight + 10 > document.documentElement.clientHeight) {
|
|
61
|
-
top = document.documentElement.clientHeight - cm.offsetHeight - this.overflowSpace;
|
|
62
|
-
}
|
|
63
|
-
// Calculate left position
|
|
64
|
-
let left = event.x + this.xGap;
|
|
65
|
-
if (left + cm.offsetWidth + 10 > document.documentElement.clientWidth) {
|
|
66
|
-
left = document.documentElement.clientWidth - cm.offsetWidth - this.overflowSpace;
|
|
67
|
-
}
|
|
68
|
-
// Set position
|
|
69
|
-
cm.style.top = top + 'px';
|
|
70
|
-
cm.style.left = left + 'px';
|
|
71
|
-
// Show
|
|
72
|
-
cm.style.opacity = '1.0';
|
|
73
|
-
cm.style['pointer-events'] = 'auto';
|
|
74
|
-
}, 1);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
// Close context menu
|
|
79
|
-
this.clickedElement = null;
|
|
80
|
-
if (this.previousDisplayStatus) {
|
|
81
|
-
cm.style.display = this.previousDisplayStatus;
|
|
82
|
-
}
|
|
83
|
-
cm.style.opacity = '0.01';
|
|
84
|
-
cm.style['pointer-events'] = 'none';
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: ContextMenuDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
88
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.2", type: ContextMenuDirective, isStandalone: true, selector: "[ltContextMenu]", inputs: { contextMenuData: "contextMenuData", ltContextMenu: "ltContextMenu", xGap: "xGap", yGap: "yGap", overflowSpace: "overflowSpace", selectors: "selectors" }, outputs: { clickedElement: "clickedElement" }, exportAs: ["contextMenuData"], ngImport: i0 });
|
|
89
|
-
}
|
|
90
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: ContextMenuDirective, decorators: [{
|
|
91
|
-
type: Directive,
|
|
92
|
-
args: [{
|
|
93
|
-
selector: '[ltContextMenu]',
|
|
94
|
-
exportAs: 'contextMenuData',
|
|
95
|
-
standalone: true,
|
|
96
|
-
}]
|
|
97
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { contextMenuData: [{
|
|
98
|
-
type: Input
|
|
99
|
-
}], ltContextMenu: [{
|
|
100
|
-
type: Input
|
|
101
|
-
}], xGap: [{
|
|
102
|
-
type: Input
|
|
103
|
-
}], yGap: [{
|
|
104
|
-
type: Input
|
|
105
|
-
}], overflowSpace: [{
|
|
106
|
-
type: Input
|
|
107
|
-
}], selectors: [{
|
|
108
|
-
type: Input
|
|
109
|
-
}], clickedElement: [{
|
|
110
|
-
type: Output
|
|
111
|
-
}] } });
|
|
112
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC1tZW51LmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWJhc2UvYmFzZS1jb21wb25lbnRzL2RpcmVjdGl2ZXMvY29udGV4dC1tZW51LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBRTdFOzs7R0FHRztBQU1ILE1BQU0sT0FBTyxvQkFBb0I7SUFVWDtJQVRYLGVBQWUsQ0FBTztJQUN0QixhQUFhLENBQWM7SUFDM0IsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUNULElBQUksR0FBRyxDQUFDLENBQUM7SUFDVCxhQUFhLEdBQUcsRUFBRSxDQUFDO0lBQ25CLFNBQVMsR0FBRyxHQUFHLENBQUM7SUFDZixjQUFjLEdBQVksSUFBSSxDQUFDO0lBQ3pDLHFCQUFxQixHQUFXLElBQUksQ0FBQztJQUVyQyxZQUFvQixFQUFjO1FBQWQsT0FBRSxHQUFGLEVBQUUsQ0FBWTtJQUFHLENBQUM7SUFFdEMsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDaEUsQ0FBQztRQUVELHNDQUFzQztRQUN0QyxzREFBc0Q7UUFDdEQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7WUFDcEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFFSCw0Q0FBNEM7UUFDNUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxRQUFR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R0FBRyxNQUFNLENBQUM7WUFDMUIsRUFBRSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUN0QyxDQUFDO0lBQ0gsQ0FBQzt1R0F6RlUsb0JBQW9COzJGQUFwQixvQkFBb0I7OzJGQUFwQixvQkFBb0I7a0JBTGhDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGlCQUFpQjtvQkFDM0IsUUFBUSxFQUFFLGlCQUFpQjtvQkFDM0IsVUFBVSxFQUFFLElBQUk7aUJBQ2pCOytFQUVVLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDSSxjQUFjO3NCQUF2QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLyoqXG4gKiBEaXJlY3RpdmUgdm9yIGNvbnRleHQgbWVudVxuICogU2VlIGh0dHBzOi8vc3RhY2tibGl0ei5jb20vZWRpdC9hbmd1bGFyLWN1c3RvbS1jb250ZXh0LW1lbnVcbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2x0Q29udGV4dE1lbnVdJyxcbiAgZXhwb3J0QXM6ICdjb250ZXh0TWVudURhdGEnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBDb250ZXh0TWVudURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBJbnB1dCgpIGNvbnRleHRNZW51RGF0YT86IGFueTtcbiAgQElucHV0KCkgbHRDb250ZXh0TWVudTogSFRNTEVsZW1lbnQ7XG4gIEBJbnB1dCgpIHhHYXAgPSAwO1xuICBASW5wdXQoKSB5R2FwID0gMDtcbiAgQElucHV0KCkgb3ZlcmZsb3dTcGFjZSA9IDEwO1xuICBASW5wdXQoKSBzZWxlY3RvcnMgPSAnKic7XG4gIEBPdXRwdXQoKSBjbGlja2VkRWxlbWVudDogRWxlbWVudCA9IG51bGw7XG4gIHByZXZpb3VzRGlzcGxheVN0YXR1czogc3RyaW5nID0gbnVsbDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsOiBFbGVtZW50UmVmKSB7fVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICh0aGlzLmx0Q29udGV4dE1lbnUpIHtcbiAgICAgIHRoaXMucHJldmlvdXNEaXNwbGF5U3RhdHVzID0gdGhpcy5sdENvbnRleHRNZW51LnN0eWxlLmRpc3BsYXk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGEgY2xpY2sgbGlzdGVuZXIgdG8gdGhlIHdpbmRvdyxcbiAgICAvLyBzbyB0aGF0IHdlIGNhbiBjbG9zZSB0aGUgY29udGV4dCBtZW51IG9uIGxlZnQgY2xpY2tcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICB0aGlzLnNob3dDb250ZXh0TWVudShudWxsLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICAvLyBDbG9zZSBjb250ZXh0IG1lbnUgd2hlbiBlc2NhcGUgaXMgcHJlc3NlZFxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGUpID0+IHtcbiAgICAgIGlmIChlLmNvZGUgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgIHRoaXMuc2hvd0NvbnRleHRNZW51KG51bGwsIGZhbHNlKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEFkZCBhbiBldmVudCBsaXN0ZW5lciB0byBsaXN0ZW4gdG8gdGhlICdjb250ZXh0bWVudScgZXZlbnRcbiAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCAoZSkgPT4ge1xuICAgICAgLy8gUHJldmVudCB0aGUgZGVmYXVsdCBjb250ZXh0IG1lbnUgdG8gcG9wdXBcbiAgICAgIGlmIChlLnByZXZlbnREZWZhdWx0KSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICAgIC8vIFNob3dzIG91ciBvd24gY29udGV4dCBtZW51XG4gICAgICB0aGlzLnNob3dDb250ZXh0TWVudShlLCB0cnVlKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFNob3dzIG9yIGhpZGVzIG91ciBjdXN0b20gY29udGV4dCBtZW51LCB3aGljaCBpcyBzcGVjaWZpZWQgYXMgYSBpbnB1dFxuICBzaG93Q29udGV4dE1lbnUoZXZlbnQsIHNob3c6IGJvb2xlYW4pIHtcbiAgICBjb25zdCBjbSA9IHRoaXMubHRDb250ZXh0TWVudTtcbiAgICBpZiAoY20pIHtcbiAgICAgIC8vIFRyeSB0byBvcGVuIGNvbnRleHQgbWVudVxuICAgICAgaWYgKHNob3cgJiYgZXZlbnQgJiYgZXZlbnQgaW5zdGFuY2VvZiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIC8vIEdldCB2YWxpZCBjbGlja2VkIHN0cnVjdHVyZUVsZW1lbnRcbiAgICAgICAgY29uc3QgY2xpY2tlZEVsZW1lbnQgPSAoZXZlbnQ/LnRhcmdldCBhcyBIVE1MRWxlbWVudCk/LmNsb3Nlc3QodGhpcy5zZWxlY3RvcnMpO1xuICAgICAgICBpZiAoY2xpY2tlZEVsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLmNsaWNrZWRFbGVtZW50ID0gY2xpY2tlZEVsZW1lbnQ7XG5cbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIC8vIFNldCBkaXNwbGF5IHN0YXR1c1xuICAgICAgICAgICAgY20uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0b3AgcG9zaXRpb25cbiAgICAgICAgICAgIGxldCB0b3AgPSBldmVudC55ICsgdGhpcy55R2FwO1xuICAgICAgICAgICAgaWYgKHRvcCArIGNtLm9mZnNldEhlaWdodCArIDEwID4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCkge1xuICAgICAgICAgICAgICB0b3AgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0IC0gY20ub2Zmc2V0SGVpZ2h0IC0gdGhpcy5vdmVyZmxvd1NwYWNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDYWxjdWxhdGUgbGVmdCBwb3NpdGlvblxuICAgICAgICAgICAgbGV0IGxlZnQgPSBldmVudC54ICsgdGhpcy54R2FwO1xuICAgICAgICAgICAgaWYgKGxlZnQgKyBjbS5vZmZzZXRXaWR0aCArIDEwID4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoKSB7XG4gICAgICAgICAgICAgIGxlZnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGggLSBjbS5vZmZzZXRXaWR0aCAtIHRoaXMub3ZlcmZsb3dTcGFjZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gU2V0IHBvc2l0aW9uXG4gICAgICAgICAgICBjbS5zdHlsZS50b3AgPSB0b3AgKyAncHgnO1xuICAgICAgICAgICAgY20uc3R5bGUubGVmdCA9IGxlZnQgKyAncHgnO1xuXG4gICAgICAgICAgICAvLyBTaG93XG4gICAgICAgICAgICBjbS5zdHlsZS5vcGFjaXR5ID0gJzEuMCc7XG4gICAgICAgICAgICBjbS5zdHlsZVsncG9pbnRlci1ldmVudHMnXSA9ICdhdXRvJztcbiAgICAgICAgICB9LCAxKTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBDbG9zZSBjb250ZXh0IG1lbnVcbiAgICAgIHRoaXMuY2xpY2tlZEVsZW1lbnQgPSBudWxsO1xuICAgICAgaWYgKHRoaXMucHJldmlvdXNEaXNwbGF5U3RhdHVzKSB7XG4gICAgICAgIGNtLnN0eWxlLmRpc3BsYXkgPSB0aGlzLnByZXZpb3VzRGlzcGxheVN0YXR1cztcbiAgICAgIH1cbiAgICAgIGNtLnN0eWxlLm9wYWNpdHkgPSAnMC4wMSc7XG4gICAgICBjbS5zdHlsZVsncG9pbnRlci1ldmVudHMnXSA9ICdub25lJztcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|