@croeminc/croem-card-widget 0.6.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Constants.d.ts +8 -0
- package/README.md +125 -0
- package/esm2020/Constants.mjs +9 -0
- package/esm2020/croeminc-croem-card-widget.mjs +5 -0
- package/esm2020/lib/card-widget/Add-card-widget/add-card-widget/add-card-widget.component.mjs +195 -0
- package/esm2020/lib/card-widget/Pay-card-widget/payment-card-widget/payment-card-widget.component.mjs +149 -0
- package/esm2020/lib/card-widget/Update-card-widget/update-card-widget/update-card-widget.component.mjs +267 -0
- package/esm2020/lib/croem-card-widget.component.mjs +77 -0
- package/esm2020/lib/croem-card-widget.module.mjs +48 -0
- package/esm2020/lib/croem-card-widget.service.mjs +62 -0
- package/esm2020/lib/dynamic-form-builder/dynamic-form-fields/dropdown.mjs +32 -0
- package/esm2020/lib/dynamic-form-builder/dynamic-form-fields/textbox.mjs +21 -0
- package/esm2020/lib/dynamic-form-builder/field-builder.component.mjs +24 -0
- package/esm2020/lib/dynamic-form-builder/interfaces/CardModeEnum.mjs +7 -0
- package/esm2020/lib/dynamic-form-builder/interfaces/FormFields.Interface.mjs +2 -0
- package/esm2020/lib/dynamic-form-builder/interfaces/InputParams.Interface.mjs +2 -0
- package/esm2020/lib/dynamic-form-builder/interfaces/apiResponse.Interface.mjs +2 -0
- package/esm2020/lib/localizations/en.mjs +16 -0
- package/esm2020/lib/localizations/es.mjs +16 -0
- package/esm2020/lib/localizations/language.interface.mjs +2 -0
- package/esm2020/public-api.mjs +11 -0
- package/fesm2015/croeminc-croem-card-widget.mjs +876 -0
- package/fesm2015/croeminc-croem-card-widget.mjs.map +1 -0
- package/fesm2020/croeminc-croem-card-widget.mjs +868 -0
- package/fesm2020/croeminc-croem-card-widget.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/card-widget/Add-card-widget/add-card-widget/add-card-widget.component.d.ts +61 -0
- package/lib/card-widget/Pay-card-widget/payment-card-widget/payment-card-widget.component.d.ts +43 -0
- package/lib/card-widget/Update-card-widget/update-card-widget/update-card-widget.component.d.ts +64 -0
- package/lib/croem-card-widget.component.d.ts +49 -0
- package/lib/croem-card-widget.module.d.ts +16 -0
- package/lib/croem-card-widget.service.d.ts +11 -0
- package/lib/dynamic-form-builder/dynamic-form-fields/dropdown.d.ts +19 -0
- package/lib/dynamic-form-builder/dynamic-form-fields/textbox.d.ts +12 -0
- package/lib/dynamic-form-builder/field-builder.component.d.ts +14 -0
- package/lib/dynamic-form-builder/interfaces/CardModeEnum.d.ts +5 -0
- package/lib/dynamic-form-builder/interfaces/FormFields.Interface.d.ts +14 -0
- package/lib/dynamic-form-builder/interfaces/InputParams.Interface.d.ts +17 -0
- package/lib/dynamic-form-builder/interfaces/apiResponse.Interface.d.ts +24 -0
- package/lib/localizations/en.d.ts +2 -0
- package/lib/localizations/es.d.ts +2 -0
- package/lib/localizations/language.interface.d.ts +15 -0
- package/package.json +48 -0
- package/public-api.d.ts +7 -0
package/Constants.d.ts
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# @croem/croem-card-widget
|
|
2
|
+
|
|
3
|
+
An Angular UI library designed to provide a secure, validation-compliant, and responsive card payment interface. It facilitates card tokenization, card detail management, and transaction execution.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Robust Card Validation**: Uses advanced validation rules for card numbers, expiration dates, and CVVs.
|
|
10
|
+
- **AMP Theme Compliant**: Clean, modern, responsive styling designed to integrate with the AMP ecosystem.
|
|
11
|
+
- **Multiple Integration Modes**:
|
|
12
|
+
- **Add Card Widget**: Collect card details securely to generate tokenized credentials.
|
|
13
|
+
- **Update Card Widget**: Manage and update existing tokenized cards.
|
|
14
|
+
- **Payment Widget**: Execute sales or pre-authorization transactions directly using card tokens.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Install the package via npm:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @croem/croem-card-widget
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Dependencies
|
|
27
|
+
|
|
28
|
+
Ensure your project has the required peer dependencies installed:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install card-validator
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Setup & Usage
|
|
37
|
+
|
|
38
|
+
### 1. Import the Module
|
|
39
|
+
|
|
40
|
+
Import `CroemCardWidgetModule` into your Angular application module:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { NgModule } from '@angular/core';
|
|
44
|
+
import { CroemCardWidgetModule } from '@croem/croem-card-widget';
|
|
45
|
+
|
|
46
|
+
@NgModule({
|
|
47
|
+
imports: [
|
|
48
|
+
CroemCardWidgetModule
|
|
49
|
+
]
|
|
50
|
+
})
|
|
51
|
+
export class AppModule { }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Available Components
|
|
55
|
+
|
|
56
|
+
The library provides three main components for different stages of the payment lifecycle:
|
|
57
|
+
|
|
58
|
+
#### A. Add Card Component (`croem-add-card-widget`)
|
|
59
|
+
Used for collecting new card details and generating a secure payment token.
|
|
60
|
+
|
|
61
|
+
**HTML Template:**
|
|
62
|
+
```html
|
|
63
|
+
<croem-add-card-widget
|
|
64
|
+
[inputParamsForWidget]="inputParams"
|
|
65
|
+
(fieldResponseEmitter)="onFormFieldsReceived($event)"
|
|
66
|
+
(widgetResponseEmitter)="onApiResponse($event)"
|
|
67
|
+
(HandleError)="onError($event)">
|
|
68
|
+
</croem-add-card-widget>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### B. Update Card Component (`croem-update-card-widget`)
|
|
72
|
+
Used for editing details of an already registered card token.
|
|
73
|
+
|
|
74
|
+
**HTML Template:**
|
|
75
|
+
```html
|
|
76
|
+
<croem-update-card-widget
|
|
77
|
+
[inputParamsForWidgetForUpdate]="inputParams"
|
|
78
|
+
(fieldResponseEmitter)="onFormFieldsReceived($event)"
|
|
79
|
+
(widgetResponseEmitter)="onApiResponse($event)"
|
|
80
|
+
(HandleError)="onError($event)">
|
|
81
|
+
</croem-update-card-widget>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### C. Payment Card Component (`croem-payment-card-widget`)
|
|
85
|
+
Used for processing transactions directly using a card token.
|
|
86
|
+
|
|
87
|
+
**HTML Template:**
|
|
88
|
+
```html
|
|
89
|
+
<croem-payment-card-widget
|
|
90
|
+
[inputParamsForWidgetForPayment]="inputParams"
|
|
91
|
+
(fieldResponseEmitter)="onFormFieldsReceived($event)"
|
|
92
|
+
(widgetResponseEmitter)="onApiResponse($event)"
|
|
93
|
+
(HandleError)="onError($event)">
|
|
94
|
+
</croem-payment-card-widget>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Configuration API
|
|
100
|
+
|
|
101
|
+
All widgets accept configuration parameters through their respective input bindings.
|
|
102
|
+
|
|
103
|
+
### Input Parameters (`InputParamsForWidget`)
|
|
104
|
+
|
|
105
|
+
| Parameter | Type | Required | Description |
|
|
106
|
+
| :--- | :--- | :--- | :--- |
|
|
107
|
+
| `APIKey` | `string` | Yes | The merchant API key. |
|
|
108
|
+
| `Token` | `string` | No | Card account token (required for Update & Payment modes). |
|
|
109
|
+
| `Culture` | `string` | No | Language locale code (e.g. `'en'`, `'es'`). Defaults to `'en'`. |
|
|
110
|
+
| `IsSale` | `boolean` | No | Set to `true` for sale/charge transactions; `false` for authorizations. |
|
|
111
|
+
| `DtrUrl` | `string` | Yes | The Gateway DTR service endpoint URL. |
|
|
112
|
+
| `Keys` | `object` | Yes | DSA Encryption Keys (`EncKey1` and `EncKey2`). |
|
|
113
|
+
| `Mode` | `CardMode` | Yes | Component interaction mode (`CardMode.Add`, `CardMode.Edit`, `CardMode.Show`). |
|
|
114
|
+
|
|
115
|
+
### Event Emitters
|
|
116
|
+
|
|
117
|
+
- **`fieldResponseEmitter`**: Fires when form validation status or input controls change.
|
|
118
|
+
- **`widgetResponseEmitter`**: Fires on successful communication with the gateway API, returning the response payload.
|
|
119
|
+
- **`HandleError`**: Fires when an error occurs during token validation or transaction processing.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const constants = {
|
|
2
|
+
urls: {
|
|
3
|
+
updateDTRUrl: "api/UIComponentApi/UpdateCreditCard",
|
|
4
|
+
addDTRUrl: "api/UIComponentApi/CreateCreditCard",
|
|
5
|
+
paymentDTRUrl: "api/UIComponentApi/PerformTransaction",
|
|
6
|
+
getCardInfoByToken: "api/UIComponentApi/GetCreditCard"
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvY3JvZW0tY2FyZC13aWRnZXQvc3JjL0NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUc7SUFDckIsSUFBSSxFQUFFO1FBQ0YsWUFBWSxFQUFFLHFDQUFxQztRQUNuRCxTQUFTLEVBQUUscUNBQXFDO1FBQ2hELGFBQWEsRUFBRSx1Q0FBdUM7UUFDdEQsa0JBQWtCLEVBQUUsa0NBQWtDO0tBQ3pEO0NBQ0osQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCBjb25zdGFudHMgPSB7XHJcbiAgICB1cmxzOiB7XHJcbiAgICAgICAgdXBkYXRlRFRSVXJsOiBcImFwaS9VSUNvbXBvbmVudEFwaS9VcGRhdGVDcmVkaXRDYXJkXCIsXHJcbiAgICAgICAgYWRkRFRSVXJsOiBcImFwaS9VSUNvbXBvbmVudEFwaS9DcmVhdGVDcmVkaXRDYXJkXCIsXHJcbiAgICAgICAgcGF5bWVudERUUlVybDogXCJhcGkvVUlDb21wb25lbnRBcGkvUGVyZm9ybVRyYW5zYWN0aW9uXCIsXHJcbiAgICAgICAgZ2V0Q2FyZEluZm9CeVRva2VuOiBcImFwaS9VSUNvbXBvbmVudEFwaS9HZXRDcmVkaXRDYXJkXCJcclxuICAgIH1cclxufVxyXG4iXX0=
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './public-api';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JvZW1pbmMtY3JvZW0tY2FyZC13aWRnZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9jcm9lbS1jYXJkLXdpZGdldC9zcmMvY3JvZW1pbmMtY3JvZW0tY2FyZC13aWRnZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { FormGroup, Validators, FormControl } from '@angular/forms';
|
|
3
|
+
import * as cardValidator from "card-validator";
|
|
4
|
+
import { LANG_EN } from '../../../localizations/en';
|
|
5
|
+
import { LANG_ES } from '../../../localizations/es';
|
|
6
|
+
import { constants } from '../../../../Constants';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@angular/forms";
|
|
9
|
+
import * as i2 from "../../../croem-card-widget.service";
|
|
10
|
+
import * as i3 from "@angular/common";
|
|
11
|
+
import * as i4 from "../../../dynamic-form-builder/field-builder.component";
|
|
12
|
+
export class AddCardWidgetComponent {
|
|
13
|
+
constructor(formBuilder, croemCardService) {
|
|
14
|
+
this.formBuilder = formBuilder;
|
|
15
|
+
this.croemCardService = croemCardService;
|
|
16
|
+
this.widgetResponseEmitter = new EventEmitter();
|
|
17
|
+
this.fieldResponseEmitter = new EventEmitter();
|
|
18
|
+
this.loader = new EventEmitter();
|
|
19
|
+
this.fields = [];
|
|
20
|
+
this.dynamicFields = {};
|
|
21
|
+
this.showLoader = false;
|
|
22
|
+
this.showInputErrorNumber = true;
|
|
23
|
+
this.showInputErrorDate = true;
|
|
24
|
+
this.showInputErrorName = true;
|
|
25
|
+
this.maxLength = 19;
|
|
26
|
+
this.maxExpYear = 28;
|
|
27
|
+
}
|
|
28
|
+
ngOnInit() {
|
|
29
|
+
this.switchLanguage(this.inputParamsForWidgetForAdd.Culture);
|
|
30
|
+
//---Dynamic Form creation innitializing form group(i.e cardForm) to pass onto the dynamic form builder component ------
|
|
31
|
+
for (const field of this.fields) {
|
|
32
|
+
const validators = [];
|
|
33
|
+
if (field.required) {
|
|
34
|
+
validators.push(Validators.required);
|
|
35
|
+
}
|
|
36
|
+
this.dynamicFields[field.name] = [field.value || null, validators];
|
|
37
|
+
}
|
|
38
|
+
const predefinedControls = {
|
|
39
|
+
name: ['', [Validators.required]],
|
|
40
|
+
cardNumber: ['', [Validators.required, Validators.minLength(10), Validators.maxLength(19)]],
|
|
41
|
+
validityDate: ['', [Validators.required, Validators.minLength(5)]],
|
|
42
|
+
};
|
|
43
|
+
this.cardForm = this.formBuilder.group({
|
|
44
|
+
...predefinedControls,
|
|
45
|
+
...this.dynamicFields
|
|
46
|
+
});
|
|
47
|
+
let fieldsContrls = {};
|
|
48
|
+
for (let f of this.fields) {
|
|
49
|
+
if (f.type !== 'checkbox') {
|
|
50
|
+
fieldsContrls[f.name] = new FormControl(f.value || '', Validators.required);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
let opts = {};
|
|
54
|
+
if (f.options) {
|
|
55
|
+
for (let opt of f.options) {
|
|
56
|
+
opts[opt.key] = new FormControl(opt.label);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
fieldsContrls[f.name] = new FormGroup(opts);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//---localization To add a new property to this go localization dir and add your property insdei en.ts and es.ts ------
|
|
64
|
+
switchLanguage(language) {
|
|
65
|
+
if (language === 'en') {
|
|
66
|
+
this.currentLang = LANG_EN;
|
|
67
|
+
}
|
|
68
|
+
else if (language === 'es') {
|
|
69
|
+
this.currentLang = LANG_ES;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
createCard() {
|
|
73
|
+
this.addCard();
|
|
74
|
+
}
|
|
75
|
+
async addCard() {
|
|
76
|
+
try {
|
|
77
|
+
this.showLoader = true;
|
|
78
|
+
this.loader.emit(this.showLoader);
|
|
79
|
+
const apiUrl = this.inputParamsForWidgetForAdd.DtrUrl + constants.urls.addDTRUrl;
|
|
80
|
+
//----encryption-------
|
|
81
|
+
var encode = this.encoding(); //--encoding parameters
|
|
82
|
+
this.encryptedString = this.innitializeKey(encode); //--innitializing DSA key
|
|
83
|
+
this.addCardResponse = await this.croemCardService.addUpdateCardAPICall(apiUrl, this.encryptedString); //--API Call to add card in DTR
|
|
84
|
+
this.showLoader = false;
|
|
85
|
+
this.fieldResponseEmitter.emit(this.cardForm.controls);
|
|
86
|
+
this.widgetResponseEmitter.emit(this.addCardResponse);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.log(error);
|
|
90
|
+
this.showLoader = false;
|
|
91
|
+
this.widgetResponseEmitter.emit(this.addCardResponse);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
encoding() {
|
|
95
|
+
return this.cardForm.value.cardNumber + "\\" +
|
|
96
|
+
this.cardForm.value.name + "\\" +
|
|
97
|
+
this.cardForm.value.validityDate.substring(0, 2) + "\\" +
|
|
98
|
+
this.cardForm.value.validityDate.substring(3) + "\\" +
|
|
99
|
+
"" + "\\" +
|
|
100
|
+
"" + "\\" +
|
|
101
|
+
this.inputParamsForWidgetForAdd.APIKey + "\\" +
|
|
102
|
+
this.inputParamsForWidgetForAdd.Culture + "\\" +
|
|
103
|
+
"" + "\\" +
|
|
104
|
+
(this.inputParamsForWidgetForAdd.IsSale ?? false) + "\\" +
|
|
105
|
+
(this.inputParamsForWidgetForAdd.Amount ?? "0") + "\\" +
|
|
106
|
+
(this.inputParamsForWidgetForAdd.ProductDetails ?? "0") + "\\" +
|
|
107
|
+
"" + "\\" +
|
|
108
|
+
"" + "\\" +
|
|
109
|
+
(this.inputParamsForWidgetForAdd.Itbms ?? "0") + "\\" +
|
|
110
|
+
this.inputParamsForWidgetForAdd.Mode;
|
|
111
|
+
}
|
|
112
|
+
innitializeKey(encode) {
|
|
113
|
+
var key = initializeKey(this.inputParamsForWidgetForAdd.Keys.EncKey1, this.inputParamsForWidgetForAdd.Keys.EncKey2);
|
|
114
|
+
return encryptedString(key, encode);
|
|
115
|
+
}
|
|
116
|
+
formatDate(event) {
|
|
117
|
+
let input = event.target.value;
|
|
118
|
+
input = input.replace(/\D/g, '');
|
|
119
|
+
const month = this.formatMonth(input.substring(0, 2));
|
|
120
|
+
const year = input.substring(2, 4);
|
|
121
|
+
const formattedDate = month + (year ? '/' + year : '');
|
|
122
|
+
event.target.value = formattedDate;
|
|
123
|
+
this.cardForm.controls['validityDate'].setValue(formattedDate);
|
|
124
|
+
this.validityDate = this.cardForm.controls['validityDate'].value;
|
|
125
|
+
this.validateDate();
|
|
126
|
+
}
|
|
127
|
+
formatMonth(month) {
|
|
128
|
+
const validMonth = parseInt(month, 10);
|
|
129
|
+
return (validMonth > 1 && validMonth <= 9) ? '0' + validMonth : month;
|
|
130
|
+
}
|
|
131
|
+
maskCardNumber() {
|
|
132
|
+
if (this.cardNumber && this.cardNumber.length > 0) {
|
|
133
|
+
const maskedNumber = '•'.repeat(Math.max(0, this.cardNumber.length - 4)) + this.cardNumber.slice(-4);
|
|
134
|
+
return maskedNumber.replace(/(•{4})/g, '$1 ');
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
return '•••• •••• •••• ••••';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
maskName() {
|
|
141
|
+
return this.name ? this.name : 'Your Name';
|
|
142
|
+
}
|
|
143
|
+
maskDate() {
|
|
144
|
+
return this.validityDate ? this.validityDate : '••/••';
|
|
145
|
+
}
|
|
146
|
+
validateDate() {
|
|
147
|
+
if (!this.inputParamsForWidgetForAdd.IsSale) {
|
|
148
|
+
this.showInputErrorDate = cardValidator.expirationDate(this.validityDate, this.maxExpYear).isValid;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.showInputErrorDate = true;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
validateNumber() {
|
|
155
|
+
const valid = cardValidator.number(this.cardNumber).isValid;
|
|
156
|
+
this.showInputErrorNumber = valid;
|
|
157
|
+
}
|
|
158
|
+
bindNumber(event) {
|
|
159
|
+
this.cardNumber = event.target.value;
|
|
160
|
+
this.validateNumber();
|
|
161
|
+
}
|
|
162
|
+
bindName(event) {
|
|
163
|
+
this.name = event.target.value;
|
|
164
|
+
this.validateName();
|
|
165
|
+
}
|
|
166
|
+
restControl(controlname) {
|
|
167
|
+
const control = this.cardForm.get(controlname);
|
|
168
|
+
control.reset();
|
|
169
|
+
}
|
|
170
|
+
validateName() {
|
|
171
|
+
if (this.name.length > 4) {
|
|
172
|
+
this.showInputErrorName = true;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
this.showInputErrorName = false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
AddCardWidgetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AddCardWidgetComponent, deps: [{ token: i1.FormBuilder }, { token: i2.CroemCardWidgetService }], target: i0.ɵɵFactoryTarget.Component });
|
|
180
|
+
AddCardWidgetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AddCardWidgetComponent, selector: "lib-add-card-widget", inputs: { inputParamsForWidgetForAdd: "inputParamsForWidgetForAdd", fields: "fields" }, outputs: { widgetResponseEmitter: "widgetResponseEmitter", fieldResponseEmitter: "fieldResponseEmitter", loader: "loader" }, ngImport: i0, template: "<form class=\"container-fluid py-3\" [formGroup]=\"cardForm\" *ngIf=\"(inputParamsForWidgetForAdd.APIKey)\">\r\n <div class=\"p-0\">\r\n <div class=\"d-flex justify-content-center mb-4\">\r\n <div class=\"card\">\r\n <div class=\"card-inner\">\r\n <div class=\"front\">\r\n <!-- Top Bar: Chip & Brand Logo -->\r\n <div class=\"card-top-bar\">\r\n <div class=\"chip\"></div>\r\n <div class=\"card-brand\">\r\n <span class=\"brand-text\">SECURE CARD</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Middle Bar: Card Number -->\r\n <div class=\"card-number-display\">\r\n <span>{{maskCardNumber()}}</span>\r\n </div>\r\n\r\n <!-- Bottom Bar: Cardholder Name & Expiration Date -->\r\n <div class=\"card-bottom-bar\">\r\n <div class=\"card-holder-info\">\r\n <label class=\"card-label\">CARDHOLDER</label>\r\n <span class=\"card-value\">{{maskName()}}</span>\r\n </div>\r\n <div class=\"card-expiry-info\">\r\n <label class=\"card-label\">{{currentLang[\"ValidThru\"]}}</label>\r\n <span class=\"card-value\">{{maskDate()}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Dynamic Form Fields -->\r\n <div class=\"dynamic-fields-container mb-3\">\r\n <div *ngFor=\"let field of fields\" class=\"mb-3\">\r\n <field-builder [field]=\"field\" [form]=\"cardForm\"></field-builder>\r\n </div>\r\n </div>\r\n\r\n <!-- Static Form Fields -->\r\n <div class=\"card-form-fields\">\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12\">\r\n <div class=\"form-group-custom\">\r\n <label for=\"card-number\" class=\"form-label-custom\">\r\n {{currentLang[\"CardNumber\"]}} <span class=\"text-danger\">*</span>\r\n </label>\r\n <div class=\"input-wrapper\">\r\n <input class=\"form-control-custom\" type=\"text\" id=\"card-number\"\r\n [class.inputError]=\"!showInputErrorNumber\" [placeholder]=\"currentLang['CardNumber']\"\r\n formControlName=\"cardNumber\" (input)=\"bindNumber($event)\" [maxlength]=\"maxLength\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12\">\r\n <div class=\"form-group-custom\">\r\n <label for=\"name\" class=\"form-label-custom\">\r\n {{currentLang[\"CardHolderName\"]}} <span class=\"text-danger\">*</span>\r\n </label>\r\n <div class=\"input-wrapper\">\r\n <input class=\"form-control-custom\" type=\"text\" id=\"name\"\r\n [placeholder]=\"currentLang['CardHolderName']\" [class.inputError]=\"!showInputErrorName\"\r\n (input)=\"bindName($event)\" formControlName=\"name\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-4\">\r\n <div class=\"col-6\">\r\n <div class=\"form-group-custom\">\r\n <label for=\"validity-date\" class=\"form-label-custom\">\r\n {{currentLang[\"ExpiryDate\"]}} <span class=\"text-danger\">*</span>\r\n </label>\r\n <div class=\"input-wrapper date-wrapper\">\r\n <input class=\"form-control-custom\" type=\"text\" id=\"validity-date\"\r\n [class.inputError]=\"!showInputErrorDate\" placeholder=\"MM/YY\"\r\n formControlName=\"validityDate\" (input)=\"formatDate($event)\" />\r\n <span class=\"calendar-icon\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-actions-custom\">\r\n <button class=\"btn-submit\" type=\"submit\" [disabled]=\"!cardForm.valid\" (click)=\"createCard()\">\r\n <span class=\"btn-text\">{{currentLang[\"lblSave\"]}}</span>\r\n </button>\r\n </div>\r\n</form>", styles: [".card{width:100%;max-width:400px;height:230px;color:#fff;perspective:1000px;border:none;background:transparent;margin:0 auto}.card-inner{width:100%;height:100%;position:relative;transition:transform .8s cubic-bezier(.175,.885,.32,1.275);transform-style:preserve-3d}.front{width:100%;height:100%;position:absolute;top:0;left:0;padding:24px 28px;border-radius:20px;overflow:hidden;z-index:1;backface-visibility:hidden;background:linear-gradient(135deg,rgba(17,24,39,.95) 0%,rgba(31,41,55,.95) 100%);box-shadow:0 20px 35px #00000040,inset 0 1px #ffffff26;border:1px solid rgba(255,255,255,.1);display:flex;flex-direction:column;justify-content:space-between;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;transition:all .3s ease}.front:before{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:radial-gradient(circle,rgba(99,102,241,.12) 0%,transparent 70%);pointer-events:none}.card-top-bar{display:flex;justify-content:space-between;align-items:center}.chip{width:48px;height:35px;background:linear-gradient(135deg,#f59e0b 0%,#d97706 100%);border-radius:6px;position:relative;box-shadow:inset 0 1px 2px #ffffff4d}.chip:before{content:\"\";position:absolute;inset:0;border:1px solid rgba(0,0,0,.15);border-radius:6px;background-image:linear-gradient(90deg,transparent 50%,rgba(0,0,0,.1) 50%),linear-gradient(0deg,transparent 50%,rgba(0,0,0,.1) 50%);background-size:10px 10px}.brand-text{font-size:10px;letter-spacing:2px;color:#ffffffb3;font-weight:700;text-shadow:0 2px 4px rgba(0,0,0,.2)}.card-number-display{font-family:Courier New,Courier,monospace;font-size:20px;letter-spacing:3px;color:#fff;text-shadow:0 2px 4px rgba(0,0,0,.3);margin:18px 0;text-align:center;-webkit-user-select:none;user-select:none}.card-bottom-bar{display:flex;justify-content:space-between;align-items:flex-end}.card-label{display:block;font-size:8px;color:#fff6;letter-spacing:1.5px;margin-bottom:2px;text-transform:uppercase}.card-value{display:block;font-size:13px;color:#fff;letter-spacing:.5px;font-weight:600;max-width:230px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-group-custom{display:flex;flex-direction:column;margin-bottom:12px}.form-label-custom{font-size:13px;font-weight:600;color:#374151;margin-bottom:6px;letter-spacing:.2px}.input-wrapper{position:relative;width:100%}.form-control-custom{width:100%;background-color:#f9fafb;border:1px solid #d1d5db;border-radius:8px;padding:10px 14px;font-size:14px;color:#1f2937;transition:all .2s ease-in-out;box-shadow:inset 0 1px 2px #00000005}.form-control-custom:focus{background-color:#fff;border-color:#4f46e5;box-shadow:0 0 0 3px #4f46e51f;outline:none}.inputError,.inputError:focus{border-color:#ef4444!important;box-shadow:0 0 0 3px #ef44441f!important}.date-wrapper{display:flex;align-items:center}.calendar-icon{width:18px;height:18px;position:absolute;right:12px;pointer-events:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%239ca3af'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-size:contain}.form-actions-custom{display:flex;justify-content:flex-end;margin-top:20px;border-top:1px solid #f3f4f6;padding-top:16px}.btn-submit{color:#fff;background-color:#5a75b6;border:solid 2px #5A75B6;border-radius:8px;padding:8px;min-width:120px;margin-right:10px}.btn-submit:hover{background-color:#3e578e;color:#fff}.btn-submit:disabled,.btn-previous:disabled,.btn-next:disabled{background-color:#ecebeb!important;border:solid 2px #ecebeb!important;color:#9c9c9c!important;cursor:not-allowed}.breathing-overlay{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0f172a99;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:9999}.show{display:block}\n"], dependencies: [{ kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.FieldBuilderComponent, selector: "field-builder", inputs: ["field", "form"] }] });
|
|
181
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AddCardWidgetComponent, decorators: [{
|
|
182
|
+
type: Component,
|
|
183
|
+
args: [{ selector: 'lib-add-card-widget', template: "<form class=\"container-fluid py-3\" [formGroup]=\"cardForm\" *ngIf=\"(inputParamsForWidgetForAdd.APIKey)\">\r\n <div class=\"p-0\">\r\n <div class=\"d-flex justify-content-center mb-4\">\r\n <div class=\"card\">\r\n <div class=\"card-inner\">\r\n <div class=\"front\">\r\n <!-- Top Bar: Chip & Brand Logo -->\r\n <div class=\"card-top-bar\">\r\n <div class=\"chip\"></div>\r\n <div class=\"card-brand\">\r\n <span class=\"brand-text\">SECURE CARD</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Middle Bar: Card Number -->\r\n <div class=\"card-number-display\">\r\n <span>{{maskCardNumber()}}</span>\r\n </div>\r\n\r\n <!-- Bottom Bar: Cardholder Name & Expiration Date -->\r\n <div class=\"card-bottom-bar\">\r\n <div class=\"card-holder-info\">\r\n <label class=\"card-label\">CARDHOLDER</label>\r\n <span class=\"card-value\">{{maskName()}}</span>\r\n </div>\r\n <div class=\"card-expiry-info\">\r\n <label class=\"card-label\">{{currentLang[\"ValidThru\"]}}</label>\r\n <span class=\"card-value\">{{maskDate()}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Dynamic Form Fields -->\r\n <div class=\"dynamic-fields-container mb-3\">\r\n <div *ngFor=\"let field of fields\" class=\"mb-3\">\r\n <field-builder [field]=\"field\" [form]=\"cardForm\"></field-builder>\r\n </div>\r\n </div>\r\n\r\n <!-- Static Form Fields -->\r\n <div class=\"card-form-fields\">\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12\">\r\n <div class=\"form-group-custom\">\r\n <label for=\"card-number\" class=\"form-label-custom\">\r\n {{currentLang[\"CardNumber\"]}} <span class=\"text-danger\">*</span>\r\n </label>\r\n <div class=\"input-wrapper\">\r\n <input class=\"form-control-custom\" type=\"text\" id=\"card-number\"\r\n [class.inputError]=\"!showInputErrorNumber\" [placeholder]=\"currentLang['CardNumber']\"\r\n formControlName=\"cardNumber\" (input)=\"bindNumber($event)\" [maxlength]=\"maxLength\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12\">\r\n <div class=\"form-group-custom\">\r\n <label for=\"name\" class=\"form-label-custom\">\r\n {{currentLang[\"CardHolderName\"]}} <span class=\"text-danger\">*</span>\r\n </label>\r\n <div class=\"input-wrapper\">\r\n <input class=\"form-control-custom\" type=\"text\" id=\"name\"\r\n [placeholder]=\"currentLang['CardHolderName']\" [class.inputError]=\"!showInputErrorName\"\r\n (input)=\"bindName($event)\" formControlName=\"name\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-4\">\r\n <div class=\"col-6\">\r\n <div class=\"form-group-custom\">\r\n <label for=\"validity-date\" class=\"form-label-custom\">\r\n {{currentLang[\"ExpiryDate\"]}} <span class=\"text-danger\">*</span>\r\n </label>\r\n <div class=\"input-wrapper date-wrapper\">\r\n <input class=\"form-control-custom\" type=\"text\" id=\"validity-date\"\r\n [class.inputError]=\"!showInputErrorDate\" placeholder=\"MM/YY\"\r\n formControlName=\"validityDate\" (input)=\"formatDate($event)\" />\r\n <span class=\"calendar-icon\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-actions-custom\">\r\n <button class=\"btn-submit\" type=\"submit\" [disabled]=\"!cardForm.valid\" (click)=\"createCard()\">\r\n <span class=\"btn-text\">{{currentLang[\"lblSave\"]}}</span>\r\n </button>\r\n </div>\r\n</form>", styles: [".card{width:100%;max-width:400px;height:230px;color:#fff;perspective:1000px;border:none;background:transparent;margin:0 auto}.card-inner{width:100%;height:100%;position:relative;transition:transform .8s cubic-bezier(.175,.885,.32,1.275);transform-style:preserve-3d}.front{width:100%;height:100%;position:absolute;top:0;left:0;padding:24px 28px;border-radius:20px;overflow:hidden;z-index:1;backface-visibility:hidden;background:linear-gradient(135deg,rgba(17,24,39,.95) 0%,rgba(31,41,55,.95) 100%);box-shadow:0 20px 35px #00000040,inset 0 1px #ffffff26;border:1px solid rgba(255,255,255,.1);display:flex;flex-direction:column;justify-content:space-between;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;transition:all .3s ease}.front:before{content:\"\";position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:radial-gradient(circle,rgba(99,102,241,.12) 0%,transparent 70%);pointer-events:none}.card-top-bar{display:flex;justify-content:space-between;align-items:center}.chip{width:48px;height:35px;background:linear-gradient(135deg,#f59e0b 0%,#d97706 100%);border-radius:6px;position:relative;box-shadow:inset 0 1px 2px #ffffff4d}.chip:before{content:\"\";position:absolute;inset:0;border:1px solid rgba(0,0,0,.15);border-radius:6px;background-image:linear-gradient(90deg,transparent 50%,rgba(0,0,0,.1) 50%),linear-gradient(0deg,transparent 50%,rgba(0,0,0,.1) 50%);background-size:10px 10px}.brand-text{font-size:10px;letter-spacing:2px;color:#ffffffb3;font-weight:700;text-shadow:0 2px 4px rgba(0,0,0,.2)}.card-number-display{font-family:Courier New,Courier,monospace;font-size:20px;letter-spacing:3px;color:#fff;text-shadow:0 2px 4px rgba(0,0,0,.3);margin:18px 0;text-align:center;-webkit-user-select:none;user-select:none}.card-bottom-bar{display:flex;justify-content:space-between;align-items:flex-end}.card-label{display:block;font-size:8px;color:#fff6;letter-spacing:1.5px;margin-bottom:2px;text-transform:uppercase}.card-value{display:block;font-size:13px;color:#fff;letter-spacing:.5px;font-weight:600;max-width:230px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-group-custom{display:flex;flex-direction:column;margin-bottom:12px}.form-label-custom{font-size:13px;font-weight:600;color:#374151;margin-bottom:6px;letter-spacing:.2px}.input-wrapper{position:relative;width:100%}.form-control-custom{width:100%;background-color:#f9fafb;border:1px solid #d1d5db;border-radius:8px;padding:10px 14px;font-size:14px;color:#1f2937;transition:all .2s ease-in-out;box-shadow:inset 0 1px 2px #00000005}.form-control-custom:focus{background-color:#fff;border-color:#4f46e5;box-shadow:0 0 0 3px #4f46e51f;outline:none}.inputError,.inputError:focus{border-color:#ef4444!important;box-shadow:0 0 0 3px #ef44441f!important}.date-wrapper{display:flex;align-items:center}.calendar-icon{width:18px;height:18px;position:absolute;right:12px;pointer-events:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%239ca3af'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-size:contain}.form-actions-custom{display:flex;justify-content:flex-end;margin-top:20px;border-top:1px solid #f3f4f6;padding-top:16px}.btn-submit{color:#fff;background-color:#5a75b6;border:solid 2px #5A75B6;border-radius:8px;padding:8px;min-width:120px;margin-right:10px}.btn-submit:hover{background-color:#3e578e;color:#fff}.btn-submit:disabled,.btn-previous:disabled,.btn-next:disabled{background-color:#ecebeb!important;border:solid 2px #ecebeb!important;color:#9c9c9c!important;cursor:not-allowed}.breathing-overlay{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0f172a99;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:9999}.show{display:block}\n"] }]
|
|
184
|
+
}], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: i2.CroemCardWidgetService }]; }, propDecorators: { inputParamsForWidgetForAdd: [{
|
|
185
|
+
type: Input
|
|
186
|
+
}], widgetResponseEmitter: [{
|
|
187
|
+
type: Output
|
|
188
|
+
}], fieldResponseEmitter: [{
|
|
189
|
+
type: Output
|
|
190
|
+
}], loader: [{
|
|
191
|
+
type: Output
|
|
192
|
+
}], fields: [{
|
|
193
|
+
type: Input
|
|
194
|
+
}] } });
|
|
195
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkLWNhcmQtd2lkZ2V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nyb2VtLWNhcmQtd2lkZ2V0L3NyYy9saWIvY2FyZC13aWRnZXQvQWRkLWNhcmQtd2lkZ2V0L2FkZC1jYXJkLXdpZGdldC9hZGQtY2FyZC13aWRnZXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY3JvZW0tY2FyZC13aWRnZXQvc3JjL2xpYi9jYXJkLXdpZGdldC9BZGQtY2FyZC13aWRnZXQvYWRkLWNhcmQtd2lkZ2V0L2FkZC1jYXJkLXdpZGdldC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxTQUFTLEVBQWUsVUFBVSxFQUFFLFdBQVcsRUFBbUIsTUFBTSxnQkFBZ0IsQ0FBQztBQUNsRyxPQUFPLEtBQUssYUFBYSxNQUFNLGdCQUFnQixDQUFDO0FBS2hELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7Ozs7QUFXbEQsTUFBTSxPQUFPLHNCQUFzQjtJQStCakMsWUFBb0IsV0FBd0IsRUFBVSxnQkFBd0M7UUFBMUUsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFBVSxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQXdCO1FBNUJwRiwwQkFBcUIsR0FBRyxJQUFJLFlBQVksRUFBd0IsQ0FBQztRQUNqRSx5QkFBb0IsR0FBRyxJQUFJLFlBQVksRUFBK0MsQ0FBQztRQUN2RixXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztR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Q0FBQyxNQUEyQixDQUFDLEtBQUssQ0FBQztRQUMzRCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUE7SUFDdkIsQ0FBQztJQUNELFFBQVEsQ0FBQyxLQUFZO1FBQ25CLElBQUksQ0FBQyxJQUFJLEdBQUksS0FBSyxDQUFDLE1BQTJCLENBQUMsS0FBSyxDQUFDO1FBQ3JELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQTtJQUNyQixDQUFDO0lBQ0QsV0FBVyxDQUFDLFdBQW1CO1FBQzdCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQy9DLE9BQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBQ0QsWUFBWTtRQUNWLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3hCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7U0FDaEM7YUFDSTtZQUNILElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7U0FDakM7SUFDSCxDQUFDOztvSEEvTVUsc0JBQXNCO3dHQUF0QixzQkFBc0IsZ1JDckJuQyxrL0pBaUdPOzRGRDVFTSxzQkFBc0I7a0JBTGxDLFNBQVM7K0JBQ0UscUJBQXFCO3VJQU10QiwwQkFBMEI7c0JBQWxDLEtBQUs7Z0JBQ0kscUJBQXFCO3NCQUE5QixNQUFNO2dCQUNHLG9CQUFvQjtzQkFBN0IsTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ0UsTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybUdyb3VwLCBGb3JtQnVpbGRlciwgVmFsaWRhdG9ycywgRm9ybUNvbnRyb2wsIEFic3RyYWN0Q29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0ICogYXMgY2FyZFZhbGlkYXRvciBmcm9tIFwiY2FyZC12YWxpZGF0b3JcIjtcclxuaW1wb3J0IHsgQ3JvZW1DYXJkV2lkZ2V0U2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2Nyb2VtLWNhcmQtd2lkZ2V0LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBGaWVsZHMgfSBmcm9tICcuLi8uLi8uLi9keW5hbWljLWZvcm0tYnVpbGRlci9pbnRlcmZhY2VzL0Zvcm1GaWVsZHMuSW50ZXJmYWNlJztcclxuaW1wb3J0IHsgSW5wdXRQYXJhbXNGb3JXaWRnZXQgfSBmcm9tICcuLi8uLi8uLi9keW5hbWljLWZvcm0tYnVpbGRlci9pbnRlcmZhY2VzL0lucHV0UGFyYW1zLkludGVyZmFjZSc7XHJcbmltcG9ydCB7IGFwaVJlc3BvbnNlSW50ZXJmYWNlIH0gZnJvbSAnLi4vLi4vLi4vZHluYW1pYy1mb3JtLWJ1aWxkZXIvaW50ZXJmYWNlcy9hcGlSZXNwb25zZS5JbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBMQU5HX0VOIH0gZnJvbSAnLi4vLi4vLi4vbG9jYWxpemF0aW9ucy9lbic7XHJcbmltcG9ydCB7IExBTkdfRVMgfSBmcm9tICcuLi8uLi8uLi9sb2NhbGl6YXRpb25zL2VzJztcclxuaW1wb3J0IHsgTGFuZ3VhZ2UgfSBmcm9tICcuLi8uLi8uLi9sb2NhbGl6YXRpb25zL2xhbmd1YWdlLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IGNvbnN0YW50cyB9IGZyb20gJy4uLy4uLy4uLy4uL0NvbnN0YW50cyc7XHJcblxyXG5cclxuZGVjbGFyZSBmdW5jdGlvbiBlbmNyeXB0ZWRTdHJpbmcoa2V5OiBhbnksIHM6IGFueSk6IHN0cmluZztcclxuZGVjbGFyZSBmdW5jdGlvbiBpbml0aWFsaXplS2V5KGV4cG9uZW50OiBhbnksIG1vZHVsdXM6IGFueSk6IGFueTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbGliLWFkZC1jYXJkLXdpZGdldCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2FkZC1jYXJkLXdpZGdldC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vYWRkLWNhcmQtd2lkZ2V0LmNvbXBvbmVudC5jc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQWRkQ2FyZFdpZGdldENvbXBvbmVudCB7XHJcblxyXG4gIEBJbnB1dCgpIGlucHV0UGFyYW1zRm9yV2lkZ2V0Rm9yQWRkITogSW5wdXRQYXJhbXNGb3JXaWRnZXQ7XHJcbiAgQE91dHB1dCgpIHdpZGdldFJlc3BvbnNlRW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXI8YXBpUmVzcG9uc2VJbnRlcmZhY2U+KCk7XHJcbiAgQE91dHB1dCgpIGZpZWxkUmVzcG9uc2VFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcjx7IFt4OiBzdHJpbmddOiBBYnN0cmFjdENvbnRyb2w8YW55LCBhbnk+OyB9PigpO1xyXG4gIEBPdXRwdXQoKSBsb2FkZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XHJcbiAgQElucHV0KCkgZmllbGRzOiBGaWVsZHNbXSA9IFtdO1xyXG5cclxuICBkeW5hbWljRmllbGRzOiB7IFtrZXk6IHN0cmluZ106IFthbnksIGFueVtdXSB9ID0ge307XHJcbiAgZW5jcnlwdGVkU3RyaW5nITogc3RyaW5nXHJcbiAgYWRkQ2FyZFJlc3BvbnNlITogYXBpUmVzcG9uc2VJbnRlcmZhY2U7XHJcbiAgc2hvd0xvYWRlcjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGNhcmRJbmZvUmVzcG9uc2UhOiBhcGlSZXNwb25zZUludGVyZmFjZVxyXG4gIGNhcmROdW1iZXIhOiBzdHJpbmc7XHJcbiAgdmFsaWRpdHlEYXRlITogc3RyaW5nO1xyXG4gIG5hbWUhOiBzdHJpbmc7XHJcbiAgc2hvd0lucHV0RXJyb3JOdW1iZXI6IGJvb2xlYW4gPSB0cnVlXHJcbiAgc2hvd0lucHV0RXJyb3JEYXRlOiBib29sZWFuID0gdHJ1ZVxyXG4gIHNob3dJbnB1dEVycm9yTmFtZTogYm9vbGVhbiA9IHRydWVcclxuXHJcbiAgY3VycmVudExhbmchOiBMYW5ndWFnZTtcclxuXHJcbiAgcHVibGljIG1vbnRoITogc3RyaW5nXHJcbiAgcHVibGljIHllYXIhOiBzdHJpbmdcclxuICBwdWJsaWMgdmFsaWQhOiBib29sZWFuXHJcbiAgcHVibGljIG1heExlbmd0aCE6IG51bWJlcjtcclxuICBwdWJsaWMgbWF4RXhwWWVhciE6IG51bWJlcjtcclxuICBjYXJkRm9ybSE6IEZvcm1Hcm91cDtcclxuICBmb3JtITogRm9ybUdyb3VwO1xyXG4gIENyb2VtQ2FyZFdpZGdldFNlcnZpY2UhOiBDcm9lbUNhcmRXaWRnZXRTZXJ2aWNlO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGZvcm1CdWlsZGVyOiBGb3JtQnVpbGRlciwgcHJpdmF0ZSBjcm9lbUNhcmRTZXJ2aWNlOiBDcm9lbUNhcmRXaWRnZXRTZXJ2aWNlKSB7XHJcbiAgICB0aGlzLm1heExlbmd0aCA9IDE5O1xyXG4gICAgdGhpcy5tYXhFeHBZZWFyID0gMjg7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuXHJcbiAgICB0aGlzLnN3aXRjaExhbmd1YWdlKHRoaXMuaW5wdXRQYXJhbXNGb3JXaWRnZXRGb3JBZGQuQ3VsdHVyZSk7XHJcblxyXG4gICAgLy8tLS1EeW5hbWljIEZvcm0gY3JlYXRpb24gaW5uaXRpYWxpemluZyBmb3JtIGdyb3VwKGkuZSBjYXJkRm9ybSkgdG8gcGFzcyBvbnRvIHRoZSBkeW5hbWljIGZvcm0gYnVpbGRlciBjb21wb25lbnQgLS0tLS0tXHJcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHRoaXMuZmllbGRzKSB7XHJcbiAgICAgIGNvbnN0IHZhbGlkYXRvcnMgPSBbXTtcclxuICAgICAgaWYgKGZpZWxkLnJlcXVpcmVkKSB7XHJcbiAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMucmVxdWlyZWQpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZHluYW1pY0ZpZWxkc1tmaWVsZC5uYW1lXSA9IFtmaWVsZC52YWx1ZSB8fCBudWxsLCB2YWxpZGF0b3JzXTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBwcmVkZWZpbmVkQ29udHJvbHMgPSB7XHJcbiAgICAgIG5hbWU6IFsnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcclxuICAgICAgY2FyZE51bWJlcjogWycnLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW5MZW5ndGgoMTApLCBWYWxpZGF0b3JzLm1heExlbmd0aCgxOSldXSxcclxuICAgICAgdmFsaWRpdHlEYXRlOiBbJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1pbkxlbmd0aCg1KV1dLFxyXG4gICAgfTtcclxuICAgIHRoaXMuY2FyZEZvcm0gPSB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcclxuICAgICAgLi4ucHJlZGVmaW5lZENvbnRyb2xzLFxyXG4gICAgICAuLi50aGlzLmR5bmFtaWNGaWVsZHNcclxuICAgIH0pO1xyXG5cclxuICAgIGxldCBmaWVsZHNDb250cmxzOiB7IFtrZXk6IHN0cmluZ106IEZvcm1Db250cm9sIHwgRm9ybUdyb3VwIH0gPSB7fTtcclxuXHJcbiAgICBmb3IgKGxldCBmIG9mIHRoaXMuZmllbGRzKSB7XHJcbiAgICAgIGlmIChmLnR5cGUgIT09ICdjaGVja2JveCcpIHtcclxuICAgICAgICBmaWVsZHNDb250cmxzW2YubmFtZV0gPSBuZXcgRm9ybUNvbnRyb2woZi52YWx1ZSB8fCAnJywgVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbGV0IG9wdHM6IHsgW2tleTogc3RyaW5nXTogRm9ybUNvbnRyb2wgfSA9IHt9O1xyXG4gICAgICAgIGlmIChmLm9wdGlvbnMpIHtcclxuXHJcbiAgICAgICAgICBmb3IgKGxldCBvcHQgb2YgZi5vcHRpb25zKSB7XHJcbiAgICAgICAgICAgIG9wdHNbb3B0LmtleV0gPSBuZXcgRm9ybUNvbnRyb2wob3B0LmxhYmVsKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZmllbGRzQ29udHJsc1tmLm5hbWVdID0gbmV3IEZvcm1Hcm91cChvcHRzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICAvLy0tLWxvY2FsaXphdGlvbiAgVG8gYWRkIGEgbmV3IHByb3BlcnR5IHRvIHRoaXMgZ28gbG9jYWxpemF0aW9uIGRpciBhbmQgYWRkIHlvdXIgcHJvcGVydHkgaW5zZGVpIGVuLnRzIGFuZCBlcy50cyAtLS0tLS1cclxuICBzd2l0Y2hMYW5ndWFnZShsYW5ndWFnZTogc3RyaW5nKSB7XHJcbiAgICBpZiAobGFuZ3VhZ2UgPT09ICdlbicpIHtcclxuICAgICAgdGhpcy5jdXJyZW50TGFuZyA9IExBTkdfRU47XHJcbiAgICB9IGVsc2UgaWYgKGxhbmd1YWdlID09PSAnZXMnKSB7XHJcbiAgICAgIHRoaXMuY3VycmVudExhbmcgPSBMQU5HX0VTO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY3JlYXRlQ2FyZCgpIHtcclxuICAgIHRoaXMuYWRkQ2FyZCgpXHJcbiAgfVxyXG5cclxuICBhc3luYyBhZGRDYXJkKCkge1xyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIHRoaXMuc2hvd0xvYWRlciA9IHRydWU7XHJcbiAgICAgIHRoaXMubG9hZGVyLmVtaXQodGhpcy5zaG93TG9hZGVyKVxyXG5cclxuICAgICAgY29uc3QgYXBpVXJsID0gdGhpcy5pbnB1dFBhcmFtc0ZvcldpZGdldEZvckFkZC5EdHJVcmwgKyBjb25zdGFudHMudXJscy5hZGREVFJVcmw7XHJcbiAgICAgIC8vLS0tLWVuY3J5cHRpb24tLS0tLS0tXHJcbiAgICAgIHZhciBlbmNvZGUgPSB0aGlzLmVuY29kaW5nKCk7ICAgIC8vLS1lbmNvZGluZyBwYXJhbWV0ZXJzIFxyXG4gICAgICB0aGlzLmVuY3J5cHRlZFN0cmluZyA9IHRoaXMuaW5uaXRpYWxpemVLZXkoZW5jb2RlKTsgICAgIC8vLS1pbm5pdGlhbGl6aW5nIERTQSBrZXlcclxuXHJcbiAgICAgIHRoaXMuYWRkQ2FyZFJlc3BvbnNlID0gYXdhaXQgdGhpcy5jcm9lbUNhcmRTZXJ2aWNlLmFkZFVwZGF0ZUNhcmRBUElDYWxsKGFwaVVybCwgdGhpcy5lbmNyeXB0ZWRTdHJpbmcpOyAgIC8vLS1BUEkgQ2FsbCB0byBhZGQgY2FyZCBpbiBEVFJcclxuXHJcbiAgICAgIHRoaXMuc2hvd0xvYWRlciA9IGZhbHNlO1xyXG4gICAgICBcclxuXHJcbiAgICAgIHRoaXMuZmllbGRSZXNwb25zZUVtaXR0ZXIuZW1pdCh0aGlzLmNhcmRGb3JtLmNvbnRyb2xzKTtcclxuICAgICAgdGhpcy53aWRnZXRSZXNwb25zZUVtaXR0ZXIuZW1pdCh0aGlzLmFkZENhcmRSZXNwb25zZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xyXG4gICAgICB0aGlzLnNob3dMb2FkZXIgPSBmYWxzZTtcclxuICAgICAgdGhpcy53aWRnZXRSZXNwb25zZUVtaXR0ZXIuZW1pdCh0aGlzLmFkZENhcmRSZXNwb25zZSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGVuY29kaW5nKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuY2FyZEZvcm0udmFsdWUuY2FyZE51bWJlciArIFwiXFxcXFwiICtcclxuICAgICAgdGhpcy5jYXJkRm9ybS52YWx1ZS5uYW1lICsgXCJcXFxcXCIgK1xyXG4gICAgICB0aGlzLmNhcmRGb3JtLnZhbHVlLnZhbGlkaXR5RGF0ZS5zdWJzdHJpbmcoMCwgMikgKyBcIlxcXFxcIiArXHJcbiAgICAgIHRoaXMuY2FyZEZvcm0udmFsdWUudmFsaWRpdHlEYXRlLnN1YnN0cmluZygzKSArIFwiXFxcXFwiICtcclxuICAgICAgXCJcIiArIFwiXFxcXFwiICtcclxuICAgICAgXCJcIiArIFwiXFxcXFwiICtcclxuICAgICAgdGhpcy5pbnB1dFBhcmFtc0ZvcldpZGdldEZvckFkZC5BUElLZXkgKyBcIlxcXFxcIiArXHJcbiAgICAgIHRoaXMuaW5wdXRQYXJhbXNGb3JXaWRnZXRGb3JBZGQuQ3VsdHVyZSArIFwiXFxcXFwiICtcclxuICAgICAgXCJcIiArIFwiXFxcXFwiICtcclxuICAgICAgKHRoaXMuaW5wdXRQYXJhbXNGb3JXaWRnZXRGb3JBZGQuSXNTYWxlID8/IGZhbHNlKSArIFwiXFxcXFwiICtcclxuICAgICAgKHRoaXMuaW5wdXRQYXJhbXNGb3JXaWRnZXRGb3JBZGQuQW1vdW50ID8/IFwiMFwiKSArIFwiXFxcXFwiICtcclxuICAgICAgKHRoaXMuaW5wdXRQYXJhbXNGb3JXaWRnZXRGb3JBZGQuUHJvZHVjdERldGFpbHMgPz8gXCIwXCIpICsgXCJcXFxcXCIgK1xyXG4gICAgICBcIlwiICsgXCJcXFxcXCIgK1xyXG4gICAgICBcIlwiICsgXCJcXFxcXCIgK1xyXG4gICAgICAodGhpcy5pbnB1dFBhcmFtc0ZvcldpZGdldEZvckFkZC5JdGJtcyA/PyBcIjBcIikgKyBcIlxcXFxcIiArXHJcbiAgICAgIHRoaXMuaW5wdXRQYXJhbXNGb3JXaWRnZXRGb3JBZGQuTW9kZVxyXG4gIH1cclxuICBpbm5pdGlhbGl6ZUtleShlbmNvZGU6IHN0cmluZykge1xyXG4gICAgdmFyIGtleSA9IGluaXRpYWxpemVLZXkodGhpcy5pbnB1dFBhcmFtc0ZvcldpZGdldEZvckFkZC5LZXlzLkVuY0tleTEsIHRoaXMuaW5wdXRQYXJhbXNGb3JXaWRnZXRGb3JBZGQuS2V5cy5FbmNLZXkyKTtcclxuICAgIHJldHVybiBlbmNyeXB0ZWRTdHJpbmcoa2V5LCBlbmNvZGUpXHJcbiAgfVxyXG5cclxuICBmb3JtYXREYXRlKGV2ZW50OiBFdmVudCkge1xyXG4gICAgbGV0IGlucHV0ID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcclxuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvXFxEL2csICcnKTtcclxuXHJcbiAgICBjb25zdCBtb250aCA9IHRoaXMuZm9ybWF0TW9udGgoaW5wdXQuc3Vic3RyaW5nKDAsIDIpKTtcclxuICAgIGNvbnN0IHllYXIgPSBpbnB1dC5zdWJzdHJpbmcoMiwgNCk7XHJcblxyXG4gICAgY29uc3QgZm9ybWF0dGVkRGF0ZSA9IG1vbnRoICsgKHllYXIgPyAnLycgKyB5ZWFyIDogJycpO1xyXG4gICAgKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZSA9IGZvcm1hdHRlZERhdGU7XHJcblxyXG4gICAgdGhpcy5jYXJkRm9ybS5jb250cm9sc1sndmFsaWRpdHlEYXRlJ10uc2V0VmFsdWUoZm9ybWF0dGVkRGF0ZSk7XHJcbiAgICB0aGlzLnZhbGlkaXR5RGF0ZSA9IHRoaXMuY2FyZEZvcm0uY29udHJvbHNbJ3ZhbGlkaXR5RGF0ZSddLnZhbHVlO1xyXG5cclxuICAgIHRoaXMudmFsaWRhdGVEYXRlKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZvcm1hdE1vbnRoKG1vbnRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgdmFsaWRNb250aCA9IHBhcnNlSW50KG1vbnRoLCAxMCk7XHJcbiAgICByZXR1cm4gKHZhbGlkTW9udGggPiAxICYmIHZhbGlkTW9udGggPD0gOSkgPyAnMCcgKyB2YWxpZE1vbnRoIDogbW9udGg7XHJcbiAgfVxyXG5cclxuXHJcbiAgbWFza0NhcmROdW1iZXIoKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLmNhcmROdW1iZXIgJiYgdGhpcy5jYXJkTnVtYmVyLmxlbmd0aCA+IDApIHtcclxuICAgICAgY29uc3QgbWFza2VkTnVtYmVyID0gJ+KAoicucmVwZWF0KE1hdGgubWF4KDAsIHRoaXMuY2FyZE51bWJlci5sZW5ndGggLSA0KSkgKyB0aGlzLmNhcmROdW1iZXIuc2xpY2UoLTQpO1xyXG4gICAgICByZXR1cm4gbWFza2VkTnVtYmVyLnJlcGxhY2UoLyjigKJ7NH0pL2csICckMSAnKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICByZXR1cm4gJ+KAouKAouKAouKAoiDigKLigKLigKLigKIg4oCi4oCi4oCi4oCiIOKAouKAouKAouKAoic7XHJcbiAgICB9XHJcbiAgfVxyXG4gIG1hc2tOYW1lKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5uYW1lID8gdGhpcy5uYW1lIDogJ1lvdXIgTmFtZSc7XHJcbiAgfVxyXG4gIG1hc2tEYXRlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMudmFsaWRpdHlEYXRlID8gdGhpcy52YWxpZGl0eURhdGUgOiAn4oCi4oCiL+KAouKAoic7XHJcbiAgfVxyXG5cclxuICB2YWxpZGF0ZURhdGUoKSB7XHJcbiAgICBpZiAoIXRoaXMuaW5wdXRQYXJhbXNGb3JXaWRnZXRGb3JBZGQuSXNTYWxlKSB7XHJcbiAgICAgIHRoaXMuc2hvd0lucHV0RXJyb3JEYXRlID0gY2FyZFZhbGlkYXRvci5leHBpcmF0aW9uRGF0ZSh0aGlzLnZhbGlkaXR5RGF0ZSwgdGhpcy5tYXhFeHBZZWFyKS5pc1ZhbGlkO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIHRoaXMuc2hvd0lucHV0RXJyb3JEYXRlID0gdHJ1ZVxyXG4gICAgfVxyXG4gIH1cclxuICB2YWxpZGF0ZU51bWJlcigpIHtcclxuICAgIGNvbnN0IHZhbGlkID0gY2FyZFZhbGlkYXRvci5udW1iZXIodGhpcy5jYXJkTnVtYmVyKS5pc1ZhbGlkO1xyXG4gICAgdGhpcy5zaG93SW5wdXRFcnJvck51bWJlciA9IHZhbGlkXHJcbiAgfVxyXG4gIGJpbmROdW1iZXIoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICB0aGlzLmNhcmROdW1iZXIgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnZhbHVlO1xyXG4gICAgdGhpcy52YWxpZGF0ZU51bWJlcigpXHJcbiAgfVxyXG4gIGJpbmROYW1lKGV2ZW50OiBFdmVudCkge1xyXG4gICAgdGhpcy5uYW1lID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcclxuICAgIHRoaXMudmFsaWRhdGVOYW1lKClcclxuICB9XHJcbiAgcmVzdENvbnRyb2woY29udHJvbG5hbWU6IHN0cmluZykge1xyXG4gICAgY29uc3QgY29udHJvbCA9IHRoaXMuY2FyZEZvcm0uZ2V0KGNvbnRyb2xuYW1lKTtcclxuICAgIGNvbnRyb2whLnJlc2V0KCk7XHJcbiAgfVxyXG4gIHZhbGlkYXRlTmFtZSgpIHtcclxuICAgIGlmICh0aGlzLm5hbWUubGVuZ3RoID4gNCkge1xyXG4gICAgICB0aGlzLnNob3dJbnB1dEVycm9yTmFtZSA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgdGhpcy5zaG93SW5wdXRFcnJvck5hbWUgPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcbn0iLCI8Zm9ybSBjbGFzcz1cImNvbnRhaW5lci1mbHVpZCBweS0zXCIgW2Zvcm1Hcm91cF09XCJjYXJkRm9ybVwiICpuZ0lmPVwiKGlucHV0UGFyYW1zRm9yV2lkZ2V0Rm9yQWRkLkFQSUtleSlcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJwLTBcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXIgbWItNFwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtaW5uZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnJvbnRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBUb3AgQmFyOiBDaGlwICYgQnJhbmQgTG9nbyAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtdG9wLWJhclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNoaXBcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWJyYW5kXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJicmFuZC10ZXh0XCI+U0VDVVJFIENBUkQ8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE1pZGRsZSBCYXI6IENhcmQgTnVtYmVyIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1udW1iZXItZGlzcGxheVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3ttYXNrQ2FyZE51bWJlcigpfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBCb3R0b20gQmFyOiBDYXJkaG9sZGVyIE5hbWUgJiBFeHBpcmF0aW9uIERhdGUgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWJvdHRvbS1iYXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWhvbGRlci1pbmZvXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2FyZC1sYWJlbFwiPkNBUkRIT0xERVI8L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY2FyZC12YWx1ZVwiPnt7bWFza05hbWUoKX19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1leHBpcnktaW5mb1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNhcmQtbGFiZWxcIj57e2N1cnJlbnRMYW5nW1wiVmFsaWRUaHJ1XCJdfX08L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY2FyZC12YWx1ZVwiPnt7bWFza0RhdGUoKX19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8IS0tIER5bmFtaWMgRm9ybSBGaWVsZHMgLS0+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImR5bmFtaWMtZmllbGRzLWNvbnRhaW5lciBtYi0zXCI+XHJcbiAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGZpZWxkc1wiIGNsYXNzPVwibWItM1wiPlxyXG4gICAgICAgICAgICAgICAgPGZpZWxkLWJ1aWxkZXIgW2ZpZWxkXT1cImZpZWxkXCIgW2Zvcm1dPVwiY2FyZEZvcm1cIj48L2ZpZWxkLWJ1aWxkZXI+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8IS0tIFN0YXRpYyBGb3JtIEZpZWxkcyAtLT5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1mb3JtLWZpZWxkc1wiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IG1iLTNcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMTJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cC1jdXN0b21cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cImNhcmQtbnVtYmVyXCIgY2xhc3M9XCJmb3JtLWxhYmVsLWN1c3RvbVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjdXJyZW50TGFuZ1tcIkNhcmROdW1iZXJcIl19fSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXdyYXBwZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY29udHJvbC1jdXN0b21cIiB0eXBlPVwidGV4dFwiIGlkPVwiY2FyZC1udW1iZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pbnB1dEVycm9yXT1cIiFzaG93SW5wdXRFcnJvck51bWJlclwiIFtwbGFjZWhvbGRlcl09XCJjdXJyZW50TGFuZ1snQ2FyZE51bWJlciddXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJjYXJkTnVtYmVyXCIgKGlucHV0KT1cImJpbmROdW1iZXIoJGV2ZW50KVwiIFttYXhsZW5ndGhdPVwibWF4TGVuZ3RoXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IG1iLTNcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMTJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cC1jdXN0b21cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cIm5hbWVcIiBjbGFzcz1cImZvcm0tbGFiZWwtY3VzdG9tXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2N1cnJlbnRMYW5nW1wiQ2FyZEhvbGRlck5hbWVcIl19fSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LXdyYXBwZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY29udHJvbC1jdXN0b21cIiB0eXBlPVwidGV4dFwiIGlkPVwibmFtZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImN1cnJlbnRMYW5nWydDYXJkSG9sZGVyTmFtZSddXCIgW2NsYXNzLmlucHV0RXJyb3JdPVwiIXNob3dJbnB1dEVycm9yTmFtZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cImJpbmROYW1lKCRldmVudClcIiBmb3JtQ29udHJvbE5hbWU9XCJuYW1lXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IG1iLTRcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtNlwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwLWN1c3RvbVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwidmFsaWRpdHktZGF0ZVwiIGNsYXNzPVwiZm9ybS1sYWJlbC1jdXN0b21cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y3VycmVudExhbmdbXCJFeHBpcnlEYXRlXCJdfX0gPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC13cmFwcGVyIGRhdGUtd3JhcHBlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jb250cm9sLWN1c3RvbVwiIHR5cGU9XCJ0ZXh0XCIgaWQ9XCJ2YWxpZGl0eS1kYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaW5wdXRFcnJvcl09XCIhc2hvd0lucHV0RXJyb3JEYXRlXCIgcGxhY2Vob2xkZXI9XCJNTS9ZWVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwidmFsaWRpdHlEYXRlXCIgKGlucHV0KT1cImZvcm1hdERhdGUoJGV2ZW50KVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNhbGVuZGFyLWljb25cIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImZvcm0tYWN0aW9ucy1jdXN0b21cIj5cclxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuLXN1Ym1pdFwiIHR5cGU9XCJzdWJtaXRcIiBbZGlzYWJsZWRdPVwiIWNhcmRGb3JtLnZhbGlkXCIgKGNsaWNrKT1cImNyZWF0ZUNhcmQoKVwiPlxyXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJ0bi10ZXh0XCI+e3tjdXJyZW50TGFuZ1tcImxibFNhdmVcIl19fTwvc3Bhbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgIDwvZGl2PlxyXG48L2Zvcm0+Il19
|