@smartbit4all/ng-client 4.2.114 → 4.2.115
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/smart-client/smart-component-api-client.mjs +34 -2
- package/esm2022/lib/smart-component-layout/api/api/api.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/api/default.service.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/api.module.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/configuration.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/encoder.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/index.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/model/componentType.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/model/layoutDirection.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/model/smartComponentWidgetDefinition.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/param.mjs +1 -1
- package/esm2022/lib/smart-component-layout/api/variables.mjs +1 -1
- package/esm2022/lib/smart-form/api/api/api.mjs +1 -1
- package/esm2022/lib/smart-form/api/api/default.service.mjs +1 -1
- package/esm2022/lib/smart-form/api/api.module.mjs +1 -1
- package/esm2022/lib/smart-form/api/configuration.mjs +1 -1
- package/esm2022/lib/smart-form/api/encoder.mjs +1 -1
- package/esm2022/lib/smart-form/api/index.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/fileUploaderProperties.mjs +2 -0
- package/esm2022/lib/smart-form/api/model/imageProperties.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/models.mjs +2 -1
- package/esm2022/lib/smart-form/api/model/propertyMapping.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/selectionDefinition.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/smartFormInputMode.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/smartFormWidgetDirection.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/smartFormWidgetType.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/smartLayoutDefinition.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/smartMatrixModel.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/smartWidgetDefinition.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/smartWidgetHint.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/sortDefinition.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/textFieldProperties.mjs +1 -1
- package/esm2022/lib/smart-form/api/model/valueChangeMode.mjs +1 -1
- package/esm2022/lib/smart-form/api/param.mjs +1 -1
- package/esm2022/lib/smart-form/api/variables.mjs +1 -1
- package/esm2022/lib/smart-form/services/smartform.layout-definition.service.mjs +2 -5
- package/esm2022/lib/smart-form/smartfileuploader/smartfileuploader.component.mjs +126 -29
- package/esm2022/lib/smart-form/smartform.form-model.mjs +1 -1
- package/esm2022/lib/smart-form/widgets/smartformwidget/smartformwidget.component.mjs +18 -13
- package/esm2022/lib/smart-map/api/api/api.mjs +1 -1
- package/esm2022/lib/smart-map/api/api/geoMap.service.mjs +1 -1
- package/esm2022/lib/smart-map/api/api.module.mjs +1 -1
- package/esm2022/lib/smart-map/api/configuration.mjs +1 -1
- package/esm2022/lib/smart-map/api/encoder.mjs +1 -1
- package/esm2022/lib/smart-map/api/index.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/gPSPosition.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/gPSRoute.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapChange.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapDataLoadingMode.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapDataSourceDescriptor.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapDataSourceType.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapEditingSession.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapInteraction.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapItem.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapItemKind.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapLayer.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapLayerChange.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapLayerDescriptor.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapModel.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapOperationMode.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapSelectionMode.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapServerModel.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapTextType.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapViewState.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/geoMapViewport.mjs +1 -1
- package/esm2022/lib/smart-map/api/model/models.mjs +1 -1
- package/esm2022/lib/smart-map/api/param.mjs +1 -1
- package/esm2022/lib/smart-map/api/variables.mjs +1 -1
- package/esm2022/lib/view-context/api/api/api.mjs +1 -1
- package/esm2022/lib/view-context/api/api/view.service.mjs +1 -1
- package/esm2022/lib/view-context/api/api.module.mjs +1 -1
- package/esm2022/lib/view-context/api/configuration.mjs +1 -1
- package/esm2022/lib/view-context/api/encoder.mjs +1 -1
- package/esm2022/lib/view-context/api/index.mjs +1 -1
- package/esm2022/lib/view-context/api/model/backgroundProcessInfo.mjs +1 -1
- package/esm2022/lib/view-context/api/model/badgeDescriptor.mjs +1 -1
- package/esm2022/lib/view-context/api/model/clipboardData.mjs +1 -1
- package/esm2022/lib/view-context/api/model/closeResult.mjs +1 -1
- package/esm2022/lib/view-context/api/model/componentConstraint.mjs +1 -1
- package/esm2022/lib/view-context/api/model/componentModel.mjs +1 -1
- package/esm2022/lib/view-context/api/model/componentModelChange.mjs +1 -1
- package/esm2022/lib/view-context/api/model/dataChange.mjs +1 -1
- package/esm2022/lib/view-context/api/model/dataChangeEvent.mjs +1 -1
- package/esm2022/lib/view-context/api/model/dataChangeKind.mjs +1 -1
- package/esm2022/lib/view-context/api/model/deviceInfo.mjs +1 -1
- package/esm2022/lib/view-context/api/model/downloadedFile.mjs +1 -1
- package/esm2022/lib/view-context/api/model/iconPosition.mjs +1 -1
- package/esm2022/lib/view-context/api/model/imageResource.mjs +1 -1
- package/esm2022/lib/view-context/api/model/link.mjs +1 -1
- package/esm2022/lib/view-context/api/model/messageData.mjs +1 -1
- package/esm2022/lib/view-context/api/model/messageOption.mjs +1 -1
- package/esm2022/lib/view-context/api/model/messageOptionType.mjs +1 -1
- package/esm2022/lib/view-context/api/model/messageResult.mjs +1 -1
- package/esm2022/lib/view-context/api/model/messageTextType.mjs +1 -1
- package/esm2022/lib/view-context/api/model/messageType.mjs +1 -1
- package/esm2022/lib/view-context/api/model/models.mjs +1 -1
- package/esm2022/lib/view-context/api/model/multiComboBoxElement.mjs +1 -1
- package/esm2022/lib/view-context/api/model/multiComboBoxModel.mjs +1 -1
- package/esm2022/lib/view-context/api/model/namedValidator.mjs +1 -1
- package/esm2022/lib/view-context/api/model/openPendingData.mjs +1 -1
- package/esm2022/lib/view-context/api/model/serverRequestExecutionStat.mjs +1 -1
- package/esm2022/lib/view-context/api/model/serverRequestTrack.mjs +1 -1
- package/esm2022/lib/view-context/api/model/serverRequestType.mjs +1 -1
- package/esm2022/lib/view-context/api/model/smartLinkData.mjs +1 -1
- package/esm2022/lib/view-context/api/model/smartLinkMigrationStatus.mjs +1 -1
- package/esm2022/lib/view-context/api/model/statisticRecord.mjs +1 -1
- package/esm2022/lib/view-context/api/model/style.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiAction.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionButtonDescriptor.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionButtonType.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionConstraint.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionDescriptor.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionDialogDescriptor.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionFeedbackType.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionInputType.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionRequest.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionTooltip.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uiActionUploadDescriptor.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uploadWidgetType.mjs +1 -1
- package/esm2022/lib/view-context/api/model/uploadedFile.mjs +1 -1
- package/esm2022/lib/view-context/api/model/valueSet.mjs +1 -1
- package/esm2022/lib/view-context/api/model/view.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewApiError.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewConstraint.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewContext.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewContextChange.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewContextData.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewContextUpdate.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewData.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewEventHandler.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewPlaceholder.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewState.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewStateUpdate.mjs +1 -1
- package/esm2022/lib/view-context/api/model/viewType.mjs +1 -1
- package/esm2022/lib/view-context/api/param.mjs +1 -1
- package/esm2022/lib/view-context/api/variables.mjs +1 -1
- package/esm2022/lib/view-context/projects.mjs +4 -3
- package/esm2022/lib/view-context/smart-ui-action/components/upload-widget/photo-capture-widget/photo-capture-widget.component.mjs +198 -0
- package/esm2022/lib/view-context/smart-ui-action/components/upload-widget/upload-widget.component.mjs +118 -0
- package/esm2022/lib/view-context/smart-ui-action/components/upload-widget/voice-record-widget/voice-record-widget.component.mjs +186 -0
- package/esm2022/lib/view-context/smart-ui-action/dialogs/ui-action-file-upload-dialog/ui-action-file-upload-dialog.component.mjs +15 -104
- package/esm2022/lib/view-context/smart-view-context.module.mjs +18 -13
- package/fesm2022/smartbit4all-ng-client.mjs +1177 -1023
- package/fesm2022/smartbit4all-ng-client.mjs.map +1 -1
- package/lib/smart-client/smart-component-api-client.d.ts +2 -0
- package/lib/smart-form/api/model/fileUploaderProperties.d.ts +17 -0
- package/lib/smart-form/api/model/models.d.ts +1 -0
- package/lib/smart-form/smartfileuploader/smartfileuploader.component.d.ts +15 -2
- package/lib/smart-form/smartform.form-model.d.ts +2 -2
- package/lib/smart-form/widgets/smartformwidget/smartformwidget.component.d.ts +10 -2
- package/lib/view-context/projects.d.ts +3 -2
- package/lib/view-context/smart-ui-action/components/upload-widget/upload-widget.component.d.ts +38 -0
- package/lib/view-context/smart-ui-action/dialogs/ui-action-file-upload-dialog/ui-action-file-upload-dialog.component.d.ts +2 -19
- package/lib/view-context/smart-view-context.module.d.ts +50 -49
- package/package.json +1 -1
- package/smartbit4all-ng-client-4.2.115.tgz +0 -0
- package/esm2022/lib/view-context/smart-ui-action/dialogs/ui-action-file-upload-dialog/photo-capture-widget/photo-capture-widget.component.mjs +0 -198
- package/esm2022/lib/view-context/smart-ui-action/dialogs/ui-action-file-upload-dialog/voice-record-widget/voice-record-widget.component.mjs +0 -186
- package/smartbit4all-ng-client-4.2.114.tgz +0 -0
- /package/lib/view-context/smart-ui-action/{dialogs/ui-action-file-upload-dialog → components/upload-widget}/photo-capture-widget/photo-capture-widget.component.d.ts +0 -0
- /package/lib/view-context/smart-ui-action/{dialogs/ui-action-file-upload-dialog → components/upload-widget}/voice-record-widget/voice-record-widget.component.d.ts +0 -0
|
@@ -82,6 +82,8 @@ export declare abstract class SmartComponentApiClient<T> implements UseUiAction2
|
|
|
82
82
|
addDataChangeActionHandler(key: string): void;
|
|
83
83
|
removeDataChangeActionHandler(key: string): void;
|
|
84
84
|
protected dataChangeActionHandler(event: SophisticatedValueChange): void;
|
|
85
|
+
protected handleLayoutUploadCallback(form: SmartComponentLayoutComponent): void;
|
|
86
|
+
protected handleUploadCallback(form: SmartformComponent): void;
|
|
85
87
|
protected handleDataChangeSubscriptions(): void;
|
|
86
88
|
getInvalidFields(): SmartFormInvalidFields;
|
|
87
89
|
protected validateForm(form: SmartformComponent | undefined, aggregatedInvalidFields: SmartFormInvalidFields): void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form layout definition
|
|
3
|
+
* Contains form layout definition objects.
|
|
4
|
+
*
|
|
5
|
+
* The version of the OpenAPI document: 1.0.0
|
|
6
|
+
* Contact: info@it4all.hu
|
|
7
|
+
*
|
|
8
|
+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
9
|
+
* https://openapi-generator.tech
|
|
10
|
+
* Do not edit the class manually.
|
|
11
|
+
*/
|
|
12
|
+
import { UiActionUploadDescriptor } from '../../../view-context/api/model/uiActionUploadDescriptor';
|
|
13
|
+
export interface FileUploaderProperties {
|
|
14
|
+
uiActionCode?: string;
|
|
15
|
+
isMultiple?: boolean;
|
|
16
|
+
uploadDescriptor?: UiActionUploadDescriptor;
|
|
17
|
+
}
|
|
@@ -1,22 +1,35 @@
|
|
|
1
1
|
import { ElementRef, OnInit } from '@angular/core';
|
|
2
2
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
3
3
|
import { SmartFileUploaderI18n } from './smartfileuploader.model';
|
|
4
|
+
import { UiActionDescriptor } from '../../view-context/api/model/models';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
export declare class SmartfileuploaderComponent implements OnInit {
|
|
6
7
|
private _snackBar;
|
|
7
8
|
fileInput: ElementRef<HTMLInputElement>;
|
|
8
|
-
files:
|
|
9
|
-
uploadCallback: (files:
|
|
9
|
+
files: File[];
|
|
10
|
+
uploadCallback: (files: File[]) => void;
|
|
10
11
|
fileFormats?: string[];
|
|
11
12
|
maxSizeMb?: number;
|
|
12
13
|
i18n?: SmartFileUploaderI18n;
|
|
13
14
|
useIconButton: boolean;
|
|
14
15
|
isMultiple?: boolean;
|
|
16
|
+
isDragOver: boolean;
|
|
17
|
+
errors: string[];
|
|
15
18
|
constructor(_snackBar: MatSnackBar);
|
|
16
19
|
ngOnInit(): void;
|
|
20
|
+
private processFiles;
|
|
17
21
|
getFile(event: any): void;
|
|
22
|
+
onDrop(event: DragEvent): void;
|
|
23
|
+
onDragOver(event: DragEvent): void;
|
|
24
|
+
onDragLeave(event: DragEvent): void;
|
|
18
25
|
remove(index: number): void;
|
|
19
26
|
uploadFile(): void;
|
|
27
|
+
formatSize(bytes: number): string;
|
|
28
|
+
filePreviewUrl(file: File): string | null;
|
|
29
|
+
downloadFile(file: File): void;
|
|
30
|
+
get uploadButton(): UiActionDescriptor;
|
|
31
|
+
get downloadButton(): UiActionDescriptor;
|
|
32
|
+
get removeButton(): UiActionDescriptor;
|
|
20
33
|
static ɵfac: i0.ɵɵFactoryDeclaration<SmartfileuploaderComponent, never>;
|
|
21
34
|
static ɵcmp: i0.ɵɵComponentDeclaration<SmartfileuploaderComponent, "smartfileuploader", never, { "uploadCallback": { "alias": "uploadCallback"; "required": false; }; "fileFormats": { "alias": "fileFormats"; "required": false; }; "maxSizeMb": { "alias": "maxSizeMb"; "required": false; }; "i18n": { "alias": "i18n"; "required": false; }; "useIconButton": { "alias": "useIconButton"; "required": false; }; "isMultiple": { "alias": "isMultiple"; "required": false; }; }, {}, never, never, false, never>;
|
|
22
35
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { QuillModules } from 'ngx-quill';
|
|
2
|
-
import { ImageProperties, SelectionDefinition, SmartFormInputMode, SmartFormWidgetDirection, SmartFormWidgetType, SmartWidgetHint, SortDefinition, TextFieldProperties, ValueChangeMode } from './api';
|
|
2
|
+
import { FileUploaderProperties, ImageProperties, SelectionDefinition, SmartFormInputMode, SmartFormWidgetDirection, SmartFormWidgetType, SmartWidgetHint, SortDefinition, TextFieldProperties, ValueChangeMode } from './api';
|
|
3
3
|
import { SmartFormTextFieldButton, SmartFormWidgetWidth, SmartIndicator, SmartValidator, ToggleLabelPosition } from './smartform.model';
|
|
4
4
|
import { ImageResource, Style } from '../view-context/api';
|
|
5
5
|
export declare type SmartFormWidget<T> = SmartTextField<T> | SmartTextFieldNumber<T> | SmartTextFieldChips<T> | SmartTextFieldLookup<T> | SmartTextBox<T> | SmartSelect<T> | SmartSelectMultiple<T> | SmartCheckBox<T> | SmartCheckBox2<T> | SmartRadioButton<T> | SmartDatePicker<T> | SmartDateTimePicker<T> | SmartContainer<T> | SmartLabel | SmartTime<T> | SmartToggle<T> | SmartIndicatorItem | SmartFileUploader | SmartImage | SmartDivider | SmartButton | SmartFormInlineComponent | SmartRichText | SmartSortable<T> | SmartMatrix | SmartYoutubePlayer | SmartMonthPicker | SmartSvg;
|
|
@@ -501,10 +501,10 @@ export interface SmartFileUploader {
|
|
|
501
501
|
cssLabelClass?: string;
|
|
502
502
|
style?: Style;
|
|
503
503
|
labelStyle?: Style;
|
|
504
|
-
uploadCallback: (key: string, files: any[]) => void;
|
|
505
504
|
fileFormats?: string[];
|
|
506
505
|
maxSizeMb?: number;
|
|
507
506
|
i18n?: any;
|
|
507
|
+
fileUploaderProperties?: FileUploaderProperties;
|
|
508
508
|
}
|
|
509
509
|
export interface SmartImage {
|
|
510
510
|
type: SmartFormWidgetType.IMAGE;
|
|
@@ -13,11 +13,18 @@ import { SmartButton, SmartFormWidget, SmartItem, SmartItems } from '../../smart
|
|
|
13
13
|
import { SmartFormTextFieldButtonIconPosition, SmartValidator, SophisticatedValueChange, Value } from '../../smartform.model';
|
|
14
14
|
import { ComponentLibrary } from '../../../view-context/utility/componentLibrary';
|
|
15
15
|
import { EditorTextChangeEvent } from 'primeng/editor';
|
|
16
|
-
import { UiActionDescriptor } from '../../../view-context/api';
|
|
16
|
+
import { UiActionDescriptor, UiActionUploadDescriptor } from '../../../view-context/api';
|
|
17
17
|
import * as i0 from "@angular/core";
|
|
18
18
|
export declare class SmartWidgetSettings {
|
|
19
19
|
static useUtc: boolean;
|
|
20
20
|
}
|
|
21
|
+
export interface UploadCallbackProps {
|
|
22
|
+
files: File[];
|
|
23
|
+
actionCode: string;
|
|
24
|
+
uploadDescriptor: UiActionUploadDescriptor;
|
|
25
|
+
isMultiple: Boolean;
|
|
26
|
+
}
|
|
27
|
+
export type UploadCallback = (props: UploadCallbackProps) => Promise<void>;
|
|
21
28
|
export declare class SmartformwidgetComponent implements OnInit, OnDestroy, AfterViewInit {
|
|
22
29
|
private service;
|
|
23
30
|
private cfService;
|
|
@@ -26,6 +33,7 @@ export declare class SmartformwidgetComponent implements OnInit, OnDestroy, Afte
|
|
|
26
33
|
changeDetector: ChangeDetectorRef;
|
|
27
34
|
private _destroy$;
|
|
28
35
|
hidePassword: boolean;
|
|
36
|
+
uploadCallback?: UploadCallback;
|
|
29
37
|
form: UntypedFormGroup;
|
|
30
38
|
widgetInstance: SmartFormWidget<any>;
|
|
31
39
|
onBlur?: Subject<any>;
|
|
@@ -128,7 +136,7 @@ export declare class SmartformwidgetComponent implements OnInit, OnDestroy, Afte
|
|
|
128
136
|
getIndicatorItemClass(index: number): string;
|
|
129
137
|
getIndicatorStatusLabelColor(): string;
|
|
130
138
|
getIndicatorStatusLabel(): string;
|
|
131
|
-
upload(
|
|
139
|
+
upload(event: any, uiACtionCode: string): void;
|
|
132
140
|
getButtonType(descriptor: any): string;
|
|
133
141
|
isOnlyIcon(descriptor: any): boolean;
|
|
134
142
|
onButtonClicked(instance: SmartButton): void;
|
|
@@ -13,7 +13,8 @@ export * from './smart-ui-action/dialogs/ui-action-input-dialog/ui-action-input-
|
|
|
13
13
|
export * from './smart-ui-action/dialogs/ui-action-input-dialog/ui-action-input-dialog.component';
|
|
14
14
|
export * from './smart-ui-action/dialogs/ui-action-dialog-button/ui-action-dialog-button.component';
|
|
15
15
|
export * from './utility/componentLibrary';
|
|
16
|
-
export * from './smart-ui-action/dialogs/ui-action-file-upload-dialog/photo-capture-widget/photo-capture-widget.component';
|
|
17
|
-
export * from './smart-ui-action/dialogs/ui-action-file-upload-dialog/voice-record-widget/voice-record-widget.component';
|
|
18
16
|
export * from './smart-ui-action/ui-action-button/ui-action-button.component';
|
|
19
17
|
export * from './smart-ui-action/components/menu/menu.component';
|
|
18
|
+
export * from './smart-ui-action/components/upload-widget/upload-widget.component';
|
|
19
|
+
export * from './smart-ui-action/components/upload-widget/photo-capture-widget/photo-capture-widget.component';
|
|
20
|
+
export * from './smart-ui-action/components/upload-widget/voice-record-widget/voice-record-widget.component';
|
package/lib/view-context/smart-ui-action/components/upload-widget/upload-widget.component.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ChangeDetectorRef, EventEmitter } from '@angular/core';
|
|
2
|
+
import { FileUpload } from 'primeng/fileupload';
|
|
3
|
+
import { UiActionUploadDescriptor, UploadWidgetType } from '../../../api';
|
|
4
|
+
import { ComponentLibrary } from '../../../utility/componentLibrary';
|
|
5
|
+
import { SmartfileuploaderComponent } from '../../../../smart-form/smartfileuploader/smartfileuploader.component';
|
|
6
|
+
import { SmartFileUploaderI18n } from '../../../../smart-form/smartfileuploader/smartfileuploader.model';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
export declare class UploadWidgetComponent {
|
|
9
|
+
private cdr;
|
|
10
|
+
compLib?: ComponentLibrary | undefined;
|
|
11
|
+
fileUploadPrime: FileUpload;
|
|
12
|
+
fileUploadMaterial: SmartfileuploaderComponent;
|
|
13
|
+
uploadDescriptor: UiActionUploadDescriptor;
|
|
14
|
+
isMultiple: boolean;
|
|
15
|
+
uploadFilesEvent: EventEmitter<{
|
|
16
|
+
files: any[];
|
|
17
|
+
uploadDescriptor?: UiActionUploadDescriptor | undefined;
|
|
18
|
+
}>;
|
|
19
|
+
componentLibrary: typeof ComponentLibrary;
|
|
20
|
+
uploadWidgetType: typeof UploadWidgetType;
|
|
21
|
+
i18n?: SmartFileUploaderI18n;
|
|
22
|
+
maxSizeMb: number;
|
|
23
|
+
fileFormats?: string[];
|
|
24
|
+
constructor(cdr: ChangeDetectorRef, compLib?: ComponentLibrary | undefined);
|
|
25
|
+
ngOnInit(): void;
|
|
26
|
+
isMobile(): boolean;
|
|
27
|
+
setUp(): Promise<void>;
|
|
28
|
+
upload(files: any[]): void;
|
|
29
|
+
uploadFiles(event: any): void;
|
|
30
|
+
uploadRecording(file: any): void;
|
|
31
|
+
uploadImage(files: any): void;
|
|
32
|
+
loadFilesIntoWidget(files: File[]): void;
|
|
33
|
+
widgetNeeded(type: UploadWidgetType): boolean;
|
|
34
|
+
downloadFile(file: File): void;
|
|
35
|
+
formatSize(bytes: number): string;
|
|
36
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<UploadWidgetComponent, [null, { optional: true; }]>;
|
|
37
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<UploadWidgetComponent, "smart-upload-widget", never, { "uploadDescriptor": { "alias": "uploadDescriptor"; "required": false; }; "isMultiple": { "alias": "isMultiple"; "required": false; }; }, { "uploadFilesEvent": "uploadFilesEvent"; }, never, never, false, never>;
|
|
38
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { ChangeDetectorRef, OnDestroy } from '@angular/core';
|
|
2
|
-
import { UiActionDescriptor
|
|
2
|
+
import { UiActionDescriptor } from '../../../api';
|
|
3
3
|
import { UiActionDescriptorService } from '../../ui-action.descriptor.service';
|
|
4
4
|
import { UiActionFileUploadDialogService } from './ui-action-file-upload-dialog.service';
|
|
5
|
-
import { SmartFileUploaderI18n } from '../../../../smart-form/smartfileuploader/smartfileuploader.model';
|
|
6
5
|
import { ComponentLibrary } from '../../../projects';
|
|
7
6
|
import { FileUpload } from 'primeng/fileupload';
|
|
8
7
|
import { SmartfileuploaderComponent } from '../../../../smart-form/smartfileuploader/smartfileuploader.component';
|
|
@@ -18,13 +17,7 @@ export declare class UiActionFileUploadDialogComponent implements OnDestroy {
|
|
|
18
17
|
dialogType: 'dialog' | 'inputDialog' | 'input2Dialog';
|
|
19
18
|
descriptor?: UiActionDescriptor;
|
|
20
19
|
componentLibrary: typeof ComponentLibrary;
|
|
21
|
-
uploadWidgetType: typeof UploadWidgetType;
|
|
22
|
-
i18n?: SmartFileUploaderI18n;
|
|
23
|
-
maxSizeMb: number;
|
|
24
|
-
fileFormats?: string[];
|
|
25
20
|
isMultiple?: boolean;
|
|
26
|
-
hasFiles?: boolean;
|
|
27
|
-
uploadedFiles: any[];
|
|
28
21
|
cancelButton: UiActionDescriptor;
|
|
29
22
|
constructor(service: UiActionFileUploadDialogService, compLib: ComponentLibrary, manager: UiActionDescriptorService, cdr: ChangeDetectorRef);
|
|
30
23
|
ngOnDestroy(): void;
|
|
@@ -36,18 +29,8 @@ export declare class UiActionFileUploadDialogComponent implements OnDestroy {
|
|
|
36
29
|
getActionButtonColor(): string;
|
|
37
30
|
getCancelButtonLabel(): string;
|
|
38
31
|
getCancelButtonColor(): string;
|
|
39
|
-
upload(
|
|
40
|
-
onSelect(event: any): void;
|
|
41
|
-
onRemove(event: any): void;
|
|
42
|
-
uploadFiles(event: any): void;
|
|
32
|
+
upload(event: any): void;
|
|
43
33
|
cancel(): void;
|
|
44
|
-
uploadRecording(file: any): void;
|
|
45
|
-
uploadImage(files: any): void;
|
|
46
|
-
loadFilesIntoWidget(files: File[]): void;
|
|
47
|
-
widgetNeeded(type: UploadWidgetType): boolean;
|
|
48
|
-
downloadFile(file: File): void;
|
|
49
|
-
removeFile(index: number): void;
|
|
50
|
-
formatSize(bytes: number): string;
|
|
51
34
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiActionFileUploadDialogComponent, never>;
|
|
52
35
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiActionFileUploadDialogComponent, "lib-ui-action-file-upload-dialog", never, {}, {}, never, never, false, never>;
|
|
53
36
|
}
|
|
@@ -18,56 +18,57 @@ import * as i16 from "../smart-form/smartfileuploader/large-file-snack-bar/large
|
|
|
18
18
|
import * as i17 from "../smart-form/widgets/smartformwidget/sortable-widget/sortable-widget.component";
|
|
19
19
|
import * as i18 from "../smart-form/widgets/components/smart-month-picker/smart-month-picker.component";
|
|
20
20
|
import * as i19 from "../smart-form/highlightMacthingString-pipe";
|
|
21
|
-
import * as i20 from "./smart-ui-action/
|
|
22
|
-
import * as i21 from "./smart-ui-action/
|
|
23
|
-
import * as i22 from "./smart-ui-action/
|
|
24
|
-
import * as i23 from "./smart-ui-action/components/
|
|
25
|
-
import * as i24 from "
|
|
26
|
-
import * as i25 from "@angular/common
|
|
27
|
-
import * as i26 from "@angular/
|
|
28
|
-
import * as i27 from "@angular/material/
|
|
29
|
-
import * as i28 from "
|
|
30
|
-
import * as i29 from "
|
|
31
|
-
import * as i30 from "@angular/material/
|
|
32
|
-
import * as i31 from "
|
|
33
|
-
import * as i32 from "
|
|
34
|
-
import * as i33 from "
|
|
35
|
-
import * as i34 from "
|
|
36
|
-
import * as i35 from "
|
|
37
|
-
import * as i36 from "@angular/
|
|
38
|
-
import * as i37 from "@angular/
|
|
39
|
-
import * as i38 from "@angular/
|
|
40
|
-
import * as i39 from "@angular/material/
|
|
41
|
-
import * as i40 from "@angular/material/
|
|
42
|
-
import * as i41 from "@angular/material/
|
|
43
|
-
import * as i42 from "@angular/material/
|
|
44
|
-
import * as i43 from "@angular/material
|
|
45
|
-
import * as i44 from "@angular/material
|
|
46
|
-
import * as i45 from "@angular/material/
|
|
47
|
-
import * as i46 from "@angular/material/
|
|
48
|
-
import * as i47 from "
|
|
49
|
-
import * as i48 from "
|
|
50
|
-
import * as i49 from "@angular/
|
|
51
|
-
import * as i50 from "
|
|
52
|
-
import * as i51 from "primeng/
|
|
53
|
-
import * as i52 from "primeng/
|
|
54
|
-
import * as i53 from "primeng/
|
|
55
|
-
import * as i54 from "primeng/
|
|
56
|
-
import * as i55 from "primeng/
|
|
57
|
-
import * as i56 from "primeng/
|
|
58
|
-
import * as i57 from "primeng/
|
|
59
|
-
import * as i58 from "primeng/
|
|
60
|
-
import * as i59 from "primeng/
|
|
61
|
-
import * as i60 from "primeng/
|
|
62
|
-
import * as i61 from "primeng/
|
|
63
|
-
import * as i62 from "primeng/
|
|
64
|
-
import * as i63 from "primeng/
|
|
65
|
-
import * as i64 from "primeng/
|
|
66
|
-
import * as i65 from "primeng/
|
|
67
|
-
import * as i66 from "primeng/
|
|
68
|
-
import * as i67 from "
|
|
21
|
+
import * as i20 from "./smart-ui-action/ui-action-button/ui-action-button.component";
|
|
22
|
+
import * as i21 from "./smart-ui-action/components/menu/menu.component";
|
|
23
|
+
import * as i22 from "./smart-ui-action/components/upload-widget/upload-widget.component";
|
|
24
|
+
import * as i23 from "./smart-ui-action/components/upload-widget/voice-record-widget/voice-record-widget.component";
|
|
25
|
+
import * as i24 from "./smart-ui-action/components/upload-widget/photo-capture-widget/photo-capture-widget.component";
|
|
26
|
+
import * as i25 from "@angular/common";
|
|
27
|
+
import * as i26 from "@angular/common/http";
|
|
28
|
+
import * as i27 from "@angular/material/core";
|
|
29
|
+
import * as i28 from "@angular/material/button";
|
|
30
|
+
import * as i29 from "primeng/button";
|
|
31
|
+
import * as i30 from "@angular/material/icon";
|
|
32
|
+
import * as i31 from "@angular/material/snack-bar";
|
|
33
|
+
import * as i32 from "../smart-icon/smart-icon.module";
|
|
34
|
+
import * as i33 from "@angular/material/tooltip";
|
|
35
|
+
import * as i34 from "../shared/shared.module";
|
|
36
|
+
import * as i35 from "primeng/api";
|
|
37
|
+
import * as i36 from "@angular/platform-browser";
|
|
38
|
+
import * as i37 from "@angular/material/chips";
|
|
39
|
+
import * as i38 from "@angular/forms";
|
|
40
|
+
import * as i39 from "@angular/material/form-field";
|
|
41
|
+
import * as i40 from "@angular/material/checkbox";
|
|
42
|
+
import * as i41 from "@angular/material/select";
|
|
43
|
+
import * as i42 from "@angular/material/input";
|
|
44
|
+
import * as i43 from "@angular/material/datepicker";
|
|
45
|
+
import * as i44 from "@angular/material-moment-adapter";
|
|
46
|
+
import * as i45 from "@angular/material/radio";
|
|
47
|
+
import * as i46 from "@angular/material/slide-toggle";
|
|
48
|
+
import * as i47 from "@angular/material/autocomplete";
|
|
49
|
+
import * as i48 from "ngx-quill";
|
|
50
|
+
import * as i49 from "@angular/cdk/drag-drop";
|
|
51
|
+
import * as i50 from "@angular/youtube-player";
|
|
52
|
+
import * as i51 from "primeng/inputtext";
|
|
53
|
+
import * as i52 from "primeng/dropdown";
|
|
54
|
+
import * as i53 from "primeng/multiselect";
|
|
55
|
+
import * as i54 from "primeng/inputswitch";
|
|
56
|
+
import * as i55 from "primeng/inputnumber";
|
|
57
|
+
import * as i56 from "primeng/inputtextarea";
|
|
58
|
+
import * as i57 from "primeng/image";
|
|
59
|
+
import * as i58 from "primeng/floatlabel";
|
|
60
|
+
import * as i59 from "primeng/toast";
|
|
61
|
+
import * as i60 from "primeng/dynamicdialog";
|
|
62
|
+
import * as i61 from "primeng/fileupload";
|
|
63
|
+
import * as i62 from "primeng/chips";
|
|
64
|
+
import * as i63 from "primeng/calendar";
|
|
65
|
+
import * as i64 from "primeng/checkbox";
|
|
66
|
+
import * as i65 from "primeng/orderlist";
|
|
67
|
+
import * as i66 from "primeng/inputmask";
|
|
68
|
+
import * as i67 from "primeng/editor";
|
|
69
|
+
import * as i68 from "@angular/material/menu";
|
|
69
70
|
export declare class SmartViewContextModule {
|
|
70
71
|
static ɵfac: i0.ɵɵFactoryDeclaration<SmartViewContextModule, never>;
|
|
71
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<SmartViewContextModule, [typeof i1.MessageDialogComponent, typeof i2.SmartViewContextErrorDialogComponent, typeof i3.SmartViewRedirect, typeof i4.UiActionToolbarComponent, typeof i5.UiActionInputDialogComponent, typeof i6.UiActionConfirmDialogComponent, typeof i7.UiActionFileUploadDialogComponent, typeof i8.InvalidFieldsSnackBarComponent, typeof i9.SmartformComponent, typeof i10.UiActionDialogButtonComponent, typeof i11.SmartformwidgetComponent, typeof i12.SmartfileuploaderComponent, typeof i13.TrackCapsDirective, typeof i14.ComparableDropdownDirective, typeof i15.ComparableMultiselectDirective, typeof i16.LargeFileSnackBarComponent, typeof i17.SortableWidgetComponent, typeof i18.SmartMonthPickerComponent, typeof i19.HighlightPipe, typeof i20.
|
|
72
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<SmartViewContextModule, [typeof i1.MessageDialogComponent, typeof i2.SmartViewContextErrorDialogComponent, typeof i3.SmartViewRedirect, typeof i4.UiActionToolbarComponent, typeof i5.UiActionInputDialogComponent, typeof i6.UiActionConfirmDialogComponent, typeof i7.UiActionFileUploadDialogComponent, typeof i8.InvalidFieldsSnackBarComponent, typeof i9.SmartformComponent, typeof i10.UiActionDialogButtonComponent, typeof i11.SmartformwidgetComponent, typeof i12.SmartfileuploaderComponent, typeof i13.TrackCapsDirective, typeof i14.ComparableDropdownDirective, typeof i15.ComparableMultiselectDirective, typeof i16.LargeFileSnackBarComponent, typeof i17.SortableWidgetComponent, typeof i18.SmartMonthPickerComponent, typeof i19.HighlightPipe, typeof i20.UiActionButtonComponent, typeof i21.MenuComponent, typeof i22.UploadWidgetComponent, typeof i23.VoiceRecordWidgetComponent, typeof i24.PhotoCaptureWidgetComponent], [typeof i25.CommonModule, typeof i26.HttpClientModule, typeof i27.MatCommonModule, typeof i28.MatButtonModule, typeof i29.ButtonModule, typeof i30.MatIconModule, typeof i31.MatSnackBarModule, typeof i32.SmartIconModule, typeof i33.MatTooltipModule, typeof i34.SharedModule, typeof i35.SharedModule, typeof i36.BrowserModule, typeof i37.MatChipsModule, typeof i38.FormsModule, typeof i38.ReactiveFormsModule, typeof i39.MatFormFieldModule, typeof i40.MatCheckboxModule, typeof i41.MatSelectModule, typeof i42.MatInputModule, typeof i43.MatDatepickerModule, typeof i44.MatMomentDateModule, typeof i45.MatRadioModule, typeof i46.MatSlideToggleModule, typeof i47.MatAutocompleteModule, typeof i48.QuillModule, typeof i49.DragDropModule, typeof i50.YouTubePlayerModule, typeof i51.InputTextModule, typeof i52.DropdownModule, typeof i53.MultiSelectModule, typeof i38.FormsModule, typeof i54.InputSwitchModule, typeof i55.InputNumberModule, typeof i56.InputTextareaModule, typeof i57.ImageModule, typeof i58.FloatLabelModule, typeof i25.CommonModule, typeof i59.ToastModule, typeof i60.DynamicDialogModule, typeof i61.FileUploadModule, typeof i62.ChipsModule, typeof i63.CalendarModule, typeof i64.CheckboxModule, typeof i65.OrderListModule, typeof i66.InputMaskModule, typeof i67.EditorModule, typeof i68.MatMenuModule, typeof i32.SmartIconModule], [typeof i4.UiActionToolbarComponent, typeof i5.UiActionInputDialogComponent, typeof i9.SmartformComponent, typeof i11.SmartformwidgetComponent, typeof i10.UiActionDialogButtonComponent, typeof i12.SmartfileuploaderComponent, typeof i19.HighlightPipe, typeof i14.ComparableDropdownDirective, typeof i15.ComparableMultiselectDirective, typeof i20.UiActionButtonComponent, typeof i21.MenuComponent, typeof i22.UploadWidgetComponent, typeof i23.VoiceRecordWidgetComponent, typeof i24.PhotoCaptureWidgetComponent]>;
|
|
72
73
|
static ɵinj: i0.ɵɵInjectorDeclaration<SmartViewContextModule>;
|
|
73
74
|
}
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { Component, EventEmitter, Inject, Input, Optional, Output, ViewChild, } from '@angular/core';
|
|
2
|
-
import { COMPONENT_LIBRARY, ComponentLibrary } from '../../../../utility/componentLibrary';
|
|
3
|
-
import { UiActionButtonType } from '../../../../api/model/uiActionButtonType';
|
|
4
|
-
import { IconPosition } from '../../../../api/model/iconPosition';
|
|
5
|
-
import * as i0 from "@angular/core";
|
|
6
|
-
import * as i1 from "@angular/common";
|
|
7
|
-
import * as i2 from "../../../ui-action-button/ui-action-button.component";
|
|
8
|
-
import * as i3 from "../../../../utility/componentLibrary";
|
|
9
|
-
export class PhotoCaptureWidgetComponent {
|
|
10
|
-
constructor(compLib) {
|
|
11
|
-
this.photoCaptured = new EventEmitter();
|
|
12
|
-
this.cameraActive = false;
|
|
13
|
-
this.isCaptured = false;
|
|
14
|
-
this.componentLibrary = ComponentLibrary;
|
|
15
|
-
this.captureButton = {
|
|
16
|
-
type: UiActionButtonType.RAISED,
|
|
17
|
-
title: 'Kép készítése',
|
|
18
|
-
icon: 'camera',
|
|
19
|
-
iconPosition: IconPosition.PRE,
|
|
20
|
-
color: 'primary',
|
|
21
|
-
};
|
|
22
|
-
this.compLib = compLib ?? ComponentLibrary.PRIMENG;
|
|
23
|
-
this.updateToggleButton();
|
|
24
|
-
}
|
|
25
|
-
isMobile() {
|
|
26
|
-
return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
|
27
|
-
}
|
|
28
|
-
async startCamera() {
|
|
29
|
-
this.stream = await navigator.mediaDevices.getUserMedia({ video: true });
|
|
30
|
-
this.videoRef.nativeElement.srcObject = this.stream;
|
|
31
|
-
this.videoRef.nativeElement.play();
|
|
32
|
-
this.cameraActive = true;
|
|
33
|
-
this.isCaptured = false;
|
|
34
|
-
this.updateToggleButton();
|
|
35
|
-
}
|
|
36
|
-
stopCamera() {
|
|
37
|
-
this.stream?.getTracks().forEach((track) => track.stop());
|
|
38
|
-
this.stream = undefined;
|
|
39
|
-
this.cameraActive = false;
|
|
40
|
-
this.updateToggleButton();
|
|
41
|
-
}
|
|
42
|
-
async capturePhoto() {
|
|
43
|
-
const video = this.videoRef.nativeElement;
|
|
44
|
-
const canvas = this.canvasRef.nativeElement;
|
|
45
|
-
const context = canvas.getContext('2d');
|
|
46
|
-
if (!context)
|
|
47
|
-
return;
|
|
48
|
-
canvas.width = video.videoWidth;
|
|
49
|
-
canvas.height = video.videoHeight;
|
|
50
|
-
context.drawImage(video, 0, 0);
|
|
51
|
-
const blob = await new Promise((resolve) => canvas.toBlob(resolve, 'image/jpeg', 0.9));
|
|
52
|
-
if (!blob)
|
|
53
|
-
return;
|
|
54
|
-
let file = new File([blob], `photo_${Date.now()}.jpg`, { type: 'image/jpeg' });
|
|
55
|
-
if (this.maxFileSize && file.size > this.maxFileSize) {
|
|
56
|
-
file = await this.compressImageFile(file, this.maxFileSize);
|
|
57
|
-
}
|
|
58
|
-
this.photoCaptured.emit([file]);
|
|
59
|
-
this.isCaptured = true;
|
|
60
|
-
this.stopCamera();
|
|
61
|
-
}
|
|
62
|
-
getPhotoDataURL() {
|
|
63
|
-
return this.canvasRef.nativeElement.toDataURL('image/png');
|
|
64
|
-
}
|
|
65
|
-
async onFileSelected(event) {
|
|
66
|
-
const input = event.target;
|
|
67
|
-
if (!input.files || input.files.length === 0)
|
|
68
|
-
return;
|
|
69
|
-
const maxSize = this.maxFileSize;
|
|
70
|
-
const filesArray = Array.from(input.files);
|
|
71
|
-
const processedFiles = [];
|
|
72
|
-
for (const file of filesArray) {
|
|
73
|
-
if (maxSize && file.size > maxSize && file.type.startsWith('image/')) {
|
|
74
|
-
try {
|
|
75
|
-
const compressed = await this.compressImageFile(file, maxSize);
|
|
76
|
-
processedFiles.push(compressed);
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
processedFiles.push(file);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
processedFiles.push(file);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
this.photoCaptured.emit(processedFiles);
|
|
87
|
-
}
|
|
88
|
-
toggleCamera() {
|
|
89
|
-
if (this.cameraActive) {
|
|
90
|
-
this.stopCamera();
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
this.startCamera();
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
updateToggleButton() {
|
|
97
|
-
let icon = this.compLib === ComponentLibrary.PRIMENG ? 'power-off' : 'power_settings_new';
|
|
98
|
-
let title;
|
|
99
|
-
let color;
|
|
100
|
-
if (this.cameraActive) {
|
|
101
|
-
title = 'Kamera kikapcsolása';
|
|
102
|
-
color = this.compLib === ComponentLibrary.PRIMENG ? 'danger' : 'red';
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
title = 'Kamera bekapcsolása';
|
|
106
|
-
color = 'primary';
|
|
107
|
-
}
|
|
108
|
-
this.toggleCameraButton = {
|
|
109
|
-
type: UiActionButtonType.RAISED,
|
|
110
|
-
title: title,
|
|
111
|
-
icon: icon,
|
|
112
|
-
color,
|
|
113
|
-
iconPosition: IconPosition.PRE,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
async compressImageFile(file, maxFileSize) {
|
|
117
|
-
if (!file.type.startsWith('image/'))
|
|
118
|
-
return file;
|
|
119
|
-
const img = await new Promise((resolve, reject) => {
|
|
120
|
-
const url = URL.createObjectURL(file);
|
|
121
|
-
const image = new Image();
|
|
122
|
-
image.onload = () => {
|
|
123
|
-
URL.revokeObjectURL(url);
|
|
124
|
-
resolve(image);
|
|
125
|
-
};
|
|
126
|
-
image.onerror = (e) => {
|
|
127
|
-
URL.revokeObjectURL(url);
|
|
128
|
-
reject(e);
|
|
129
|
-
};
|
|
130
|
-
image.src = url;
|
|
131
|
-
});
|
|
132
|
-
const canvas = document.createElement('canvas');
|
|
133
|
-
const ctx = canvas.getContext('2d');
|
|
134
|
-
if (!ctx)
|
|
135
|
-
return file;
|
|
136
|
-
let width = img.naturalWidth;
|
|
137
|
-
let height = img.naturalHeight;
|
|
138
|
-
let quality = 0.9;
|
|
139
|
-
const minQuality = 0.4;
|
|
140
|
-
const minDimension = 640;
|
|
141
|
-
const getBlob = (q) => new Promise((resolve) => {
|
|
142
|
-
canvas.width = width;
|
|
143
|
-
canvas.height = height;
|
|
144
|
-
ctx.clearRect(0, 0, width, height);
|
|
145
|
-
ctx.drawImage(img, 0, 0, width, height);
|
|
146
|
-
canvas.toBlob((blob) => {
|
|
147
|
-
if (blob)
|
|
148
|
-
resolve(blob);
|
|
149
|
-
}, 'image/jpeg', q);
|
|
150
|
-
});
|
|
151
|
-
let blob = await getBlob(quality);
|
|
152
|
-
while (blob.size > maxFileSize) {
|
|
153
|
-
if (quality > minQuality) {
|
|
154
|
-
quality -= 0.1;
|
|
155
|
-
}
|
|
156
|
-
else if (width > minDimension && height > minDimension) {
|
|
157
|
-
width = Math.floor(width * 0.8);
|
|
158
|
-
height = Math.floor(height * 0.8);
|
|
159
|
-
quality = 0.9;
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
blob = await getBlob(quality);
|
|
165
|
-
}
|
|
166
|
-
if (blob.size <= maxFileSize) {
|
|
167
|
-
return new File([blob], file.name, { type: 'image/jpeg' });
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
return file;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PhotoCaptureWidgetComponent, deps: [{ token: COMPONENT_LIBRARY, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
174
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PhotoCaptureWidgetComponent, selector: "photo-capture-widget", inputs: { maxFileSize: "maxFileSize" }, outputs: { photoCaptured: "photoCaptured" }, viewQueries: [{ propertyName: "videoRef", first: true, predicate: ["video"], descendants: true }, { propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true }, { propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"photoWidgetContainer\">\r\n <ng-container *ngIf=\"!isMobile()\">\r\n <video #video autoplay [hidden]=\"isCaptured || !cameraActive\"></video>\r\n <canvas #canvas [hidden]=\"!isCaptured || cameraActive\"></canvas>\r\n\r\n <ng-container *ngIf=\"!cameraActive && !isCaptured\">\r\n <p class=\"message\">Kapcsolja be a kamer\u00E1t a k\u00E9p k\u00E9sz\u00EDt\u00E9s\u00E9hez!</p>\r\n </ng-container>\r\n\r\n <div class=\"controls\">\r\n <!-- START CAMERA -->\r\n <ui-action-button [descriptor]=\"toggleCameraButton\" (actionClick)=\"toggleCamera()\">\r\n </ui-action-button>\r\n\r\n <!-- CAPTURE CAMERA -->\r\n <ui-action-button\r\n [disabled]=\"!cameraActive\"\r\n [descriptor]=\"captureButton\"\r\n (actionClick)=\"capturePhoto()\"\r\n >\r\n </ui-action-button>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"isMobile()\">\r\n <div class=\"controls\">\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\"image/*\"\r\n capture=\"environment\"\r\n (change)=\"onFileSelected($event)\"\r\n style=\"display: none\"\r\n />\r\n\r\n <ui-action-button [descriptor]=\"captureButton\" (actionClick)=\"fileInput.click()\">\r\n </ui-action-button>\r\n </div>\r\n </ng-container>\r\n</div>\r\n", styles: [".photoWidgetContainer{border-radius:5px;width:100%;max-width:100%;display:flex;flex-direction:column;justify-content:center;border:1px solid #dee2e6}.message{text-align:center;color:#6b7280}video,canvas{border-top-right-radius:5px;border-top-left-radius:5px;width:100%}.controls{padding:.5rem;display:flex;gap:1rem;flex-direction:row;justify-content:center;background:#f8f9fa;border-top:1px solid #dee2e6;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.controls ::ng-deep button{border-radius:3px}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.UiActionButtonComponent, selector: "ui-action-button", inputs: ["disabled", "descriptor", "code", "addedCssClass"], outputs: ["actionClick", "actionDoubleClick"] }] }); }
|
|
175
|
-
}
|
|
176
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PhotoCaptureWidgetComponent, decorators: [{
|
|
177
|
-
type: Component,
|
|
178
|
-
args: [{ selector: 'photo-capture-widget', template: "<div class=\"photoWidgetContainer\">\r\n <ng-container *ngIf=\"!isMobile()\">\r\n <video #video autoplay [hidden]=\"isCaptured || !cameraActive\"></video>\r\n <canvas #canvas [hidden]=\"!isCaptured || cameraActive\"></canvas>\r\n\r\n <ng-container *ngIf=\"!cameraActive && !isCaptured\">\r\n <p class=\"message\">Kapcsolja be a kamer\u00E1t a k\u00E9p k\u00E9sz\u00EDt\u00E9s\u00E9hez!</p>\r\n </ng-container>\r\n\r\n <div class=\"controls\">\r\n <!-- START CAMERA -->\r\n <ui-action-button [descriptor]=\"toggleCameraButton\" (actionClick)=\"toggleCamera()\">\r\n </ui-action-button>\r\n\r\n <!-- CAPTURE CAMERA -->\r\n <ui-action-button\r\n [disabled]=\"!cameraActive\"\r\n [descriptor]=\"captureButton\"\r\n (actionClick)=\"capturePhoto()\"\r\n >\r\n </ui-action-button>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"isMobile()\">\r\n <div class=\"controls\">\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\"image/*\"\r\n capture=\"environment\"\r\n (change)=\"onFileSelected($event)\"\r\n style=\"display: none\"\r\n />\r\n\r\n <ui-action-button [descriptor]=\"captureButton\" (actionClick)=\"fileInput.click()\">\r\n </ui-action-button>\r\n </div>\r\n </ng-container>\r\n</div>\r\n", styles: [".photoWidgetContainer{border-radius:5px;width:100%;max-width:100%;display:flex;flex-direction:column;justify-content:center;border:1px solid #dee2e6}.message{text-align:center;color:#6b7280}video,canvas{border-top-right-radius:5px;border-top-left-radius:5px;width:100%}.controls{padding:.5rem;display:flex;gap:1rem;flex-direction:row;justify-content:center;background:#f8f9fa;border-top:1px solid #dee2e6;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.controls ::ng-deep button{border-radius:3px}\n"] }]
|
|
179
|
-
}], ctorParameters: () => [{ type: i3.ComponentLibrary, decorators: [{
|
|
180
|
-
type: Inject,
|
|
181
|
-
args: [COMPONENT_LIBRARY]
|
|
182
|
-
}, {
|
|
183
|
-
type: Optional
|
|
184
|
-
}] }], propDecorators: { videoRef: [{
|
|
185
|
-
type: ViewChild,
|
|
186
|
-
args: ['video']
|
|
187
|
-
}], canvasRef: [{
|
|
188
|
-
type: ViewChild,
|
|
189
|
-
args: ['canvas']
|
|
190
|
-
}], fileInputRef: [{
|
|
191
|
-
type: ViewChild,
|
|
192
|
-
args: ['fileInput']
|
|
193
|
-
}], maxFileSize: [{
|
|
194
|
-
type: Input
|
|
195
|
-
}], photoCaptured: [{
|
|
196
|
-
type: Output
|
|
197
|
-
}] } });
|
|
198
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGhvdG8tY2FwdHVyZS13aWRnZXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtbmctY2xpZW50L3NyYy9saWIvdmlldy1jb250ZXh0L3NtYXJ0LXVpLWFjdGlvbi9kaWFsb2dzL3VpLWFjdGlvbi1maWxlLXVwbG9hZC1kaWFsb2cvcGhvdG8tY2FwdHVyZS13aWRnZXQvcGhvdG8tY2FwdHVyZS13aWRnZXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtbmctY2xpZW50L3NyYy9saWIvdmlldy1jb250ZXh0L3NtYXJ0LXVpLWFjdGlvbi9kaWFsb2dzL3VpLWFjdGlvbi1maWxlLXVwbG9hZC1kaWFsb2cvcGhvdG8tY2FwdHVyZS13aWRnZXQvcGhvdG8tY2FwdHVyZS13aWRnZXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUUzRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7Ozs7O0FBUWxFLE1BQU0sT0FBTywyQkFBMkI7SUEwQnRDLFlBQW1ELE9BQTBCO1FBcEJuRSxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFFckQsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDckIsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUtuQixxQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztRQUlwQyxrQkFBYSxH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QUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUM3RCxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7K0dBcE1VLDJCQUEyQixrQkEwQmxCLGlCQUFpQjttR0ExQjFCLDJCQUEyQixzYUNyQnhDLG0xQ0F3Q0E7OzRGRG5CYSwyQkFBMkI7a0JBTHZDLFNBQVM7K0JBQ0Usc0JBQXNCOzswQkE4Qm5CLE1BQU07MkJBQUMsaUJBQWlCOzswQkFBRyxRQUFRO3lDQXpCNUIsUUFBUTtzQkFBM0IsU0FBUzt1QkFBQyxPQUFPO2dCQUNHLFNBQVM7c0JBQTdCLFNBQVM7dUJBQUMsUUFBUTtnQkFDSyxZQUFZO3NCQUFuQyxTQUFTO3VCQUFDLFdBQVc7Z0JBRWIsV0FBVztzQkFBbkIsS0FBSztnQkFDSSxhQUFhO3NCQUF0QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5qZWN0LFxyXG4gIElucHV0LFxyXG4gIE9wdGlvbmFsLFxyXG4gIE91dHB1dCxcclxuICBWaWV3Q2hpbGQsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENPTVBPTkVOVF9MSUJSQVJZLCBDb21wb25lbnRMaWJyYXJ5IH0gZnJvbSAnLi4vLi4vLi4vLi4vdXRpbGl0eS9jb21wb25lbnRMaWJyYXJ5JztcclxuaW1wb3J0IHsgVWlBY3Rpb25Nb2RlbCB9IGZyb20gJy4uLy4uLy4uL3VpLWFjdGlvbi5tb2RlbCc7XHJcbmltcG9ydCB7IFVpQWN0aW9uQnV0dG9uVHlwZSB9IGZyb20gJy4uLy4uLy4uLy4uL2FwaS9tb2RlbC91aUFjdGlvbkJ1dHRvblR5cGUnO1xyXG5pbXBvcnQgeyBJY29uUG9zaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9hcGkvbW9kZWwvaWNvblBvc2l0aW9uJztcclxuaW1wb3J0IHsgVWlBY3Rpb25EZXNjcmlwdG9yIH0gZnJvbSAnLi4vLi4vLi4vLi4vYXBpJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAncGhvdG8tY2FwdHVyZS13aWRnZXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9waG90by1jYXB0dXJlLXdpZGdldC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL3Bob3RvLWNhcHR1cmUtd2lkZ2V0LmNvbXBvbmVudC5jc3MnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgUGhvdG9DYXB0dXJlV2lkZ2V0Q29tcG9uZW50IHtcclxuICBAVmlld0NoaWxkKCd2aWRlbycpIHZpZGVvUmVmITogRWxlbWVudFJlZjxIVE1MVmlkZW9FbGVtZW50PjtcclxuICBAVmlld0NoaWxkKCdjYW52YXMnKSBjYW52YXNSZWYhOiBFbGVtZW50UmVmPEhUTUxDYW52YXNFbGVtZW50PjtcclxuICBAVmlld0NoaWxkKCdmaWxlSW5wdXQnKSBmaWxlSW5wdXRSZWYhOiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xyXG5cclxuICBASW5wdXQoKSBtYXhGaWxlU2l6ZT86IG51bWJlcjtcclxuICBAT3V0cHV0KCkgcGhvdG9DYXB0dXJlZCA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZVtdPigpO1xyXG5cclxuICBjYW1lcmFBY3RpdmUgPSBmYWxzZTtcclxuICBpc0NhcHR1cmVkID0gZmFsc2U7XHJcblxyXG4gIHN0cmVhbT86IE1lZGlhU3RyZWFtO1xyXG5cclxuICBjb21wTGliOiBDb21wb25lbnRMaWJyYXJ5O1xyXG4gIGNvbXBvbmVudExpYnJhcnkgPSBDb21wb25lbnRMaWJyYXJ5O1xyXG5cclxuICB0b2dnbGVDYW1lcmFCdXR0b24hOiBVaUFjdGlvbkRlc2NyaXB0b3I7XHJcblxyXG4gIGNhcHR1cmVCdXR0b246IFVpQWN0aW9uRGVzY3JpcHRvciA9IHtcclxuICAgIHR5cGU6IFVpQWN0aW9uQnV0dG9uVHlwZS5SQUlTRUQsXHJcbiAgICB0aXRsZTogJ0vDqXAga8Opc3rDrXTDqXNlJyxcclxuICAgIGljb246ICdjYW1lcmEnLFxyXG4gICAgaWNvblBvc2l0aW9uOiBJY29uUG9zaXRpb24uUFJFLFxyXG4gICAgY29sb3I6ICdwcmltYXJ5JyxcclxuICB9O1xyXG5cclxuICBjb25zdHJ1Y3RvcihASW5qZWN0KENPTVBPTkVOVF9MSUJSQVJZKSBAT3B0aW9uYWwoKSBjb21wTGliPzogQ29tcG9uZW50TGlicmFyeSkge1xyXG4gICAgdGhpcy5jb21wTGliID0gY29tcExpYiA/PyBDb21wb25lbnRMaWJyYXJ5LlBSSU1FTkc7XHJcbiAgICB0aGlzLnVwZGF0ZVRvZ2dsZUJ1dHRvbigpO1xyXG4gIH1cclxuXHJcbiAgaXNNb2JpbGUoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gL2lQaG9uZXxpUGFkfGlQb2R8QW5kcm9pZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBzdGFydENhbWVyYSgpIHtcclxuICAgIHRoaXMuc3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoeyB2aWRlbzogdHJ1ZSB9KTtcclxuICAgIHRoaXMudmlkZW9SZWYubmF0aXZlRWxlbWVudC5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbTtcclxuICAgIHRoaXMudmlkZW9SZWYubmF0aXZlRWxlbWVudC5wbGF5KCk7XHJcbiAgICB0aGlzLmNhbWVyYUFjdGl2ZSA9IHRydWU7XHJcbiAgICB0aGlzLmlzQ2FwdHVyZWQgPSBmYWxzZTtcclxuICAgIHRoaXMudXBkYXRlVG9nZ2xlQnV0dG9uKCk7XHJcbiAgfVxyXG5cclxuICBzdG9wQ2FtZXJhKCkge1xyXG4gICAgdGhpcy5zdHJlYW0/LmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB0cmFjay5zdG9wKCkpO1xyXG4gICAgdGhpcy5zdHJlYW0gPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmNhbWVyYUFjdGl2ZSA9IGZhbHNlO1xyXG4gICAgdGhpcy51cGRhdGVUb2dnbGVCdXR0b24oKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNhcHR1cmVQaG90bygpIHtcclxuICAgIGNvbnN0IHZpZGVvID0gdGhpcy52aWRlb1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgIGlmICghY29udGV4dCkgcmV0dXJuO1xyXG5cclxuICAgIGNhbnZhcy53aWR0aCA9IHZpZGVvLnZpZGVvV2lkdGg7XHJcbiAgICBjYW52YXMuaGVpZ2h0ID0gdmlkZW8udmlkZW9IZWlnaHQ7XHJcbiAgICBjb250ZXh0LmRyYXdJbWFnZSh2aWRlbywgMCwgMCk7XHJcblxyXG4gICAgY29uc3QgYmxvYiA9IGF3YWl0IG5ldyBQcm9taXNlPEJsb2IgfCBudWxsPigocmVzb2x2ZSkgPT5cclxuICAgICAgY2FudmFzLnRvQmxvYihyZXNvbHZlLCAnaW1hZ2UvanBlZycsIDAuOSlcclxuICAgICk7XHJcbiAgICBpZiAoIWJsb2IpIHJldHVybjtcclxuXHJcbiAgICBsZXQgZmlsZSA9IG5ldyBGaWxlKFtibG9iXSwgYHBob3RvXyR7RGF0ZS5ub3coKX0uanBnYCwgeyB0eXBlOiAnaW1hZ2UvanBlZycgfSk7XHJcblxyXG4gICAgaWYgKHRoaXMubWF4RmlsZVNpemUgJiYgZmlsZS5zaXplID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xyXG4gICAgICBmaWxlID0gYXdhaXQgdGhpcy5jb21wcmVzc0ltYWdlRmlsZShmaWxlLCB0aGlzLm1heEZpbGVTaXplKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnBob3RvQ2FwdHVyZWQuZW1pdChbZmlsZV0pO1xyXG4gICAgdGhpcy5pc0NhcHR1cmVkID0gdHJ1ZTtcclxuICAgIHRoaXMuc3RvcENhbWVyYSgpO1xyXG4gIH1cclxuXHJcbiAgZ2V0UGhvdG9EYXRhVVJMKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudC50b0RhdGFVUkwoJ2ltYWdlL3BuZycpO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgb25GaWxlU2VsZWN0ZWQoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICBjb25zdCBpbnB1dCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG4gICAgaWYgKCFpbnB1dC5maWxlcyB8fCBpbnB1dC5maWxlcy5sZW5ndGggPT09IDApIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBtYXhTaXplID0gdGhpcy5tYXhGaWxlU2l6ZTtcclxuICAgIGNvbnN0IGZpbGVzQXJyYXkgPSBBcnJheS5mcm9tKGlucHV0LmZpbGVzKTtcclxuICAgIGNvbnN0IHByb2Nlc3NlZEZpbGVzOiBGaWxlW10gPSBbXTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXNBcnJheSkge1xyXG4gICAgICBpZiAobWF4U2l6ZSAmJiBmaWxlLnNpemUgPiBtYXhTaXplICYmIGZpbGUudHlwZS5zdGFydHNXaXRoKCdpbWFnZS8nKSkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBjb25zdCBjb21wcmVzc2VkID0gYXdhaXQgdGhpcy5jb21wcmVzc0ltYWdlRmlsZShmaWxlLCBtYXhTaXplKTtcclxuICAgICAgICAgIHByb2Nlc3NlZEZpbGVzLnB1c2goY29tcHJlc3NlZCk7XHJcbiAgICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgICBwcm9jZXNzZWRGaWxlcy5wdXNoKGZpbGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBwcm9jZXNzZWRGaWxlcy5wdXNoKGZpbGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5waG90b0NhcHR1cmVkLmVtaXQocHJvY2Vzc2VkRmlsZXMpO1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlQ2FtZXJhKCkge1xyXG4gICAgaWYgKHRoaXMuY2FtZXJhQWN0aXZlKSB7XHJcbiAgICAgIHRoaXMuc3RvcENhbWVyYSgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zdGFydENhbWVyYSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlVG9nZ2xlQnV0dG9uKCkge1xyXG4gICAgbGV0IGljb24gPSB0aGlzLmNvbXBMaWIgPT09IENvbXBvbmVudExpYnJhcnkuUFJJTUVORyA/ICdwb3dlci1vZmYnIDogJ3Bvd2VyX3NldHRpbmdzX25ldyc7XHJcbiAgICBsZXQgdGl0bGU7XHJcbiAgICBsZXQgY29sb3I7XHJcbiAgICBpZiAodGhpcy5jYW1lcmFBY3RpdmUpIHtcclxuICAgICAgdGl0bGUgPSAnS2FtZXJhIGtpa2FwY3NvbMOhc2EnO1xyXG4gICAgICBjb2xvciA9IHRoaXMuY29tcExpYiA9PT0gQ29tcG9uZW50TGlicmFyeS5QUklNRU5HID8gJ2RhbmdlcicgOiAncmVkJztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRpdGxlID0gJ0thbWVyYSBiZWthcGNzb2zDoXNhJztcclxuICAgICAgY29sb3IgPSAncHJpbWFyeSc7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy50b2dnbGVDYW1lcmFCdXR0b24gPSB7XHJcbiAgICAgIHR5cGU6IFVpQWN0aW9uQnV0dG9uVHlwZS5SQUlTRUQsXHJcbiAgICAgIHRpdGxlOiB0aXRsZSxcclxuICAgICAgaWNvbjogaWNvbixcclxuICAgICAgY29sb3IsXHJcbiAgICAgIGljb25Qb3NpdGlvbjogSWNvblBvc2l0aW9uLlBSRSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGNvbXByZXNzSW1hZ2VGaWxlKGZpbGU6IEZpbGUsIG1heEZpbGVTaXplOiBudW1iZXIpOiBQcm9taXNlPEZpbGU+IHtcclxuICAgIGlmICghZmlsZS50eXBlLnN0YXJ0c1dpdGgoJ2ltYWdlLycpKSByZXR1cm4gZmlsZTtcclxuXHJcbiAgICBjb25zdCBpbWcgPSBhd2FpdCBuZXcgUHJvbWlzZTxIVE1MSW1hZ2VFbGVtZW50PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XHJcbiAgICAgIGNvbnN0IGltYWdlID0gbmV3IEltYWdlKCk7XHJcbiAgICAgIGltYWdlLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XHJcbiAgICAgICAgcmVzb2x2ZShpbWFnZSk7XHJcbiAgICAgIH07XHJcbiAgICAgIGltYWdlLm9uZXJyb3IgPSAoZSkgPT4ge1xyXG4gICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcclxuICAgICAgICByZWplY3QoZSk7XHJcbiAgICAgIH07XHJcbiAgICAgIGltYWdlLnNyYyA9IHVybDtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xyXG4gICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XHJcbiAgICBpZiAoIWN0eCkgcmV0dXJuIGZpbGU7XHJcblxyXG4gICAgbGV0IHdpZHRoID0gaW1nLm5hdHVyYWxXaWR0aDtcclxuICAgIGxldCBoZWlnaHQgPSBpbWcubmF0dXJhbEhlaWdodDtcclxuICAgIGxldCBxdWFsaXR5ID0gMC45O1xyXG4gICAgY29uc3QgbWluUXVhbGl0eSA9IDAuNDtcclxuICAgIGNvbnN0IG1pbkRpbWVuc2lvbiA9IDY0MDtcclxuXHJcbiAgICBjb25zdCBnZXRCbG9iID0gKHE6IG51bWJlcik6IFByb21pc2U8QmxvYj4gPT5cclxuICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICBjYW52YXMud2lkdGggPSB3aWR0aDtcclxuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xyXG4gICAgICAgIGN0eC5jbGVhclJlY3QoMCwgMCwgd2lkdGgsIGhlaWdodCk7XHJcbiAgICAgICAgY3R4LmRyYXdJbWFnZShpbWcsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xyXG4gICAgICAgIGNhbnZhcy50b0Jsb2IoXHJcbiAgICAgICAgICAoYmxvYikgPT4ge1xyXG4gICAgICAgICAgICBpZiAoYmxvYikgcmVzb2x2ZShibG9iKTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICAnaW1hZ2UvanBlZycsXHJcbiAgICAgICAgICBxXHJcbiAgICAgICAgKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgbGV0IGJsb2IgPSBhd2FpdCBnZXRCbG9iKHF1YWxpdHkpO1xyXG5cclxuICAgIHdoaWxlIChibG9iLnNpemUgPiBtYXhGaWxlU2l6ZSkge1xyXG4gICAgICBpZiAocXVhbGl0eSA+IG1pblF1YWxpdHkpIHtcclxuICAgICAgICBxdWFsaXR5IC09IDAuMTtcclxuICAgICAgfSBlbHNlIGlmICh3aWR0aCA+IG1pbkRpbWVuc2lvbiAmJiBoZWlnaHQgPiBtaW5EaW1lbnNpb24pIHtcclxuICAgICAgICB3aWR0aCA9IE1hdGguZmxvb3Iod2lkdGggKiAwLjgpO1xyXG4gICAgICAgIGhlaWdodCA9IE1hdGguZmxvb3IoaGVpZ2h0ICogMC44KTtcclxuICAgICAgICBxdWFsaXR5ID0gMC45O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgIGJsb2IgPSBhd2FpdCBnZXRCbG9iKHF1YWxpdHkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChibG9iLnNpemUgPD0gbWF4RmlsZVNpemUpIHtcclxuICAgICAgcmV0dXJuIG5ldyBGaWxlKFtibG9iXSwgZmlsZS5uYW1lLCB7IHR5cGU6ICdpbWFnZS9qcGVnJyB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBmaWxlO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwicGhvdG9XaWRnZXRDb250YWluZXJcIj5cclxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzTW9iaWxlKClcIj5cclxuICAgIDx2aWRlbyAjdmlkZW8gYXV0b3BsYXkgW2hpZGRlbl09XCJpc0NhcHR1cmVkIHx8ICFjYW1lcmFBY3RpdmVcIj48L3ZpZGVvPlxyXG4gICAgPGNhbnZhcyAjY2FudmFzIFtoaWRkZW5dPVwiIWlzQ2FwdHVyZWQgfHwgY2FtZXJhQWN0aXZlXCI+PC9jYW52YXM+XHJcblxyXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFjYW1lcmFBY3RpdmUgJiYgIWlzQ2FwdHVyZWRcIj5cclxuICAgICAgPHAgY2xhc3M9XCJtZXNzYWdlXCI+S2FwY3NvbGphIGJlIGEga2FtZXLDoXQgYSBrw6lwIGvDqXN6w610w6lzw6loZXohPC9wPlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImNvbnRyb2xzXCI+XHJcbiAgICAgIDwhLS0gU1RBUlQgQ0FNRVJBIC0tPlxyXG4gICAgICA8dWktYWN0aW9uLWJ1dHRvbiBbZGVzY3JpcHRvcl09XCJ0b2dnbGVDYW1lcmFCdXR0b25cIiAoYWN0aW9uQ2xpY2spPVwidG9nZ2xlQ2FtZXJhKClcIj5cclxuICAgICAgPC91aS1hY3Rpb24tYnV0dG9uPlxyXG5cclxuICAgICAgPCEtLSBDQVBUVVJFIENBTUVSQSAtLT5cclxuICAgICAgPHVpLWFjdGlvbi1idXR0b25cclxuICAgICAgICBbZGlzYWJsZWRdPVwiIWNhbWVyYUFjdGl2ZVwiXHJcbiAgICAgICAgW2Rlc2NyaXB0b3JdPVwiY2FwdHVyZUJ1dHRvblwiXHJcbiAgICAgICAgKGFjdGlvbkNsaWNrKT1cImNhcHR1cmVQaG90bygpXCJcclxuICAgICAgPlxyXG4gICAgICA8L3VpLWFjdGlvbi1idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzTW9iaWxlKClcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJjb250cm9sc1wiPlxyXG4gICAgICA8aW5wdXRcclxuICAgICAgICAjZmlsZUlucHV0XHJcbiAgICAgICAgdHlwZT1cImZpbGVcIlxyXG4gICAgICAgIGFjY2VwdD1cImltYWdlLypcIlxyXG4gICAgICAgIGNhcHR1cmU9XCJlbnZpcm9ubWVudFwiXHJcbiAgICAgICAgKGNoYW5nZSk9XCJvbkZpbGVTZWxlY3RlZCgkZXZlbnQpXCJcclxuICAgICAgICBzdHlsZT1cImRpc3BsYXk6IG5vbmVcIlxyXG4gICAgICAvPlxyXG5cclxuICAgICAgPHVpLWFjdGlvbi1idXR0b24gW2Rlc2NyaXB0b3JdPVwiY2FwdHVyZUJ1dHRvblwiIChhY3Rpb25DbGljayk9XCJmaWxlSW5wdXQuY2xpY2soKVwiPlxyXG4gICAgICA8L3VpLWFjdGlvbi1idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICA8L25nLWNvbnRhaW5lcj5cclxuPC9kaXY+XHJcbiJdfQ==
|