@oneluiz/dual-datepicker 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -23,6 +23,8 @@ A beautiful, customizable dual-calendar date range picker for Angular 17+. Built
|
|
|
23
23
|
- 🌐 **TypeScript** - Full type safety
|
|
24
24
|
- ♿ **Accessible** - Keyboard navigation and ARIA labels
|
|
25
25
|
- 🎭 **Flexible Behavior** - Control when the picker closes
|
|
26
|
+
- 🔄 **Reactive Forms Support** - Full ControlValueAccessor implementation
|
|
27
|
+
- ⚡ **Angular Signals** - Modern reactive state management
|
|
26
28
|
|
|
27
29
|
## 📦 Installation
|
|
28
30
|
|
|
@@ -67,14 +69,16 @@ import { DualDatepickerComponent } from '@oneluiz/dual-datepicker';
|
|
|
67
69
|
imports: [FormsModule, DualDatepickerComponent],
|
|
68
70
|
template: `
|
|
69
71
|
<ngx-dual-datepicker
|
|
70
|
-
[
|
|
72
|
+
[fechaInicio]="fechaInicio"
|
|
73
|
+
[fechaFin]="fechaFin"
|
|
71
74
|
[presets]="customPresets"
|
|
72
|
-
(
|
|
75
|
+
(dateRangeChange)="onDateChange($event)">
|
|
73
76
|
</ngx-dual-datepicker>
|
|
74
77
|
`
|
|
75
78
|
})
|
|
76
79
|
export class ExampleComponent {
|
|
77
|
-
|
|
80
|
+
fechaInicio = '';
|
|
81
|
+
fechaFin = '';
|
|
78
82
|
|
|
79
83
|
customPresets = [
|
|
80
84
|
{ label: 'Last 7 days', daysAgo: 7 },
|
|
@@ -82,8 +86,119 @@ export class ExampleComponent {
|
|
|
82
86
|
{ label: 'Last 90 days', daysAgo: 90 }
|
|
83
87
|
];
|
|
84
88
|
|
|
85
|
-
onDateChange(range:
|
|
89
|
+
onDateChange(range: DateRange) {
|
|
86
90
|
console.log('Date range selected:', range);
|
|
91
|
+
this.fechaInicio = range.fechaInicio;
|
|
92
|
+
this.fechaFin = range.fechaFin;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 3. Use with Reactive Forms ✨ New!
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { Component, OnInit } from '@angular/core';
|
|
101
|
+
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
102
|
+
import { DualDatepickerComponent, DateRange } from '@oneluiz/dual-datepicker';
|
|
103
|
+
|
|
104
|
+
@Component({
|
|
105
|
+
selector: 'app-reactive-form',
|
|
106
|
+
standalone: true,
|
|
107
|
+
imports: [ReactiveFormsModule, DualDatepickerComponent],
|
|
108
|
+
template: `
|
|
109
|
+
<form [formGroup]="form" (ngSubmit)="onSubmit()">
|
|
110
|
+
<label>Select Date Range:</label>
|
|
111
|
+
<ngx-dual-datepicker
|
|
112
|
+
formControlName="dateRange"
|
|
113
|
+
placeholder="Choose dates"
|
|
114
|
+
[showClearButton]="true">
|
|
115
|
+
</ngx-dual-datepicker>
|
|
116
|
+
|
|
117
|
+
<button type="submit" [disabled]="!form.valid">Submit</button>
|
|
118
|
+
|
|
119
|
+
@if (form.value.dateRange) {
|
|
120
|
+
<div>
|
|
121
|
+
Selected: {{ form.value.dateRange.fechaInicio }} to {{ form.value.dateRange.fechaFin }}
|
|
122
|
+
</div>
|
|
123
|
+
}
|
|
124
|
+
</form>
|
|
125
|
+
`
|
|
126
|
+
})
|
|
127
|
+
export class ReactiveFormComponent implements OnInit {
|
|
128
|
+
form!: FormGroup;
|
|
129
|
+
|
|
130
|
+
constructor(private fb: FormBuilder) {}
|
|
131
|
+
|
|
132
|
+
ngOnInit() {
|
|
133
|
+
this.form = this.fb.group({
|
|
134
|
+
dateRange: [null] // Will receive DateRange object
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Listen to changes
|
|
138
|
+
this.form.get('dateRange')?.valueChanges.subscribe(value => {
|
|
139
|
+
console.log('Date range changed:', value);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
onSubmit() {
|
|
144
|
+
const dateRange: DateRange = this.form.value.dateRange;
|
|
145
|
+
console.log('Form submitted:', dateRange);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 4. Use with Angular Signals ⚡ New!
|
|
151
|
+
|
|
152
|
+
The component now uses Angular Signals internally for better performance and reactivity:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { Component, signal, computed } from '@angular/core';
|
|
156
|
+
import { DualDatepickerComponent, DateRange } from '@oneluiz/dual-datepicker';
|
|
157
|
+
|
|
158
|
+
@Component({
|
|
159
|
+
selector: 'app-signals-example',
|
|
160
|
+
standalone: true,
|
|
161
|
+
imports: [DualDatepickerComponent],
|
|
162
|
+
template: `
|
|
163
|
+
<ngx-dual-datepicker
|
|
164
|
+
[fechaInicio]="fechaInicio()"
|
|
165
|
+
[fechaFin]="fechaFin()"
|
|
166
|
+
(dateRangeChange)="onDateChange($event)">
|
|
167
|
+
</ngx-dual-datepicker>
|
|
168
|
+
|
|
169
|
+
@if (isRangeSelected()) {
|
|
170
|
+
<div>
|
|
171
|
+
<p>{{ rangeText() }}</p>
|
|
172
|
+
<p>Days selected: {{ daysDifference() }}</p>
|
|
173
|
+
</div>
|
|
174
|
+
}
|
|
175
|
+
`
|
|
176
|
+
})
|
|
177
|
+
export class SignalsExampleComponent {
|
|
178
|
+
fechaInicio = signal('');
|
|
179
|
+
fechaFin = signal('');
|
|
180
|
+
|
|
181
|
+
// Computed values
|
|
182
|
+
isRangeSelected = computed(() =>
|
|
183
|
+
this.fechaInicio() !== '' && this.fechaFin() !== ''
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
rangeText = computed(() =>
|
|
187
|
+
this.isRangeSelected()
|
|
188
|
+
? `${this.fechaInicio()} to ${this.fechaFin()}`
|
|
189
|
+
: 'No range selected'
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
daysDifference = computed(() => {
|
|
193
|
+
if (!this.isRangeSelected()) return 0;
|
|
194
|
+
const start = new Date(this.fechaInicio());
|
|
195
|
+
const end = new Date(this.fechaFin());
|
|
196
|
+
return Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
onDateChange(range: DateRange) {
|
|
200
|
+
this.fechaInicio.set(range.fechaInicio);
|
|
201
|
+
this.fechaFin.set(range.fechaFin);
|
|
87
202
|
}
|
|
88
203
|
}
|
|
89
204
|
```
|
|
@@ -146,7 +261,7 @@ customPresets: PresetConfig[] = [
|
|
|
146
261
|
| `placeholder` | `string` | `'Select date range'` | Input placeholder text |
|
|
147
262
|
| `presets` | `PresetConfig[]` | Default presets | Array of preset configurations |
|
|
148
263
|
| `showPresets` | `boolean` | `true` | Show/hide the presets sidebar |
|
|
149
|
-
| `showClearButton` | `boolean` | `
|
|
264
|
+
| `showClearButton` | `boolean` | `false` | Show/hide the Clear button in dropdown |
|
|
150
265
|
| `closeOnSelection` | `boolean` | `false` | Close picker when both dates selected |
|
|
151
266
|
| `closeOnPresetSelection` | `boolean` | `false` | Close picker when preset is clicked |
|
|
152
267
|
| `closeOnClickOutside` | `boolean` | `true` | Close picker when clicking outside |
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EventEmitter, OnInit, OnChanges, SimpleChanges, ElementRef } from '@angular/core';
|
|
2
|
+
import { ControlValueAccessor } from '@angular/forms';
|
|
2
3
|
import * as i0 from "@angular/core";
|
|
3
4
|
export interface DateRange {
|
|
4
5
|
fechaInicio: string;
|
|
@@ -16,7 +17,7 @@ export interface LocaleConfig {
|
|
|
16
17
|
dayNamesShort?: string[];
|
|
17
18
|
firstDayOfWeek?: number;
|
|
18
19
|
}
|
|
19
|
-
export declare class DualDatepickerComponent implements OnInit, OnChanges {
|
|
20
|
+
export declare class DualDatepickerComponent implements OnInit, OnChanges, ControlValueAccessor {
|
|
20
21
|
private elementRef;
|
|
21
22
|
placeholder: string;
|
|
22
23
|
fechaInicio: string;
|
|
@@ -36,17 +37,23 @@ export declare class DualDatepickerComponent implements OnInit, OnChanges {
|
|
|
36
37
|
locale: LocaleConfig;
|
|
37
38
|
dateRangeChange: EventEmitter<DateRange>;
|
|
38
39
|
dateRangeSelected: EventEmitter<DateRange>;
|
|
39
|
-
mostrarDatePicker: boolean
|
|
40
|
-
rangoFechas: string
|
|
41
|
-
fechaSeleccionandoInicio: boolean
|
|
42
|
-
mesActual: Date
|
|
43
|
-
mesAnterior: Date
|
|
44
|
-
diasMesActual: any[]
|
|
45
|
-
diasMesAnterior: any[]
|
|
40
|
+
mostrarDatePicker: import("@angular/core").WritableSignal<boolean>;
|
|
41
|
+
rangoFechas: import("@angular/core").WritableSignal<string>;
|
|
42
|
+
fechaSeleccionandoInicio: import("@angular/core").WritableSignal<boolean>;
|
|
43
|
+
mesActual: import("@angular/core").WritableSignal<Date>;
|
|
44
|
+
mesAnterior: import("@angular/core").WritableSignal<Date>;
|
|
45
|
+
diasMesActual: import("@angular/core").WritableSignal<any[]>;
|
|
46
|
+
diasMesAnterior: import("@angular/core").WritableSignal<any[]>;
|
|
47
|
+
isDisabled: import("@angular/core").WritableSignal<boolean>;
|
|
48
|
+
nombreMesActual: import("@angular/core").Signal<string>;
|
|
49
|
+
nombreMesAnterior: import("@angular/core").Signal<string>;
|
|
50
|
+
diasSemana: import("@angular/core").Signal<string[]>;
|
|
46
51
|
private readonly defaultMonthNames;
|
|
47
52
|
private readonly defaultMonthNamesShort;
|
|
48
53
|
private readonly defaultDayNames;
|
|
49
54
|
private readonly defaultDayNamesShort;
|
|
55
|
+
private onChange;
|
|
56
|
+
private onTouched;
|
|
50
57
|
constructor(elementRef: ElementRef);
|
|
51
58
|
onClickOutside(event: MouseEvent): void;
|
|
52
59
|
ngOnInit(): void;
|
|
@@ -67,6 +74,11 @@ export declare class DualDatepickerComponent implements OnInit, OnChanges {
|
|
|
67
74
|
limpiar(): void;
|
|
68
75
|
private emitirCambio;
|
|
69
76
|
private emitirSeleccion;
|
|
77
|
+
private getDateRangeValue;
|
|
78
|
+
writeValue(value: DateRange | null): void;
|
|
79
|
+
registerOnChange(fn: (value: DateRange | null) => void): void;
|
|
80
|
+
registerOnTouched(fn: () => void): void;
|
|
81
|
+
setDisabledState(isDisabled: boolean): void;
|
|
70
82
|
static ɵfac: i0.ɵɵFactoryDeclaration<DualDatepickerComponent, never>;
|
|
71
83
|
static ɵcmp: i0.ɵɵComponentDeclaration<DualDatepickerComponent, "ngx-dual-datepicker", never, { "placeholder": { "alias": "placeholder"; "required": false; }; "fechaInicio": { "alias": "fechaInicio"; "required": false; }; "fechaFin": { "alias": "fechaFin"; "required": false; }; "showPresets": { "alias": "showPresets"; "required": false; }; "showClearButton": { "alias": "showClearButton"; "required": false; }; "closeOnSelection": { "alias": "closeOnSelection"; "required": false; }; "closeOnPresetSelection": { "alias": "closeOnPresetSelection"; "required": false; }; "closeOnClickOutside": { "alias": "closeOnClickOutside"; "required": false; }; "presets": { "alias": "presets"; "required": false; }; "inputBackgroundColor": { "alias": "inputBackgroundColor"; "required": false; }; "inputTextColor": { "alias": "inputTextColor"; "required": false; }; "inputBorderColor": { "alias": "inputBorderColor"; "required": false; }; "inputBorderColorHover": { "alias": "inputBorderColorHover"; "required": false; }; "inputBorderColorFocus": { "alias": "inputBorderColorFocus"; "required": false; }; "inputPadding": { "alias": "inputPadding"; "required": false; }; "locale": { "alias": "locale"; "required": false; }; }, { "dateRangeChange": "dateRangeChange"; "dateRangeSelected": "dateRangeSelected"; }, never, never, true, never>;
|
|
72
84
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter, HostListener } from '@angular/core';
|
|
1
|
+
import { Component, Input, Output, EventEmitter, HostListener, forwardRef, signal, computed, effect } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { FormsModule } from '@angular/forms';
|
|
3
|
+
import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
import * as i1 from "@angular/common";
|
|
6
6
|
export class DualDatepickerComponent {
|
|
@@ -9,7 +9,7 @@ export class DualDatepickerComponent {
|
|
|
9
9
|
fechaInicio = '';
|
|
10
10
|
fechaFin = '';
|
|
11
11
|
showPresets = true;
|
|
12
|
-
showClearButton =
|
|
12
|
+
showClearButton = false;
|
|
13
13
|
closeOnSelection = true;
|
|
14
14
|
closeOnPresetSelection = true;
|
|
15
15
|
closeOnClickOutside = true;
|
|
@@ -27,22 +27,38 @@ export class DualDatepickerComponent {
|
|
|
27
27
|
locale = {};
|
|
28
28
|
dateRangeChange = new EventEmitter();
|
|
29
29
|
dateRangeSelected = new EventEmitter();
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
// Signals for reactive state
|
|
31
|
+
mostrarDatePicker = signal(false);
|
|
32
|
+
rangoFechas = signal('');
|
|
33
|
+
fechaSeleccionandoInicio = signal(true);
|
|
34
|
+
mesActual = signal(new Date());
|
|
35
|
+
mesAnterior = signal(new Date());
|
|
36
|
+
diasMesActual = signal([]);
|
|
37
|
+
diasMesAnterior = signal([]);
|
|
38
|
+
isDisabled = signal(false);
|
|
39
|
+
// Computed values
|
|
40
|
+
nombreMesActual = computed(() => this.getNombreMes(this.mesActual()));
|
|
41
|
+
nombreMesAnterior = computed(() => this.getNombreMes(this.mesAnterior()));
|
|
42
|
+
diasSemana = computed(() => this.getDayNames());
|
|
37
43
|
defaultMonthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
38
44
|
defaultMonthNamesShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
39
45
|
defaultDayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
40
46
|
defaultDayNamesShort = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
|
|
47
|
+
// ControlValueAccessor callbacks
|
|
48
|
+
onChange = () => { };
|
|
49
|
+
onTouched = () => { };
|
|
41
50
|
constructor(elementRef) {
|
|
42
51
|
this.elementRef = elementRef;
|
|
52
|
+
// Effect to emit changes when dates change
|
|
53
|
+
effect(() => {
|
|
54
|
+
const rango = this.rangoFechas();
|
|
55
|
+
if (this.fechaInicio || this.fechaFin) {
|
|
56
|
+
this.onChange(this.getDateRangeValue());
|
|
57
|
+
}
|
|
58
|
+
});
|
|
43
59
|
}
|
|
44
60
|
onClickOutside(event) {
|
|
45
|
-
if (this.mostrarDatePicker && this.closeOnClickOutside) {
|
|
61
|
+
if (this.mostrarDatePicker() && this.closeOnClickOutside) {
|
|
46
62
|
const clickedInside = this.elementRef.nativeElement.contains(event.target);
|
|
47
63
|
if (!clickedInside) {
|
|
48
64
|
this.cerrarDatePicker();
|
|
@@ -62,7 +78,7 @@ export class DualDatepickerComponent {
|
|
|
62
78
|
this.generarCalendarios();
|
|
63
79
|
}
|
|
64
80
|
else if (!this.fechaInicio && !this.fechaFin) {
|
|
65
|
-
this.rangoFechas
|
|
81
|
+
this.rangoFechas.set('');
|
|
66
82
|
}
|
|
67
83
|
}
|
|
68
84
|
}
|
|
@@ -83,26 +99,29 @@ export class DualDatepickerComponent {
|
|
|
83
99
|
if (this.fechaInicio && this.fechaFin) {
|
|
84
100
|
const inicio = this.formatearFechaDisplay(this.fechaInicio);
|
|
85
101
|
const fin = this.formatearFechaDisplay(this.fechaFin);
|
|
86
|
-
this.rangoFechas
|
|
102
|
+
this.rangoFechas.set(`${inicio} - ${fin}`);
|
|
87
103
|
}
|
|
88
104
|
else {
|
|
89
|
-
this.rangoFechas
|
|
105
|
+
this.rangoFechas.set('');
|
|
90
106
|
}
|
|
91
107
|
}
|
|
92
108
|
toggleDatePicker() {
|
|
93
|
-
this.mostrarDatePicker
|
|
94
|
-
if (this.mostrarDatePicker) {
|
|
95
|
-
this.fechaSeleccionandoInicio
|
|
96
|
-
|
|
109
|
+
this.mostrarDatePicker.update(value => !value);
|
|
110
|
+
if (this.mostrarDatePicker()) {
|
|
111
|
+
this.fechaSeleccionandoInicio.set(true);
|
|
112
|
+
const mesActualValue = this.mesActual();
|
|
113
|
+
this.mesAnterior.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() - 1, 1));
|
|
97
114
|
this.generarCalendarios();
|
|
98
115
|
}
|
|
116
|
+
this.onTouched();
|
|
99
117
|
}
|
|
100
118
|
cerrarDatePicker() {
|
|
101
|
-
this.mostrarDatePicker
|
|
119
|
+
this.mostrarDatePicker.set(false);
|
|
120
|
+
this.onTouched();
|
|
102
121
|
}
|
|
103
122
|
generarCalendarios() {
|
|
104
|
-
this.diasMesAnterior
|
|
105
|
-
this.diasMesActual
|
|
123
|
+
this.diasMesAnterior.set(this.generarCalendarioMes(this.mesAnterior()));
|
|
124
|
+
this.diasMesActual.set(this.generarCalendarioMes(this.mesActual()));
|
|
106
125
|
}
|
|
107
126
|
generarCalendarioMes(fecha) {
|
|
108
127
|
const año = fecha.getFullYear();
|
|
@@ -135,13 +154,13 @@ export class DualDatepickerComponent {
|
|
|
135
154
|
return fechaStr >= this.fechaInicio && fechaStr <= this.fechaFin;
|
|
136
155
|
}
|
|
137
156
|
seleccionarDia(diaObj) {
|
|
138
|
-
if (!diaObj.esMesActual)
|
|
157
|
+
if (!diaObj.esMesActual || this.isDisabled())
|
|
139
158
|
return;
|
|
140
|
-
if (this.fechaSeleccionandoInicio) {
|
|
159
|
+
if (this.fechaSeleccionandoInicio()) {
|
|
141
160
|
this.fechaInicio = diaObj.fecha;
|
|
142
161
|
this.fechaFin = '';
|
|
143
|
-
this.rangoFechas
|
|
144
|
-
this.fechaSeleccionandoInicio
|
|
162
|
+
this.rangoFechas.set('');
|
|
163
|
+
this.fechaSeleccionandoInicio.set(false);
|
|
145
164
|
this.emitirCambio();
|
|
146
165
|
}
|
|
147
166
|
else {
|
|
@@ -154,17 +173,19 @@ export class DualDatepickerComponent {
|
|
|
154
173
|
}
|
|
155
174
|
this.actualizarRangoFechasTexto();
|
|
156
175
|
if (this.closeOnSelection) {
|
|
157
|
-
this.mostrarDatePicker
|
|
176
|
+
this.mostrarDatePicker.set(false);
|
|
158
177
|
}
|
|
159
|
-
this.fechaSeleccionandoInicio
|
|
178
|
+
this.fechaSeleccionandoInicio.set(true);
|
|
160
179
|
this.emitirCambio();
|
|
161
180
|
this.emitirSeleccion();
|
|
162
181
|
}
|
|
163
182
|
this.generarCalendarios();
|
|
164
183
|
}
|
|
165
184
|
cambiarMes(direccion) {
|
|
166
|
-
|
|
167
|
-
this.
|
|
185
|
+
const mesActualValue = this.mesActual();
|
|
186
|
+
this.mesActual.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() + direccion, 1));
|
|
187
|
+
const nuevoMesActual = this.mesActual();
|
|
188
|
+
this.mesAnterior.set(new Date(nuevoMesActual.getFullYear(), nuevoMesActual.getMonth() - 1, 1));
|
|
168
189
|
this.generarCalendarios();
|
|
169
190
|
}
|
|
170
191
|
getNombreMes(fecha) {
|
|
@@ -183,38 +204,83 @@ export class DualDatepickerComponent {
|
|
|
183
204
|
this.actualizarRangoFechasTexto();
|
|
184
205
|
this.generarCalendarios();
|
|
185
206
|
if (this.closeOnPresetSelection) {
|
|
186
|
-
this.mostrarDatePicker
|
|
207
|
+
this.mostrarDatePicker.set(false);
|
|
187
208
|
}
|
|
188
209
|
this.emitirSeleccion();
|
|
189
210
|
}
|
|
190
211
|
limpiar() {
|
|
191
212
|
this.fechaInicio = '';
|
|
192
213
|
this.fechaFin = '';
|
|
193
|
-
this.rangoFechas
|
|
194
|
-
this.mostrarDatePicker
|
|
195
|
-
this.fechaSeleccionandoInicio
|
|
214
|
+
this.rangoFechas.set('');
|
|
215
|
+
this.mostrarDatePicker.set(false);
|
|
216
|
+
this.fechaSeleccionandoInicio.set(true);
|
|
196
217
|
this.emitirCambio();
|
|
218
|
+
this.onTouched();
|
|
197
219
|
}
|
|
198
220
|
emitirCambio() {
|
|
199
221
|
this.dateRangeChange.emit({
|
|
200
222
|
fechaInicio: this.fechaInicio,
|
|
201
223
|
fechaFin: this.fechaFin,
|
|
202
|
-
rangoTexto: this.rangoFechas
|
|
224
|
+
rangoTexto: this.rangoFechas()
|
|
203
225
|
});
|
|
204
226
|
}
|
|
205
227
|
emitirSeleccion() {
|
|
206
228
|
this.dateRangeSelected.emit({
|
|
207
229
|
fechaInicio: this.fechaInicio,
|
|
208
230
|
fechaFin: this.fechaFin,
|
|
209
|
-
rangoTexto: this.rangoFechas
|
|
231
|
+
rangoTexto: this.rangoFechas()
|
|
210
232
|
});
|
|
211
233
|
}
|
|
234
|
+
getDateRangeValue() {
|
|
235
|
+
return {
|
|
236
|
+
fechaInicio: this.fechaInicio,
|
|
237
|
+
fechaFin: this.fechaFin,
|
|
238
|
+
rangoTexto: this.rangoFechas()
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
// ControlValueAccessor implementation
|
|
242
|
+
writeValue(value) {
|
|
243
|
+
if (value) {
|
|
244
|
+
this.fechaInicio = value.fechaInicio || '';
|
|
245
|
+
this.fechaFin = value.fechaFin || '';
|
|
246
|
+
if (this.fechaInicio && this.fechaFin) {
|
|
247
|
+
this.actualizarRangoFechasTexto();
|
|
248
|
+
this.generarCalendarios();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
this.fechaInicio = '';
|
|
253
|
+
this.fechaFin = '';
|
|
254
|
+
this.rangoFechas.set('');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
registerOnChange(fn) {
|
|
258
|
+
this.onChange = fn;
|
|
259
|
+
}
|
|
260
|
+
registerOnTouched(fn) {
|
|
261
|
+
this.onTouched = fn;
|
|
262
|
+
}
|
|
263
|
+
setDisabledState(isDisabled) {
|
|
264
|
+
this.isDisabled.set(isDisabled);
|
|
265
|
+
}
|
|
212
266
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DualDatepickerComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
213
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DualDatepickerComponent, isStandalone: true, selector: "ngx-dual-datepicker", inputs: { placeholder: "placeholder", fechaInicio: "fechaInicio", fechaFin: "fechaFin", showPresets: "showPresets", showClearButton: "showClearButton", closeOnSelection: "closeOnSelection", closeOnPresetSelection: "closeOnPresetSelection", closeOnClickOutside: "closeOnClickOutside", presets: "presets", inputBackgroundColor: "inputBackgroundColor", inputTextColor: "inputTextColor", inputBorderColor: "inputBorderColor", inputBorderColorHover: "inputBorderColorHover", inputBorderColorFocus: "inputBorderColorFocus", inputPadding: "inputPadding", locale: "locale" }, outputs: { dateRangeChange: "dateRangeChange", dateRangeSelected: "dateRangeSelected" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ getNombreMes(mesAnterior) }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of getDayNames(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior; track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ getNombreMes(mesActual) }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of getDayNames(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual; track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".datepicker-wrapper{position:relative;width:100%}.datepicker-wrapper .datepicker-input{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;cursor:pointer}.datepicker-wrapper .datepicker-input:hover{border-color:var(--input-border-hover, #ced4da)}.datepicker-wrapper .datepicker-input:focus{border-color:var(--input-border-focus, #80bdff);box-shadow:0 0 0 .2rem #007bff40;outline:0}.datepicker-wrapper .datepicker-input::placeholder{color:#6c757d;opacity:1}.datepicker-wrapper .datepicker-input:disabled,.datepicker-wrapper .datepicker-input[readonly]{background-color:#e9ecef;opacity:1}.date-picker-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e1e4e8;border-radius:8px;box-shadow:0 4px 12px #00000014,0 0 1px #00000014;padding:16px;z-index:1060;min-width:680px}@media (max-width: 768px){.date-picker-dropdown{min-width:100%;left:0;right:0}}.date-picker-header-only-close{display:flex;justify-content:flex-end;margin-bottom:12px}.date-picker-header-only-close .btn-close-calendar{background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;border-radius:6px;cursor:pointer;transition:all .15s ease;font-size:1.5rem;line-height:1}.date-picker-header-only-close .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-header-only-close .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-presets{display:flex;gap:6px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #e5e7eb;align-items:center}@media (max-width: 768px){.date-picker-presets{flex-wrap:wrap}}.date-picker-presets button{font-size:.75rem;padding:6px 14px;border:none;background-color:#f9fafb;color:#374151;border-radius:6px;transition:all .15s ease;font-weight:500;cursor:pointer;border:1px solid #e5e7eb}.date-picker-presets button:hover{background-color:#f3f4f6;border-color:#d1d5db;transform:translateY(-1px);box-shadow:0 2px 4px #0000000f}.date-picker-presets button:active{transform:translateY(0);box-shadow:none}.date-picker-presets .btn-close-calendar{margin-left:auto;background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;font-size:1.5rem;line-height:1}.date-picker-presets .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-presets .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-calendars{display:flex;gap:32px}@media (max-width: 768px){.date-picker-calendars{flex-direction:column;gap:16px}}.date-picker-calendar{flex:1}.date-picker-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding:0 4px}.date-picker-header span{font-size:.813rem;font-weight:600;color:#111827}.date-picker-header button{padding:4px;color:#6b7280;text-decoration:none;border-radius:6px;transition:all .15s ease;border:none;background:transparent;cursor:pointer}.date-picker-header button:hover{background-color:#f3f4f6;color:#111827}.date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.date-picker-weekdays span{text-align:center;font-size:.625rem;font-weight:600;color:#6b7280;padding:6px}.date-picker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.date-picker-day{aspect-ratio:1;border:none;background:transparent;border-radius:50%;font-size:.75rem;cursor:pointer;transition:all .15s ease;color:#374151;font-weight:400}.date-picker-day:hover:not(:disabled):not(.selected){background-color:#f3f4f6;color:#111827}.date-picker-day.empty{visibility:hidden}.date-picker-day.selected{background-color:#222;color:#fff;font-weight:600}.date-picker-day.in-range{background-color:#f9fafb;border-radius:0}.date-picker-day:disabled{cursor:not-allowed;opacity:.3}.date-picker-footer{padding:12px;border-top:1px solid #e1e4e8;display:flex;justify-content:center;gap:8px}.date-picker-footer .btn-clear{padding:8px 16px;background-color:#f6f8fa;border:1px solid #d0d7de;border-radius:6px;font-size:.875rem;font-weight:500;color:#24292f;cursor:pointer;transition:all .15s ease}.date-picker-footer .btn-clear:hover{background-color:#f3f4f6;border-color:#8c959f;transform:translateY(-1px);box-shadow:0 2px 4px #0000000d}.date-picker-footer .btn-clear:active{transform:translateY(0);box-shadow:none;background-color:#e9ecef}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }] });
|
|
267
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DualDatepickerComponent, isStandalone: true, selector: "ngx-dual-datepicker", inputs: { placeholder: "placeholder", fechaInicio: "fechaInicio", fechaFin: "fechaFin", showPresets: "showPresets", showClearButton: "showClearButton", closeOnSelection: "closeOnSelection", closeOnPresetSelection: "closeOnPresetSelection", closeOnClickOutside: "closeOnClickOutside", presets: "presets", inputBackgroundColor: "inputBackgroundColor", inputTextColor: "inputTextColor", inputBorderColor: "inputBorderColor", inputBorderColorHover: "inputBorderColorHover", inputBorderColorFocus: "inputBorderColorFocus", inputPadding: "inputPadding", locale: "locale" }, outputs: { dateRangeChange: "dateRangeChange", dateRangeSelected: "dateRangeSelected" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
|
|
268
|
+
{
|
|
269
|
+
provide: NG_VALUE_ACCESSOR,
|
|
270
|
+
useExisting: forwardRef(() => DualDatepickerComponent),
|
|
271
|
+
multi: true
|
|
272
|
+
}
|
|
273
|
+
], usesOnChanges: true, ngImport: i0, template: "<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas()\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [disabled]=\"isDisabled()\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker()) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesAnterior() }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesActual() }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".datepicker-wrapper{position:relative;width:100%}.datepicker-wrapper .datepicker-input{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;cursor:pointer}.datepicker-wrapper .datepicker-input:hover{border-color:var(--input-border-hover, #ced4da)}.datepicker-wrapper .datepicker-input:focus{border-color:var(--input-border-focus, #80bdff);box-shadow:0 0 0 .2rem #007bff40;outline:0}.datepicker-wrapper .datepicker-input::placeholder{color:#6c757d;opacity:1}.datepicker-wrapper .datepicker-input:disabled,.datepicker-wrapper .datepicker-input[readonly]{background-color:#e9ecef;opacity:1}.date-picker-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e1e4e8;border-radius:8px;box-shadow:0 4px 12px #00000014,0 0 1px #00000014;padding:16px;z-index:1060;min-width:680px}@media (max-width: 768px){.date-picker-dropdown{min-width:100%;left:0;right:0}}.date-picker-header-only-close{display:flex;justify-content:flex-end;margin-bottom:12px}.date-picker-header-only-close .btn-close-calendar{background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;border-radius:6px;cursor:pointer;transition:all .15s ease;font-size:1.5rem;line-height:1}.date-picker-header-only-close .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-header-only-close .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-presets{display:flex;gap:6px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #e5e7eb;align-items:center}@media (max-width: 768px){.date-picker-presets{flex-wrap:wrap}}.date-picker-presets button{font-size:.75rem;padding:6px 14px;border:none;background-color:#f9fafb;color:#374151;border-radius:6px;transition:all .15s ease;font-weight:500;cursor:pointer;border:1px solid #e5e7eb}.date-picker-presets button:hover{background-color:#f3f4f6;border-color:#d1d5db;transform:translateY(-1px);box-shadow:0 2px 4px #0000000f}.date-picker-presets button:active{transform:translateY(0);box-shadow:none}.date-picker-presets .btn-close-calendar{margin-left:auto;background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;font-size:1.5rem;line-height:1}.date-picker-presets .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-presets .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-calendars{display:flex;gap:32px}@media (max-width: 768px){.date-picker-calendars{flex-direction:column;gap:16px}}.date-picker-calendar{flex:1}.date-picker-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding:0 4px}.date-picker-header span{font-size:.813rem;font-weight:600;color:#111827}.date-picker-header button{padding:4px;color:#6b7280;text-decoration:none;border-radius:6px;transition:all .15s ease;border:none;background:transparent;cursor:pointer}.date-picker-header button:hover{background-color:#f3f4f6;color:#111827}.date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.date-picker-weekdays span{text-align:center;font-size:.625rem;font-weight:600;color:#6b7280;padding:6px}.date-picker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.date-picker-day{aspect-ratio:1;border:none;background:transparent;border-radius:50%;font-size:.75rem;cursor:pointer;transition:all .15s ease;color:#374151;font-weight:400}.date-picker-day:hover:not(:disabled):not(.selected){background-color:#f3f4f6;color:#111827}.date-picker-day.empty{visibility:hidden}.date-picker-day.selected{background-color:#222;color:#fff;font-weight:600}.date-picker-day.in-range{background-color:#f9fafb;border-radius:0}.date-picker-day:disabled{cursor:not-allowed;opacity:.3}.date-picker-footer{padding:12px;border-top:1px solid #e1e4e8;display:flex;justify-content:center;gap:8px}.date-picker-footer .btn-clear{padding:8px 16px;background-color:#f6f8fa;border:1px solid #d0d7de;border-radius:6px;font-size:.875rem;font-weight:500;color:#24292f;cursor:pointer;transition:all .15s ease}.date-picker-footer .btn-clear:hover{background-color:#f3f4f6;border-color:#8c959f;transform:translateY(-1px);box-shadow:0 2px 4px #0000000d}.date-picker-footer .btn-clear:active{transform:translateY(0);box-shadow:none;background-color:#e9ecef}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
|
|
214
274
|
}
|
|
215
275
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DualDatepickerComponent, decorators: [{
|
|
216
276
|
type: Component,
|
|
217
|
-
args: [{ selector: 'ngx-dual-datepicker', standalone: true, imports: [CommonModule, FormsModule
|
|
277
|
+
args: [{ selector: 'ngx-dual-datepicker', standalone: true, imports: [CommonModule, FormsModule, ReactiveFormsModule], providers: [
|
|
278
|
+
{
|
|
279
|
+
provide: NG_VALUE_ACCESSOR,
|
|
280
|
+
useExisting: forwardRef(() => DualDatepickerComponent),
|
|
281
|
+
multi: true
|
|
282
|
+
}
|
|
283
|
+
], template: "<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas()\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [disabled]=\"isDisabled()\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker()) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesAnterior() }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesActual() }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".datepicker-wrapper{position:relative;width:100%}.datepicker-wrapper .datepicker-input{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;cursor:pointer}.datepicker-wrapper .datepicker-input:hover{border-color:var(--input-border-hover, #ced4da)}.datepicker-wrapper .datepicker-input:focus{border-color:var(--input-border-focus, #80bdff);box-shadow:0 0 0 .2rem #007bff40;outline:0}.datepicker-wrapper .datepicker-input::placeholder{color:#6c757d;opacity:1}.datepicker-wrapper .datepicker-input:disabled,.datepicker-wrapper .datepicker-input[readonly]{background-color:#e9ecef;opacity:1}.date-picker-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e1e4e8;border-radius:8px;box-shadow:0 4px 12px #00000014,0 0 1px #00000014;padding:16px;z-index:1060;min-width:680px}@media (max-width: 768px){.date-picker-dropdown{min-width:100%;left:0;right:0}}.date-picker-header-only-close{display:flex;justify-content:flex-end;margin-bottom:12px}.date-picker-header-only-close .btn-close-calendar{background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;border-radius:6px;cursor:pointer;transition:all .15s ease;font-size:1.5rem;line-height:1}.date-picker-header-only-close .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-header-only-close .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-presets{display:flex;gap:6px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #e5e7eb;align-items:center}@media (max-width: 768px){.date-picker-presets{flex-wrap:wrap}}.date-picker-presets button{font-size:.75rem;padding:6px 14px;border:none;background-color:#f9fafb;color:#374151;border-radius:6px;transition:all .15s ease;font-weight:500;cursor:pointer;border:1px solid #e5e7eb}.date-picker-presets button:hover{background-color:#f3f4f6;border-color:#d1d5db;transform:translateY(-1px);box-shadow:0 2px 4px #0000000f}.date-picker-presets button:active{transform:translateY(0);box-shadow:none}.date-picker-presets .btn-close-calendar{margin-left:auto;background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;font-size:1.5rem;line-height:1}.date-picker-presets .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-presets .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-calendars{display:flex;gap:32px}@media (max-width: 768px){.date-picker-calendars{flex-direction:column;gap:16px}}.date-picker-calendar{flex:1}.date-picker-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding:0 4px}.date-picker-header span{font-size:.813rem;font-weight:600;color:#111827}.date-picker-header button{padding:4px;color:#6b7280;text-decoration:none;border-radius:6px;transition:all .15s ease;border:none;background:transparent;cursor:pointer}.date-picker-header button:hover{background-color:#f3f4f6;color:#111827}.date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.date-picker-weekdays span{text-align:center;font-size:.625rem;font-weight:600;color:#6b7280;padding:6px}.date-picker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.date-picker-day{aspect-ratio:1;border:none;background:transparent;border-radius:50%;font-size:.75rem;cursor:pointer;transition:all .15s ease;color:#374151;font-weight:400}.date-picker-day:hover:not(:disabled):not(.selected){background-color:#f3f4f6;color:#111827}.date-picker-day.empty{visibility:hidden}.date-picker-day.selected{background-color:#222;color:#fff;font-weight:600}.date-picker-day.in-range{background-color:#f9fafb;border-radius:0}.date-picker-day:disabled{cursor:not-allowed;opacity:.3}.date-picker-footer{padding:12px;border-top:1px solid #e1e4e8;display:flex;justify-content:center;gap:8px}.date-picker-footer .btn-clear{padding:8px 16px;background-color:#f6f8fa;border:1px solid #d0d7de;border-radius:6px;font-size:.875rem;font-weight:500;color:#24292f;cursor:pointer;transition:all .15s ease}.date-picker-footer .btn-clear:hover{background-color:#f3f4f6;border-color:#8c959f;transform:translateY(-1px);box-shadow:0 2px 4px #0000000d}.date-picker-footer .btn-clear:active{transform:translateY(0);box-shadow:none;background-color:#e9ecef}\n"] }]
|
|
218
284
|
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { placeholder: [{
|
|
219
285
|
type: Input
|
|
220
286
|
}], fechaInicio: [{
|
|
@@ -255,4 +321,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
255
321
|
type: HostListener,
|
|
256
322
|
args: ['document:click', ['$event']]
|
|
257
323
|
}] } });
|
|
258
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHVhbC1kYXRlcGlja2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kdWFsLWRhdGVwaWNrZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vc3JjL2R1YWwtZGF0ZXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFvQyxZQUFZLEVBQWMsTUFBTSxlQUFlLENBQUM7QUFDbkksT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBNEI3QyxNQUFNLE9BQU8sdUJBQXVCO0lBc0NkO0lBckNYLFdBQVcsR0FBVyxtQkFBbUIsQ0FBQztJQUMxQyxXQUFXLEdBQVcsRUFBRSxDQUFDO0lBQ3pCLFFBQVEsR0FBVyxFQUFFLENBQUM7SUFDdEIsV0FBVyxHQUFZLElBQUksQ0FBQztJQUM1QixlQUFlLEdBQVksSUFBSSxDQUFDO0lBQ2hDLGdCQUFnQixHQUFZLElBQUksQ0FBQztJQUNqQyxzQkFBc0IsR0FBWSxJQUFJLENBQUM7SUFDdkMsbUJBQW1CLEdBQVksSUFBSSxDQUFDO0lBQ3BDLE9BQU8sR0FBbUI7UUFDakMsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUU7UUFDcEMsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUU7UUFDeEMsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUU7S0FDckMsQ0FBQztJQUNPLG9CQUFvQixHQUFXLE1BQU0sQ0FBQztJQUN0QyxjQUFjLEdBQVcsU0FBUyxDQUFDO0lBQ25DLGdCQUFnQixHQUFXLFNBQVMsQ0FBQztJQUNyQyxxQkFBcUIsR0FBVyxTQUFTLENBQUM7SUFDMUMscUJB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c0I7c0JBQTlCLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFLRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0cscUJBQXFCO3NCQUE3QixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFFSSxlQUFlO3NCQUF4QixNQUFNO2dCQUNHLGlCQUFpQjtzQkFBMUIsTUFBTTtnQkFrQlAsY0FBYztzQkFEYixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIE9uSW5pdCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBIb3N0TGlzdGVuZXIsIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuZXhwb3J0IGludGVyZmFjZSBEYXRlUmFuZ2Uge1xuICBmZWNoYUluaWNpbzogc3RyaW5nO1xuICBmZWNoYUZpbjogc3RyaW5nO1xuICByYW5nb1RleHRvOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJlc2V0Q29uZmlnIHtcbiAgbGFiZWw6IHN0cmluZztcbiAgZGF5c0FnbzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExvY2FsZUNvbmZpZyB7XG4gIG1vbnRoTmFtZXM/OiBzdHJpbmdbXTtcbiAgbW9udGhOYW1lc1Nob3J0Pzogc3RyaW5nW107XG4gIGRheU5hbWVzPzogc3RyaW5nW107XG4gIGRheU5hbWVzU2hvcnQ/OiBzdHJpbmdbXTtcbiAgZmlyc3REYXlPZldlZWs/OiBudW1iZXI7IC8vIDAgPSBTdW5kYXksIDEgPSBNb25kYXksIGV0Yy5cbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWR1YWwtZGF0ZXBpY2tlcicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2R1YWwtZGF0ZXBpY2tlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9kdWFsLWRhdGVwaWNrZXIuY29tcG9uZW50LnNjc3MnXG59KVxuZXhwb3J0IGNsYXNzIER1YWxEYXRlcGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJ1NlbGVjdCBkYXRlIHJhbmdlJztcbiAgQElucHV0KCkgZmVjaGFJbmljaW86IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBmZWNoYUZpbjogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIHNob3dQcmVzZXRzOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgc2hvd0NsZWFyQnV0dG9uOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgY2xvc2VPblNlbGVjdGlvbjogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGNsb3NlT25QcmVzZXRTZWxlY3Rpb246IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBjbG9zZU9uQ2xpY2tPdXRzaWRlOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgcHJlc2V0czogUHJlc2V0Q29uZmlnW10gPSBbXG4gICAgeyBsYWJlbDogJ0xhc3QgbW9udGgnLCBkYXlzQWdvOiAzMCB9LFxuICAgIHsgbGFiZWw6ICdMYXN0IDYgbW9udGhzJywgZGF5c0FnbzogMTgwIH0sXG4gICAgeyBsYWJlbDogJ0xhc3QgeWVhcicsIGRheXNBZ286IDM2NSB9XG4gIF07XG4gIEBJbnB1dCgpIGlucHV0QmFja2dyb3VuZENvbG9yOiBzdHJpbmcgPSAnI2ZmZic7XG4gIEBJbnB1dCgpIGlucHV0VGV4dENvbG9yOiBzdHJpbmcgPSAnIzQ5NTA1Nyc7XG4gIEBJbnB1dCgpIGlucHV0Qm9yZGVyQ29sb3I6IHN0cmluZyA9ICcjY2VkNGRhJztcbiAgQElucHV0KCkgaW5wdXRCb3JkZXJDb2xvckhvdmVyOiBzdHJpbmcgPSAnI2NlZDRkYSc7XG4gIEBJbnB1dCgpIGlucHV0Qm9yZGVyQ29sb3JGb2N1czogc3RyaW5nID0gJyM4MGJkZmYnO1xuICBASW5wdXQoKSBpbnB1dFBhZGRpbmc6IHN0cmluZyA9ICcwLjM3NXJlbSAwLjc1cmVtJztcbiAgQElucHV0KCkgbG9jYWxlOiBMb2NhbGVDb25maWcgPSB7fTtcblxuICBAT3V0cHV0KCkgZGF0ZVJhbmdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRlUmFuZ2U+KCk7XG4gIEBPdXRwdXQoKSBkYXRlUmFuZ2VTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0ZVJhbmdlPigpO1xuXG4gIG1vc3RyYXJEYXRlUGlja2VyID0gZmFsc2U7XG4gIHJhbmdvRmVjaGFzID0gJyc7XG4gIGZlY2hhU2VsZWNjaW9uYW5kb0luaWNpbyA9IHRydWU7XG4gIG1lc0FjdHVhbCA9IG5ldyBEYXRlKCk7XG4gIG1lc0FudGVyaW9yID0gbmV3IERhdGUoKTtcbiAgZGlhc01lc0FjdHVhbDogYW55W10gPSBbXTtcbiAgZGlhc01lc0FudGVyaW9yOiBhbnlbXSA9IFtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdE1vbnRoTmFtZXMgPSBbJ0phbnVhcnknLCAnRmVicnVhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLCAnSnVseScsICdBdWd1c3QnLCAnU2VwdGVtYmVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0TW9udGhOYW1lc1Nob3J0ID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHREYXlOYW1lcyA9IFsnU3VuZGF5JywgJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknXTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0RGF5TmFtZXNTaG9ydCA9IFsnUycsICdNJywgJ1QnLCAnVycsICdUJywgJ0YnLCAnUyddO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZikge31cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXG4gIG9uQ2xpY2tPdXRzaWRlKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMubW9zdHJhckRhdGVQaWNrZXIgJiYgdGhpcy5jbG9zZU9uQ2xpY2tPdXRzaWRlKSB7XG4gICAgICBjb25zdCBjbGlja2VkSW5zaWRlID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0KTtcbiAgICAgIGlmICghY2xpY2tlZEluc2lkZSkge1xuICAgICAgICB0aGlzLmNlcnJhckRhdGVQaWNrZXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mZWNoYUluaWNpbyAmJiB0aGlzLmZlY2hhRmluKSB7XG4gICAgICB0aGlzLmFjdHVhbGl6YXJSYW5nb0ZlY2hhc1RleHRvKCk7XG4gICAgICB0aGlzLmdlbmVyYXJDYWxlbmRhcmlvcygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snZmVjaGFJbmljaW8nXSB8fCBjaGFuZ2VzWydmZWNoYUZpbiddKSB7XG4gICAgICBpZiAodGhpcy5mZWNoYUluaWNpbyAmJiB0aGlzLmZlY2hhRmluKSB7XG4gICAgICAgIHRoaXMuYWN0dWFsaXphclJhbmdvRmVjaGFzVGV4dG8oKTtcbiAgICAgICAgdGhpcy5nZW5lcmFyQ2FsZW5kYXJpb3MoKTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuZmVjaGFJbmljaW8gJiYgIXRoaXMuZmVjaGFGaW4pIHtcbiAgICAgICAgdGhpcy5yYW5nb0ZlY2hhcyA9ICcnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZvcm1hdGVhckZlY2hhKGZlY2hhOiBEYXRlKTogc3RyaW5nIHtcbiAgICBjb25zdCB5ZWFyID0gZmVjaGEuZ2V0RnVsbFllYXIoKTtcbiAgICBjb25zdCBtb250aCA9IFN0cmluZyhmZWNoYS5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCBkYXkgPSBTdHJpbmcoZmVjaGEuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIHJldHVybiBgJHt5ZWFyfS0ke21vbnRofS0ke2RheX1gO1xuICB9XG5cbiAgZm9ybWF0ZWFyRmVjaGFEaXNwbGF5KGZlY2hhU3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghZmVjaGFTdHIpIHJldHVybiAnJztcbiAgICBjb25zdCBmZWNoYSA9IG5ldyBEYXRlKGZlY2hhU3RyICsgJ1QwMDowMDowMCcpO1xuICAgIGNvbnN0IG1vbnRoTmFtZXMgPSB0aGlzLmxvY2FsZS5tb250aE5hbWVzU2hvcnQgfHwgdGhpcy5kZWZhdWx0TW9udGhOYW1lc1Nob3J0O1xuICAgIHJldHVybiBgJHtmZWNoYS5nZXREYXRlKCl9ICR7bW9udGhOYW1lc1tmZWNoYS5nZXRNb250aCgpXX1gO1xuICB9XG5cbiAgYWN0dWFsaXphclJhbmdvRmVjaGFzVGV4dG8oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZmVjaGFJbmljaW8gJiYgdGhpcy5mZWNoYUZpbikge1xuICAgICAgY29uc3QgaW5pY2lvID0gdGhpcy5mb3JtYXRlYXJGZWNoYURpc3BsYXkodGhpcy5mZWNoYUluaWNpbyk7XG4gICAgICBjb25zdCBmaW4gPSB0aGlzLmZvcm1hdGVhckZlY2hhRGlzcGxheSh0aGlzLmZlY2hhRmluKTtcbiAgICAgIHRoaXMucmFuZ29GZWNoYXMgPSBgJHtpbmljaW99IC0gJHtmaW59YDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yYW5nb0ZlY2hhcyA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZURhdGVQaWNrZXIoKTogdm9pZCB7XG4gICAgdGhpcy5tb3N0cmFyRGF0ZVBpY2tlciA9ICF0aGlzLm1vc3RyYXJEYXRlUGlja2VyO1xuICAgIGlmICh0aGlzLm1vc3RyYXJEYXRlUGlja2VyKSB7XG4gICAgICB0aGlzLmZlY2hhU2VsZWNjaW9uYW5kb0luaWNpbyA9IHRydWU7XG4gICAgICB0aGlzLm1lc0FudGVyaW9yID0gbmV3IERhdGUodGhpcy5tZXNBY3R1YWwuZ2V0RnVsbFllYXIoKSwgdGhpcy5tZXNBY3R1YWwuZ2V0TW9udGgoKSAtIDEsIDEpO1xuICAgICAgdGhpcy5nZW5lcmFyQ2FsZW5kYXJpb3MoKTtcbiAgICB9XG4gIH1cblxuICBjZXJyYXJEYXRlUGlja2VyKCk6IHZvaWQge1xuICAgIHRoaXMubW9zdHJhckRhdGVQaWNrZXIgPSBmYWxzZTtcbiAgfVxuXG4gIGdlbmVyYXJDYWxlbmRhcmlvcygpOiB2b2lkIHtcbiAgICB0aGlzLmRpYXNNZXNBbnRlcmlvciA9IHRoaXMuZ2VuZXJhckNhbGVuZGFyaW9NZXModGhpcy5tZXNBbnRlcmlvcik7XG4gICAgdGhpcy5kaWFzTWVzQWN0dWFsID0gdGhpcy5nZW5lcmFyQ2FsZW5kYXJpb01lcyh0aGlzLm1lc0FjdHVhbCk7XG4gIH1cblxuICBnZW5lcmFyQ2FsZW5kYXJpb01lcyhmZWNoYTogRGF0ZSk6IGFueVtdIHtcbiAgICBjb25zdCBhw7FvID0gZmVjaGEuZ2V0RnVsbFllYXIoKTtcbiAgICBjb25zdCBtZXMgPSBmZWNoYS5nZXRNb250aCgpO1xuICAgIGNvbnN0IHByaW1lckRpYSA9IG5ldyBEYXRlKGHDsW8sIG1lcywgMSk7XG4gICAgY29uc3QgdWx0aW1vRGlhID0gbmV3IERhdGUoYcOxbywgbWVzICsgMSwgMCk7XG4gICAgY29uc3QgZGlhc0VuTWVzID0gdWx0aW1vRGlhLmdldERhdGUoKTtcbiAgICBjb25zdCBwcmltZXJEaWFTZW1hbmEgPSBwcmltZXJEaWEuZ2V0RGF5KCk7XG5cbiAgICBjb25zdCBkaWFzTWVzID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByaW1lckRpYVNlbWFuYTsgaSsrKSB7XG4gICAgICBkaWFzTWVzLnB1c2goeyBkaWE6IG51bGwsIGVzTWVzQWN0dWFsOiBmYWxzZSB9KTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBkaWEgPSAxOyBkaWEgPD0gZGlhc0VuTWVzOyBkaWErKykge1xuICAgICAgY29uc3QgZmVjaGFEaWEgPSBuZXcgRGF0ZShhw7FvLCBtZXMsIGRpYSk7XG4gICAgICBjb25zdCBmZWNoYVN0ciA9IHRoaXMuZm9ybWF0ZWFyRmVjaGEoZmVjaGFEaWEpO1xuICAgICAgZGlhc01lcy5wdXNoKHtcbiAgICAgICAgZGlhOiBkaWEsXG4gICAgICAgIGZlY2hhOiBmZWNoYVN0cixcbiAgICAgICAgZXNNZXNBY3R1YWw6IHRydWUsXG4gICAgICAgIGVzSW5pY2lvOiB0aGlzLmZlY2hhSW5pY2lvID09PSBmZWNoYVN0cixcbiAgICAgICAgZXNGaW46IHRoaXMuZmVjaGFGaW4gPT09IGZlY2hhU3RyLFxuICAgICAgICBlblJhbmdvOiB0aGlzLmVzdGFFblJhbmdvKGZlY2hhU3RyKVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRpYXNNZXM7XG4gIH1cblxuICBlc3RhRW5SYW5nbyhmZWNoYVN0cjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmZlY2hhSW5pY2lvIHx8ICF0aGlzLmZlY2hhRmluKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIGZlY2hhU3RyID49IHRoaXMuZmVjaGFJbmljaW8gJiYgZmVjaGFTdHIgPD0gdGhpcy5mZWNoYUZpbjtcbiAgfVxuXG4gIHNlbGVjY2lvbmFyRGlhKGRpYU9iajogYW55KTogdm9pZCB7XG4gICAgaWYgKCFkaWFPYmouZXNNZXNBY3R1YWwpIHJldHVybjtcblxuICAgIGlmICh0aGlzLmZlY2hhU2VsZWNjaW9uYW5kb0luaWNpbykge1xuICAgICAgdGhpcy5mZWNoYUluaWNpbyA9IGRpYU9iai5mZWNoYTtcbiAgICAgIHRoaXMuZmVjaGFGaW4gPSAnJztcbiAgICAgIHRoaXMucmFuZ29GZWNoYXMgPSAnJztcbiAgICAgIHRoaXMuZmVjaGFTZWxlY2Npb25hbmRvSW5pY2lvID0gZmFsc2U7XG4gICAgICB0aGlzLmVtaXRpckNhbWJpbygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZGlhT2JqLmZlY2hhIDwgdGhpcy5mZWNoYUluaWNpbykge1xuICAgICAgICB0aGlzLmZlY2hhRmluID0gdGhpcy5mZWNoYUluaWNpbztcbiAgICAgICAgdGhpcy5mZWNoYUluaWNpbyA9IGRpYU9iai5mZWNoYTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZmVjaGFGaW4gPSBkaWFPYmouZmVjaGE7XG4gICAgICB9XG4gICAgICB0aGlzLmFjdHVhbGl6YXJSYW5nb0ZlY2hhc1RleHRvKCk7XG4gICAgICBpZiAodGhpcy5jbG9zZU9uU2VsZWN0aW9uKSB7XG4gICAgICAgIHRoaXMubW9zdHJhckRhdGVQaWNrZXIgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmVjaGFTZWxlY2Npb25hbmRvSW5pY2lvID0gdHJ1ZTtcbiAgICAgIHRoaXMuZW1pdGlyQ2FtYmlvKCk7XG4gICAgICB0aGlzLmVtaXRpclNlbGVjY2lvbigpO1xuICAgIH1cbiAgICB0aGlzLmdlbmVyYXJDYWxlbmRhcmlvcygpO1xuICB9XG5cbiAgY2FtYmlhck1lcyhkaXJlY2Npb246IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMubWVzQWN0dWFsID0gbmV3IERhdGUodGhpcy5tZXNBY3R1YWwuZ2V0RnVsbFllYXIoKSwgdGhpcy5tZXNBY3R1YWwuZ2V0TW9udGgoKSArIGRpcmVjY2lvbiwgMSk7XG4gICAgdGhpcy5tZXNBbnRlcmlvciA9IG5ldyBEYXRlKHRoaXMubWVzQWN0dWFsLmdldEZ1bGxZZWFyKCksIHRoaXMubWVzQWN0dWFsLmdldE1vbnRoKCkgLSAxLCAxKTtcbiAgICB0aGlzLmdlbmVyYXJDYWxlbmRhcmlvcygpO1xuICB9XG5cbiAgZ2V0Tm9tYnJlTWVzKGZlY2hhOiBEYXRlKTogc3RyaW5nIHtcbiAgICBjb25zdCBtb250aE5hbWVzID0gdGhpcy5sb2NhbGUubW9udGhOYW1lcyB8fCB0aGlzLmRlZmF1bHRNb250aE5hbWVzO1xuICAgIHJldHVybiBgJHttb250aE5hbWVzW2ZlY2hhLmdldE1vbnRoKCldfSAke2ZlY2hhLmdldEZ1bGxZZWFyKCl9YDtcbiAgfVxuXG4gIGdldERheU5hbWVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5sb2NhbGUuZGF5TmFtZXNTaG9ydCB8fCB0aGlzLmRlZmF1bHREYXlOYW1lc1Nob3J0O1xuICB9XG5cbiAgc2VsZWNjaW9uYXJSYW5nb1ByZWRlZmluaWRvKHByZXNldDogUHJlc2V0Q29uZmlnKTogdm9pZCB7XG4gICAgY29uc3QgaG95ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCBmZWNoYUluaWNpbyA9IG5ldyBEYXRlKGhveSk7XG4gICAgZmVjaGFJbmljaW8uc2V0RGF0ZShob3kuZ2V0RGF0ZSgpIC0gcHJlc2V0LmRheXNBZ28pO1xuXG4gICAgdGhpcy5mZWNoYUluaWNpbyA9IHRoaXMuZm9ybWF0ZWFyRmVjaGEoZmVjaGFJbmljaW8pO1xuICAgIHRoaXMuZmVjaGFGaW4gPSB0aGlzLmZvcm1hdGVhckZlY2hhKGhveSk7XG4gICAgdGhpcy5hY3R1YWxpemFyUmFuZ29GZWNoYXNUZXh0bygpO1xuICAgIHRoaXMuZ2VuZXJhckNhbGVuZGFyaW9zKCk7XG4gICAgaWYgKHRoaXMuY2xvc2VPblByZXNldFNlbGVjdGlvbikge1xuICAgICAgdGhpcy5tb3N0cmFyRGF0ZVBpY2tlciA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLmVtaXRpclNlbGVjY2lvbigpO1xuICB9XG5cbiAgbGltcGlhcigpOiB2b2lkIHtcbiAgICB0aGlzLmZlY2hhSW5pY2lvID0gJyc7XG4gICAgdGhpcy5mZWNoYUZpbiA9ICcnO1xuICAgIHRoaXMucmFuZ29GZWNoYXMgPSAnJztcbiAgICB0aGlzLm1vc3RyYXJEYXRlUGlja2VyID0gZmFsc2U7XG4gICAgdGhpcy5mZWNoYVNlbGVjY2lvbmFuZG9JbmljaW8gPSB0cnVlO1xuICAgIHRoaXMuZW1pdGlyQ2FtYmlvKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRpckNhbWJpbygpOiB2b2lkIHtcbiAgICB0aGlzLmRhdGVSYW5nZUNoYW5nZS5lbWl0KHtcbiAgICAgIGZlY2hhSW5pY2lvOiB0aGlzLmZlY2hhSW5pY2lvLFxuICAgICAgZmVjaGFGaW46IHRoaXMuZmVjaGFGaW4sXG4gICAgICByYW5nb1RleHRvOiB0aGlzLnJhbmdvRmVjaGFzXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRpclNlbGVjY2lvbigpOiB2b2lkIHtcbiAgICB0aGlzLmRhdGVSYW5nZVNlbGVjdGVkLmVtaXQoe1xuICAgICAgZmVjaGFJbmljaW86IHRoaXMuZmVjaGFJbmljaW8sXG4gICAgICBmZWNoYUZpbjogdGhpcy5mZWNoYUZpbixcbiAgICAgIHJhbmdvVGV4dG86IHRoaXMucmFuZ29GZWNoYXNcbiAgICB9KTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImRhdGVwaWNrZXItd3JhcHBlclwiIFxuICBbc3R5bGUuLS1pbnB1dC1ib3JkZXItaG92ZXJdPVwiaW5wdXRCb3JkZXJDb2xvckhvdmVyXCJcbiAgW3N0eWxlLi0taW5wdXQtYm9yZGVyLWZvY3VzXT1cImlucHV0Qm9yZGVyQ29sb3JGb2N1c1wiPlxuICA8aW5wdXQgXG4gICAgdHlwZT1cInRleHRcIiBcbiAgICBjbGFzcz1cImRhdGVwaWNrZXItaW5wdXRcIiBcbiAgICBbdmFsdWVdPVwicmFuZ29GZWNoYXNcIiBcbiAgICAoY2xpY2spPVwidG9nZ2xlRGF0ZVBpY2tlcigpXCIgXG4gICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAnYmFja2dyb3VuZC1jb2xvcic6IGlucHV0QmFja2dyb3VuZENvbG9yLFxuICAgICAgJ2NvbG9yJzogaW5wdXRUZXh0Q29sb3IsXG4gICAgICAnYm9yZGVyLWNvbG9yJzogaW5wdXRCb3JkZXJDb2xvcixcbiAgICAgICdwYWRkaW5nJzogaW5wdXRQYWRkaW5nXG4gICAgfVwiXG4gICAgcmVhZG9ubHk+XG5cbiAgQGlmIChtb3N0cmFyRGF0ZVBpY2tlcikge1xuICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItZHJvcGRvd25cIj5cbiAgICBAaWYgKHNob3dQcmVzZXRzKSB7XG4gICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLXByZXNldHNcIj5cbiAgICAgIEBmb3IgKHByZXNldCBvZiBwcmVzZXRzOyB0cmFjayBwcmVzZXQubGFiZWwpIHtcbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJzZWxlY2Npb25hclJhbmdvUHJlZGVmaW5pZG8ocHJlc2V0KVwiPnt7IHByZXNldC5sYWJlbCB9fTwvYnV0dG9uPlxuICAgICAgfVxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2UtY2FsZW5kYXJcIiAoY2xpY2spPVwiY2VycmFyRGF0ZVBpY2tlcigpXCIgdGl0bGU9XCJDbG9zZVwiPlxuICAgICAgICDDl1xuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gICAgfVxuXG4gICAgQGlmICghc2hvd1ByZXNldHMpIHtcbiAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItaGVhZGVyLW9ubHktY2xvc2VcIj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWNsb3NlLWNhbGVuZGFyXCIgKGNsaWNrKT1cImNlcnJhckRhdGVQaWNrZXIoKVwiIHRpdGxlPVwiQ2xvc2VcIj5cbiAgICAgICAgw5dcbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICAgIH1cblxuICAgIDwhLS0gQ2FsZW5kYXJzIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJkYXRlLXBpY2tlci1jYWxlbmRhcnNcIj5cbiAgICAgIDwhLS0gUHJldmlvdXMgbW9udGggY2FsZW5kYXIgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItY2FsZW5kYXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWhlYWRlclwiPlxuICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJjYW1iaWFyTWVzKC0xKVwiPlxuICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgdmlld0JveD1cIjAgMCAxNiAxNlwiPlxuICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCIgZD1cIk0xMS4zNTQgMS42NDZhLjUuNSAwIDAgMSAwIC43MDhMNS43MDcgOGw1LjY0NyA1LjY0NmEuNS41IDAgMCAxLS43MDguNzA4bC02LTZhLjUuNSAwIDAgMSAwLS43MDhsNi02YS41LjUgMCAwIDEgLjcwOCAwelwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxzcGFuPnt7IGdldE5vbWJyZU1lcyhtZXNBbnRlcmlvcikgfX08L3NwYW4+XG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgc3R5bGU9XCJ2aXNpYmlsaXR5OiBoaWRkZW47XCI+XG4gICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCI+XG4gICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIiBkPVwiTTQuNjQ2IDEuNjQ2YS41LjUgMCAwIDEgLjcwOCAwbDYgNmEuNS41IDAgMCAxIDAgLjcwOGwtNiA2YS41LjUgMCAwIDEtLjcwOC0uNzA4TDEwLjI5MyA4IDQuNjQ2IDIuMzU0YS41LjUgMCAwIDEgMC0uNzA4elwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLXdlZWtkYXlzXCI+XG4gICAgICAgICAgQGZvciAoZGF5TmFtZSBvZiBnZXREYXlOYW1lcygpOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgIDxzcGFuPnt7IGRheU5hbWUgfX08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWRheXNcIj5cbiAgICAgICAgICBAZm9yIChkaWFPYmogb2YgZGlhc01lc0FudGVyaW9yOyB0cmFjayBkaWFPYmouZmVjaGEgfHwgJGluZGV4KSB7XG4gICAgICAgICAgICA8YnV0dG9uIFxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJkYXRlLXBpY2tlci1kYXlcIiBcbiAgICAgICAgICAgICAgW2NsYXNzLmVtcHR5XT1cIiFkaWFPYmouZXNNZXNBY3R1YWxcIlxuICAgICAgICAgICAgICBbY2xhc3Muc2VsZWN0ZWRdPVwiZGlhT2JqLmVzSW5pY2lvIHx8IGRpYU9iai5lc0ZpblwiXG4gICAgICAgICAgICAgIFtjbGFzcy5pbi1yYW5nZV09XCJkaWFPYmouZW5SYW5nbyAmJiAhZGlhT2JqLmVzSW5pY2lvICYmICFkaWFPYmouZXNGaW5cIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWNjaW9uYXJEaWEoZGlhT2JqKVwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhZGlhT2JqLmVzTWVzQWN0dWFsXCI+XG4gICAgICAgICAgICAgIHt7IGRpYU9iai5kaWEgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBDdXJyZW50IG1vbnRoIGNhbGVuZGFyIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWNhbGVuZGFyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkYXRlLXBpY2tlci1oZWFkZXJcIj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBzdHlsZT1cInZpc2liaWxpdHk6IGhpZGRlbjtcIj5cbiAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIj5cbiAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiIGQ9XCJNMTEuMzU0IDEuNjQ2YS41LjUgMCAwIDEgMCAuNzA4TDUuNzA3IDhsNS42NDcgNS42NDZhLjUuNSAwIDAgMS0uNzA4LjcwOGwtNi02YS41LjUgMCAwIDEgMC0uNzA4bDYtNmEuNS41IDAgMCAxIC43MDggMHpcIi8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8c3Bhbj57eyBnZXROb21icmVNZXMobWVzQWN0dWFsKSB9fTwvc3Bhbj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2FtYmlhck1lcygxKVwiPlxuICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgdmlld0JveD1cIjAgMCAxNiAxNlwiPlxuICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCIgZD1cIk00LjY0NiAxLjY0NmEuNS41IDAgMCAxIC43MDggMGw2IDZhLjUuNSAwIDAgMSAwIC43MDhsLTYgNmEuNS41IDAgMCAxLS43MDgtLjcwOEwxMC4yOTMgOCA0LjY0NiAyLjM1NGEuNS41IDAgMCAxIDAtLjcwOHpcIi8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkYXRlLXBpY2tlci13ZWVrZGF5c1wiPlxuICAgICAgICAgIEBmb3IgKGRheU5hbWUgb2YgZ2V0RGF5TmFtZXMoKTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICA8c3Bhbj57eyBkYXlOYW1lIH19PC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkYXRlLXBpY2tlci1kYXlzXCI+XG4gICAgICAgICAgQGZvciAoZGlhT2JqIG9mIGRpYXNNZXNBY3R1YWw7IHRyYWNrIGRpYU9iai5mZWNoYSB8fCAkaW5kZXgpIHtcbiAgICAgICAgICAgIDxidXR0b24gXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImRhdGUtcGlja2VyLWRheVwiIFxuICAgICAgICAgICAgICBbY2xhc3MuZW1wdHldPVwiIWRpYU9iai5lc01lc0FjdHVhbFwiXG4gICAgICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJkaWFPYmouZXNJbmljaW8gfHwgZGlhT2JqLmVzRmluXCJcbiAgICAgICAgICAgICAgW2NsYXNzLmluLXJhbmdlXT1cImRpYU9iai5lblJhbmdvICYmICFkaWFPYmouZXNJbmljaW8gJiYgIWRpYU9iai5lc0ZpblwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY2Npb25hckRpYShkaWFPYmopXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFkaWFPYmouZXNNZXNBY3R1YWxcIj5cbiAgICAgICAgICAgICAge3sgZGlhT2JqLmRpYSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBGb290ZXIgd2l0aCBjbGVhciBidXR0b24gLS0+XG4gICAgQGlmIChzaG93Q2xlYXJCdXR0b24pIHtcbiAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItZm9vdGVyXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1jbGVhclwiIChjbGljayk9XCJsaW1waWFyKClcIiB0aXRsZT1cIkNsZWFyIHNlbGVjdGlvblwiPlxuICAgICAgICBDbGVhclxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cbiAgfVxuPC9kaXY+XG4iXX0=
|
|
324
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHVhbC1kYXRlcGlja2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kdWFsLWRhdGVwaWNrZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vc3JjL2R1YWwtZGF0ZXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFvQyxZQUFZLEVBQWMsVUFBVSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pLLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFtQzNHLE1BQU0sT0FBTyx1QkFBdUI7SUFpRGQ7SUFoRFgsV0FBVyxHQUFXLG1CQUFtQixDQUFDO0lBQzFDLFdBQVcsR0FBVyxFQUFFLENBQUM7SUFDekIsUUFBUSxHQUFXLEVBQUUsQ0FBQztJQUN0QixXQUFXLEdBQVksSUFBSSxDQUFDO0lBQzVCLGVBQWUsR0FBWSxLQUFLLENBQUM7SUFDakMsZ0JBQWdCLEdBQVksSUFBSSxDQUFDO0lBQ2pDLHNCQUFzQixHQUFZLElBQUksQ0FBQztJQUN2QyxtQkFBbUIsR0FBWSxJQUFJLENBQUM7SUFDcEMsT0FBTyxHQUFtQjtRQUNqQyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRTtRQUNwQyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRTtRQUN4QyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRTtLQUNyQyxDQUFDO0lBQ08sb0JBQW9CLEdBQVcsTUFBTSxDQUFDO0lBQ3RDLGNBQWMsR0FBVyxTQUFTLENBQUM7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O2dCQUNHLGlCQUFpQjtzQkFBMUIsTUFBTTtnQkFxQ1AsY0FBYztzQkFEYixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIE9uSW5pdCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBIb3N0TGlzdGVuZXIsIEVsZW1lbnRSZWYsIGZvcndhcmRSZWYsIHNpZ25hbCwgY29tcHV0ZWQsIGVmZmVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlLCBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0ZVJhbmdlIHtcbiAgZmVjaGFJbmljaW86IHN0cmluZztcbiAgZmVjaGFGaW46IHN0cmluZztcbiAgcmFuZ29UZXh0bzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByZXNldENvbmZpZyB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGRheXNBZ286IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMb2NhbGVDb25maWcge1xuICBtb250aE5hbWVzPzogc3RyaW5nW107XG4gIG1vbnRoTmFtZXNTaG9ydD86IHN0cmluZ1tdO1xuICBkYXlOYW1lcz86IHN0cmluZ1tdO1xuICBkYXlOYW1lc1Nob3J0Pzogc3RyaW5nW107XG4gIGZpcnN0RGF5T2ZXZWVrPzogbnVtYmVyOyAvLyAwID0gU3VuZGF5LCAxID0gTW9uZGF5LCBldGMuXG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1kdWFsLWRhdGVwaWNrZXInLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9kdWFsLWRhdGVwaWNrZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vZHVhbC1kYXRlcGlja2VyLmNvbXBvbmVudC5zY3NzJyxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBEdWFsRGF0ZXBpY2tlckNvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH1cbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBEdWFsRGF0ZXBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyOiBzdHJpbmcgPSAnU2VsZWN0IGRhdGUgcmFuZ2UnO1xuICBASW5wdXQoKSBmZWNoYUluaWNpbzogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIGZlY2hhRmluOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgc2hvd1ByZXNldHM6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBzaG93Q2xlYXJCdXR0b246IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgY2xvc2VPblNlbGVjdGlvbjogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGNsb3NlT25QcmVzZXRTZWxlY3Rpb246IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBjbG9zZU9uQ2xpY2tPdXRzaWRlOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgcHJlc2V0czogUHJlc2V0Q29uZmlnW10gPSBbXG4gICAgeyBsYWJlbDogJ0xhc3QgbW9udGgnLCBkYXlzQWdvOiAzMCB9LFxuICAgIHsgbGFiZWw6ICdMYXN0IDYgbW9udGhzJywgZGF5c0FnbzogMTgwIH0sXG4gICAgeyBsYWJlbDogJ0xhc3QgeWVhcicsIGRheXNBZ286IDM2NSB9XG4gIF07XG4gIEBJbnB1dCgpIGlucHV0QmFja2dyb3VuZENvbG9yOiBzdHJpbmcgPSAnI2ZmZic7XG4gIEBJbnB1dCgpIGlucHV0VGV4dENvbG9yOiBzdHJpbmcgPSAnIzQ5NTA1Nyc7XG4gIEBJbnB1dCgpIGlucHV0Qm9yZGVyQ29sb3I6IHN0cmluZyA9ICcjY2VkNGRhJztcbiAgQElucHV0KCkgaW5wdXRCb3JkZXJDb2xvckhvdmVyOiBzdHJpbmcgPSAnI2NlZDRkYSc7XG4gIEBJbnB1dCgpIGlucHV0Qm9yZGVyQ29sb3JGb2N1czogc3RyaW5nID0gJyM4MGJkZmYnO1xuICBASW5wdXQoKSBpbnB1dFBhZGRpbmc6IHN0cmluZyA9ICcwLjM3NXJlbSAwLjc1cmVtJztcbiAgQElucHV0KCkgbG9jYWxlOiBMb2NhbGVDb25maWcgPSB7fTtcblxuICBAT3V0cHV0KCkgZGF0ZVJhbmdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRlUmFuZ2U+KCk7XG4gIEBPdXRwdXQoKSBkYXRlUmFuZ2VTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0ZVJhbmdlPigpO1xuXG4gIC8vIFNpZ25hbHMgZm9yIHJlYWN0aXZlIHN0YXRlXG4gIG1vc3RyYXJEYXRlUGlja2VyID0gc2lnbmFsKGZhbHNlKTtcbiAgcmFuZ29GZWNoYXMgPSBzaWduYWwoJycpO1xuICBmZWNoYVNlbGVjY2lvbmFuZG9JbmljaW8gPSBzaWduYWwodHJ1ZSk7XG4gIG1lc0FjdHVhbCA9IHNpZ25hbChuZXcgRGF0ZSgpKTtcbiAgbWVzQW50ZXJpb3IgPSBzaWduYWwobmV3IERhdGUoKSk7XG4gIGRpYXNNZXNBY3R1YWwgPSBzaWduYWw8YW55W10+KFtdKTtcbiAgZGlhc01lc0FudGVyaW9yID0gc2lnbmFsPGFueVtdPihbXSk7XG4gIGlzRGlzYWJsZWQgPSBzaWduYWwoZmFsc2UpO1xuXG4gIC8vIENvbXB1dGVkIHZhbHVlc1xuICBub21icmVNZXNBY3R1YWwgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmdldE5vbWJyZU1lcyh0aGlzLm1lc0FjdHVhbCgpKSk7XG4gIG5vbWJyZU1lc0FudGVyaW9yID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5nZXROb21icmVNZXModGhpcy5tZXNBbnRlcmlvcigpKSk7XG4gIGRpYXNTZW1hbmEgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmdldERheU5hbWVzKCkpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdE1vbnRoTmFtZXMgPSBbJ0phbnVhcnknLCAnRmVicnVhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLCAnSnVseScsICdBdWd1c3QnLCAnU2VwdGVtYmVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0TW9udGhOYW1lc1Nob3J0ID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHREYXlOYW1lcyA9IFsnU3VuZGF5JywgJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknXTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0RGF5TmFtZXNTaG9ydCA9IFsnUycsICdNJywgJ1QnLCAnVycsICdUJywgJ0YnLCAnUyddO1xuXG4gIC8vIENvbnRyb2xWYWx1ZUFjY2Vzc29yIGNhbGxiYWNrc1xuICBwcml2YXRlIG9uQ2hhbmdlOiAodmFsdWU6IERhdGVSYW5nZSB8IG51bGwpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgcHJpdmF0ZSBvblRvdWNoZWQ6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHtcbiAgICAvLyBFZmZlY3QgdG8gZW1pdCBjaGFuZ2VzIHdoZW4gZGF0ZXMgY2hhbmdlXG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGNvbnN0IHJhbmdvID0gdGhpcy5yYW5nb0ZlY2hhcygpO1xuICAgICAgaWYgKHRoaXMuZmVjaGFJbmljaW8gfHwgdGhpcy5mZWNoYUZpbikge1xuICAgICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMuZ2V0RGF0ZVJhbmdlVmFsdWUoKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXG4gIG9uQ2xpY2tPdXRzaWRlKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMubW9zdHJhckRhdGVQaWNrZXIoKSAmJiB0aGlzLmNsb3NlT25DbGlja091dHNpZGUpIHtcbiAgICAgIGNvbnN0IGNsaWNrZWRJbnNpZGUgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpO1xuICAgICAgaWYgKCFjbGlja2VkSW5zaWRlKSB7XG4gICAgICAgIHRoaXMuY2VycmFyRGF0ZVBpY2tlcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmZlY2hhSW5pY2lvICYmIHRoaXMuZmVjaGFGaW4pIHtcbiAgICAgIHRoaXMuYWN0dWFsaXphclJhbmdvRmVjaGFzVGV4dG8oKTtcbiAgICAgIHRoaXMuZ2VuZXJhckNhbGVuZGFyaW9zKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydmZWNoYUluaWNpbyddIHx8IGNoYW5nZXNbJ2ZlY2hhRmluJ10pIHtcbiAgICAgIGlmICh0aGlzLmZlY2hhSW5pY2lvICYmIHRoaXMuZmVjaGFGaW4pIHtcbiAgICAgICAgdGhpcy5hY3R1YWxpemFyUmFuZ29GZWNoYXNUZXh0bygpO1xuICAgICAgICB0aGlzLmdlbmVyYXJDYWxlbmRhcmlvcygpO1xuICAgICAgfSBlbHNlIGlmICghdGhpcy5mZWNoYUluaWNpbyAmJiAhdGhpcy5mZWNoYUZpbikge1xuICAgICAgICB0aGlzLnJhbmdvRmVjaGFzLnNldCgnJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZm9ybWF0ZWFyRmVjaGEoZmVjaGE6IERhdGUpOiBzdHJpbmcge1xuICAgIGNvbnN0IHllYXIgPSBmZWNoYS5nZXRGdWxsWWVhcigpO1xuICAgIGNvbnN0IG1vbnRoID0gU3RyaW5nKGZlY2hhLmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIGNvbnN0IGRheSA9IFN0cmluZyhmZWNoYS5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgcmV0dXJuIGAke3llYXJ9LSR7bW9udGh9LSR7ZGF5fWA7XG4gIH1cblxuICBmb3JtYXRlYXJGZWNoYURpc3BsYXkoZmVjaGFTdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFmZWNoYVN0cikgcmV0dXJuICcnO1xuICAgIGNvbnN0IGZlY2hhID0gbmV3IERhdGUoZmVjaGFTdHIgKyAnVDAwOjAwOjAwJyk7XG4gICAgY29uc3QgbW9udGhOYW1lcyA9IHRoaXMubG9jYWxlLm1vbnRoTmFtZXNTaG9ydCB8fCB0aGlzLmRlZmF1bHRNb250aE5hbWVzU2hvcnQ7XG4gICAgcmV0dXJuIGAke2ZlY2hhLmdldERhdGUoKX0gJHttb250aE5hbWVzW2ZlY2hhLmdldE1vbnRoKCldfWA7XG4gIH1cblxuICBhY3R1YWxpemFyUmFuZ29GZWNoYXNUZXh0bygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mZWNoYUluaWNpbyAmJiB0aGlzLmZlY2hhRmluKSB7XG4gICAgICBjb25zdCBpbmljaW8gPSB0aGlzLmZvcm1hdGVhckZlY2hhRGlzcGxheSh0aGlzLmZlY2hhSW5pY2lvKTtcbiAgICAgIGNvbnN0IGZpbiA9IHRoaXMuZm9ybWF0ZWFyRmVjaGFEaXNwbGF5KHRoaXMuZmVjaGFGaW4pO1xuICAgICAgdGhpcy5yYW5nb0ZlY2hhcy5zZXQoYCR7aW5pY2lvfSAtICR7ZmlufWApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJhbmdvRmVjaGFzLnNldCgnJyk7XG4gICAgfVxuICB9XG5cbiAgdG9nZ2xlRGF0ZVBpY2tlcigpOiB2b2lkIHtcbiAgICB0aGlzLm1vc3RyYXJEYXRlUGlja2VyLnVwZGF0ZSh2YWx1ZSA9PiAhdmFsdWUpO1xuICAgIGlmICh0aGlzLm1vc3RyYXJEYXRlUGlja2VyKCkpIHtcbiAgICAgIHRoaXMuZmVjaGFTZWxlY2Npb25hbmRvSW5pY2lvLnNldCh0cnVlKTtcbiAgICAgIGNvbnN0IG1lc0FjdHVhbFZhbHVlID0gdGhpcy5tZXNBY3R1YWwoKTtcbiAgICAgIHRoaXMubWVzQW50ZXJpb3Iuc2V0KG5ldyBEYXRlKG1lc0FjdHVhbFZhbHVlLmdldEZ1bGxZZWFyKCksIG1lc0FjdHVhbFZhbHVlLmdldE1vbnRoKCkgLSAxLCAxKSk7XG4gICAgICB0aGlzLmdlbmVyYXJDYWxlbmRhcmlvcygpO1xuICAgIH1cbiAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICB9XG5cbiAgY2VycmFyRGF0ZVBpY2tlcigpOiB2b2lkIHtcbiAgICB0aGlzLm1vc3RyYXJEYXRlUGlja2VyLnNldChmYWxzZSk7XG4gICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgfVxuXG4gIGdlbmVyYXJDYWxlbmRhcmlvcygpOiB2b2lkIHtcbiAgICB0aGlzLmRpYXNNZXNBbnRlcmlvci5zZXQodGhpcy5nZW5lcmFyQ2FsZW5kYXJpb01lcyh0aGlzLm1lc0FudGVyaW9yKCkpKTtcbiAgICB0aGlzLmRpYXNNZXNBY3R1YWwuc2V0KHRoaXMuZ2VuZXJhckNhbGVuZGFyaW9NZXModGhpcy5tZXNBY3R1YWwoKSkpO1xuICB9XG5cbiAgZ2VuZXJhckNhbGVuZGFyaW9NZXMoZmVjaGE6IERhdGUpOiBhbnlbXSB7XG4gICAgY29uc3QgYcOxbyA9IGZlY2hhLmdldEZ1bGxZZWFyKCk7XG4gICAgY29uc3QgbWVzID0gZmVjaGEuZ2V0TW9udGgoKTtcbiAgICBjb25zdCBwcmltZXJEaWEgPSBuZXcgRGF0ZShhw7FvLCBtZXMsIDEpO1xuICAgIGNvbnN0IHVsdGltb0RpYSA9IG5ldyBEYXRlKGHDsW8sIG1lcyArIDEsIDApO1xuICAgIGNvbnN0IGRpYXNFbk1lcyA9IHVsdGltb0RpYS5nZXREYXRlKCk7XG4gICAgY29uc3QgcHJpbWVyRGlhU2VtYW5hID0gcHJpbWVyRGlhLmdldERheSgpO1xuXG4gICAgY29uc3QgZGlhc01lcyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcmltZXJEaWFTZW1hbmE7IGkrKykge1xuICAgICAgZGlhc01lcy5wdXNoKHsgZGlhOiBudWxsLCBlc01lc0FjdHVhbDogZmFsc2UgfSk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgZGlhID0gMTsgZGlhIDw9IGRpYXNFbk1lczsgZGlhKyspIHtcbiAgICAgIGNvbnN0IGZlY2hhRGlhID0gbmV3IERhdGUoYcOxbywgbWVzLCBkaWEpO1xuICAgICAgY29uc3QgZmVjaGFTdHIgPSB0aGlzLmZvcm1hdGVhckZlY2hhKGZlY2hhRGlhKTtcbiAgICAgIGRpYXNNZXMucHVzaCh7XG4gICAgICAgIGRpYTogZGlhLFxuICAgICAgICBmZWNoYTogZmVjaGFTdHIsXG4gICAgICAgIGVzTWVzQWN0dWFsOiB0cnVlLFxuICAgICAgICBlc0luaWNpbzogdGhpcy5mZWNoYUluaWNpbyA9PT0gZmVjaGFTdHIsXG4gICAgICAgIGVzRmluOiB0aGlzLmZlY2hhRmluID09PSBmZWNoYVN0cixcbiAgICAgICAgZW5SYW5nbzogdGhpcy5lc3RhRW5SYW5nbyhmZWNoYVN0cilcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBkaWFzTWVzO1xuICB9XG5cbiAgZXN0YUVuUmFuZ28oZmVjaGFTdHI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5mZWNoYUluaWNpbyB8fCAhdGhpcy5mZWNoYUZpbikgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBmZWNoYVN0ciA+PSB0aGlzLmZlY2hhSW5pY2lvICYmIGZlY2hhU3RyIDw9IHRoaXMuZmVjaGFGaW47XG4gIH1cblxuICBzZWxlY2Npb25hckRpYShkaWFPYmo6IGFueSk6IHZvaWQge1xuICAgIGlmICghZGlhT2JqLmVzTWVzQWN0dWFsIHx8IHRoaXMuaXNEaXNhYmxlZCgpKSByZXR1cm47XG5cbiAgICBpZiAodGhpcy5mZWNoYVNlbGVjY2lvbmFuZG9JbmljaW8oKSkge1xuICAgICAgdGhpcy5mZWNoYUluaWNpbyA9IGRpYU9iai5mZWNoYTtcbiAgICAgIHRoaXMuZmVjaGFGaW4gPSAnJztcbiAgICAgIHRoaXMucmFuZ29GZWNoYXMuc2V0KCcnKTtcbiAgICAgIHRoaXMuZmVjaGFTZWxlY2Npb25hbmRvSW5pY2lvLnNldChmYWxzZSk7XG4gICAgICB0aGlzLmVtaXRpckNhbWJpbygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZGlhT2JqLmZlY2hhIDwgdGhpcy5mZWNoYUluaWNpbykge1xuICAgICAgICB0aGlzLmZlY2hhRmluID0gdGhpcy5mZWNoYUluaWNpbztcbiAgICAgICAgdGhpcy5mZWNoYUluaWNpbyA9IGRpYU9iai5mZWNoYTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZmVjaGFGaW4gPSBkaWFPYmouZmVjaGE7XG4gICAgICB9XG4gICAgICB0aGlzLmFjdHVhbGl6YXJSYW5nb0ZlY2hhc1RleHRvKCk7XG4gICAgICBpZiAodGhpcy5jbG9zZU9uU2VsZWN0aW9uKSB7XG4gICAgICAgIHRoaXMubW9zdHJhckRhdGVQaWNrZXIuc2V0KGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmVjaGFTZWxlY2Npb25hbmRvSW5pY2lvLnNldCh0cnVlKTtcbiAgICAgIHRoaXMuZW1pdGlyQ2FtYmlvKCk7XG4gICAgICB0aGlzLmVtaXRpclNlbGVjY2lvbigpO1xuICAgIH1cbiAgICB0aGlzLmdlbmVyYXJDYWxlbmRhcmlvcygpO1xuICB9XG5cbiAgY2FtYmlhck1lcyhkaXJlY2Npb246IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IG1lc0FjdHVhbFZhbHVlID0gdGhpcy5tZXNBY3R1YWwoKTtcbiAgICB0aGlzLm1lc0FjdHVhbC5zZXQobmV3IERhdGUobWVzQWN0dWFsVmFsdWUuZ2V0RnVsbFllYXIoKSwgbWVzQWN0dWFsVmFsdWUuZ2V0TW9udGgoKSArIGRpcmVjY2lvbiwgMSkpO1xuICAgIGNvbnN0IG51ZXZvTWVzQWN0dWFsID0gdGhpcy5tZXNBY3R1YWwoKTtcbiAgICB0aGlzLm1lc0FudGVyaW9yLnNldChuZXcgRGF0ZShudWV2b01lc0FjdHVhbC5nZXRGdWxsWWVhcigpLCBudWV2b01lc0FjdHVhbC5nZXRNb250aCgpIC0gMSwgMSkpO1xuICAgIHRoaXMuZ2VuZXJhckNhbGVuZGFyaW9zKCk7XG4gIH1cblxuICBnZXROb21icmVNZXMoZmVjaGE6IERhdGUpOiBzdHJpbmcge1xuICAgIGNvbnN0IG1vbnRoTmFtZXMgPSB0aGlzLmxvY2FsZS5tb250aE5hbWVzIHx8IHRoaXMuZGVmYXVsdE1vbnRoTmFtZXM7XG4gICAgcmV0dXJuIGAke21vbnRoTmFtZXNbZmVjaGEuZ2V0TW9udGgoKV19ICR7ZmVjaGEuZ2V0RnVsbFllYXIoKX1gO1xuICB9XG5cbiAgZ2V0RGF5TmFtZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmxvY2FsZS5kYXlOYW1lc1Nob3J0IHx8IHRoaXMuZGVmYXVsdERheU5hbWVzU2hvcnQ7XG4gIH1cblxuICBzZWxlY2Npb25hclJhbmdvUHJlZGVmaW5pZG8ocHJlc2V0OiBQcmVzZXRDb25maWcpOiB2b2lkIHtcbiAgICBjb25zdCBob3kgPSBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IGZlY2hhSW5pY2lvID0gbmV3IERhdGUoaG95KTtcbiAgICBmZWNoYUluaWNpby5zZXREYXRlKGhveS5nZXREYXRlKCkgLSBwcmVzZXQuZGF5c0Fnbyk7XG5cbiAgICB0aGlzLmZlY2hhSW5pY2lvID0gdGhpcy5mb3JtYXRlYXJGZWNoYShmZWNoYUluaWNpbyk7XG4gICAgdGhpcy5mZWNoYUZpbiA9IHRoaXMuZm9ybWF0ZWFyRmVjaGEoaG95KTtcbiAgICB0aGlzLmFjdHVhbGl6YXJSYW5nb0ZlY2hhc1RleHRvKCk7XG4gICAgdGhpcy5nZW5lcmFyQ2FsZW5kYXJpb3MoKTtcbiAgICBpZiAodGhpcy5jbG9zZU9uUHJlc2V0U2VsZWN0aW9uKSB7XG4gICAgICB0aGlzLm1vc3RyYXJEYXRlUGlja2VyLnNldChmYWxzZSk7XG4gICAgfVxuICAgIHRoaXMuZW1pdGlyU2VsZWNjaW9uKCk7XG4gIH1cblxuICBsaW1waWFyKCk6IHZvaWQge1xuICAgIHRoaXMuZmVjaGFJbmljaW8gPSAnJztcbiAgICB0aGlzLmZlY2hhRmluID0gJyc7XG4gICAgdGhpcy5yYW5nb0ZlY2hhcy5zZXQoJycpO1xuICAgIHRoaXMubW9zdHJhckRhdGVQaWNrZXIuc2V0KGZhbHNlKTtcbiAgICB0aGlzLmZlY2hhU2VsZWNjaW9uYW5kb0luaWNpby5zZXQodHJ1ZSk7XG4gICAgdGhpcy5lbWl0aXJDYW1iaW8oKTtcbiAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0aXJDYW1iaW8oKTogdm9pZCB7XG4gICAgdGhpcy5kYXRlUmFuZ2VDaGFuZ2UuZW1pdCh7XG4gICAgICBmZWNoYUluaWNpbzogdGhpcy5mZWNoYUluaWNpbyxcbiAgICAgIGZlY2hhRmluOiB0aGlzLmZlY2hhRmluLFxuICAgICAgcmFuZ29UZXh0bzogdGhpcy5yYW5nb0ZlY2hhcygpXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRpclNlbGVjY2lvbigpOiB2b2lkIHtcbiAgICB0aGlzLmRhdGVSYW5nZVNlbGVjdGVkLmVtaXQoe1xuICAgICAgZmVjaGFJbmljaW86IHRoaXMuZmVjaGFJbmljaW8sXG4gICAgICBmZWNoYUZpbjogdGhpcy5mZWNoYUZpbixcbiAgICAgIHJhbmdvVGV4dG86IHRoaXMucmFuZ29GZWNoYXMoKVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREYXRlUmFuZ2VWYWx1ZSgpOiBEYXRlUmFuZ2Uge1xuICAgIHJldHVybiB7XG4gICAgICBmZWNoYUluaWNpbzogdGhpcy5mZWNoYUluaWNpbyxcbiAgICAgIGZlY2hhRmluOiB0aGlzLmZlY2hhRmluLFxuICAgICAgcmFuZ29UZXh0bzogdGhpcy5yYW5nb0ZlY2hhcygpXG4gICAgfTtcbiAgfVxuXG4gIC8vIENvbnRyb2xWYWx1ZUFjY2Vzc29yIGltcGxlbWVudGF0aW9uXG4gIHdyaXRlVmFsdWUodmFsdWU6IERhdGVSYW5nZSB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuZmVjaGFJbmljaW8gPSB2YWx1ZS5mZWNoYUluaWNpbyB8fCAnJztcbiAgICAgIHRoaXMuZmVjaGFGaW4gPSB2YWx1ZS5mZWNoYUZpbiB8fCAnJztcbiAgICAgIGlmICh0aGlzLmZlY2hhSW5pY2lvICYmIHRoaXMuZmVjaGFGaW4pIHtcbiAgICAgICAgdGhpcy5hY3R1YWxpemFyUmFuZ29GZWNoYXNUZXh0bygpO1xuICAgICAgICB0aGlzLmdlbmVyYXJDYWxlbmRhcmlvcygpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZlY2hhSW5pY2lvID0gJyc7XG4gICAgICB0aGlzLmZlY2hhRmluID0gJyc7XG4gICAgICB0aGlzLnJhbmdvRmVjaGFzLnNldCgnJyk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKHZhbHVlOiBEYXRlUmFuZ2UgfCBudWxsKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5pc0Rpc2FibGVkLnNldChpc0Rpc2FibGVkKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImRhdGVwaWNrZXItd3JhcHBlclwiIFxuICBbc3R5bGUuLS1pbnB1dC1ib3JkZXItaG92ZXJdPVwiaW5wdXRCb3JkZXJDb2xvckhvdmVyXCJcbiAgW3N0eWxlLi0taW5wdXQtYm9yZGVyLWZvY3VzXT1cImlucHV0Qm9yZGVyQ29sb3JGb2N1c1wiPlxuICA8aW5wdXQgXG4gICAgdHlwZT1cInRleHRcIiBcbiAgICBjbGFzcz1cImRhdGVwaWNrZXItaW5wdXRcIiBcbiAgICBbdmFsdWVdPVwicmFuZ29GZWNoYXMoKVwiIFxuICAgIChjbGljayk9XCJ0b2dnbGVEYXRlUGlja2VyKClcIiBcbiAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxuICAgIFtkaXNhYmxlZF09XCJpc0Rpc2FibGVkKClcIlxuICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICdiYWNrZ3JvdW5kLWNvbG9yJzogaW5wdXRCYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAnY29sb3InOiBpbnB1dFRleHRDb2xvcixcbiAgICAgICdib3JkZXItY29sb3InOiBpbnB1dEJvcmRlckNvbG9yLFxuICAgICAgJ3BhZGRpbmcnOiBpbnB1dFBhZGRpbmdcbiAgICB9XCJcbiAgICByZWFkb25seT5cblxuICBAaWYgKG1vc3RyYXJEYXRlUGlja2VyKCkpIHtcbiAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWRyb3Bkb3duXCI+XG4gICAgQGlmIChzaG93UHJlc2V0cykge1xuICAgIDxkaXYgY2xhc3M9XCJkYXRlLXBpY2tlci1wcmVzZXRzXCI+XG4gICAgICBAZm9yIChwcmVzZXQgb2YgcHJlc2V0czsgdHJhY2sgcHJlc2V0LmxhYmVsKSB7XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwic2VsZWNjaW9uYXJSYW5nb1ByZWRlZmluaWRvKHByZXNldClcIj57eyBwcmVzZXQubGFiZWwgfX08L2J1dHRvbj5cbiAgICAgIH1cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWNsb3NlLWNhbGVuZGFyXCIgKGNsaWNrKT1cImNlcnJhckRhdGVQaWNrZXIoKVwiIHRpdGxlPVwiQ2xvc2VcIj5cbiAgICAgICAgw5dcbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICAgIH1cblxuICAgIEBpZiAoIXNob3dQcmVzZXRzKSB7XG4gICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWhlYWRlci1vbmx5LWNsb3NlXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1jbG9zZS1jYWxlbmRhclwiIChjbGljayk9XCJjZXJyYXJEYXRlUGlja2VyKClcIiB0aXRsZT1cIkNsb3NlXCI+XG4gICAgICAgIMOXXG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICB9XG5cbiAgICA8IS0tIENhbGVuZGFycyAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItY2FsZW5kYXJzXCI+XG4gICAgICA8IS0tIFByZXZpb3VzIG1vbnRoIGNhbGVuZGFyIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWNhbGVuZGFyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkYXRlLXBpY2tlci1oZWFkZXJcIj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2FtYmlhck1lcygtMSlcIj5cbiAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIj5cbiAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiIGQ9XCJNMTEuMzU0IDEuNjQ2YS41LjUgMCAwIDEgMCAuNzA4TDUuNzA3IDhsNS42NDcgNS42NDZhLjUuNSAwIDAgMS0uNzA4LjcwOGwtNi02YS41LjUgMCAwIDEgMC0uNzA4bDYtNmEuNS41IDAgMCAxIC43MDggMHpcIi8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8c3Bhbj57eyBub21icmVNZXNBbnRlcmlvcigpIH19PC9zcGFuPlxuICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIHN0eWxlPVwidmlzaWJpbGl0eTogaGlkZGVuO1wiPlxuICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgdmlld0JveD1cIjAgMCAxNiAxNlwiPlxuICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCIgZD1cIk00LjY0NiAxLjY0NmEuNS41IDAgMCAxIC43MDggMGw2IDZhLjUuNSAwIDAgMSAwIC43MDhsLTYgNmEuNS41IDAgMCAxLS43MDgtLjcwOEwxMC4yOTMgOCA0LjY0NiAyLjM1NGEuNS41IDAgMCAxIDAtLjcwOHpcIi8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkYXRlLXBpY2tlci13ZWVrZGF5c1wiPlxuICAgICAgICAgIEBmb3IgKGRheU5hbWUgb2YgZGlhc1NlbWFuYSgpOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgIDxzcGFuPnt7IGRheU5hbWUgfX08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWRheXNcIj5cbiAgICAgICAgICBAZm9yIChkaWFPYmogb2YgZGlhc01lc0FudGVyaW9yKCk7IHRyYWNrIGRpYU9iai5mZWNoYSB8fCAkaW5kZXgpIHtcbiAgICAgICAgICAgIDxidXR0b24gXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImRhdGUtcGlja2VyLWRheVwiIFxuICAgICAgICAgICAgICBbY2xhc3MuZW1wdHldPVwiIWRpYU9iai5lc01lc0FjdHVhbFwiXG4gICAgICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJkaWFPYmouZXNJbmljaW8gfHwgZGlhT2JqLmVzRmluXCJcbiAgICAgICAgICAgICAgW2NsYXNzLmluLXJhbmdlXT1cImRpYU9iai5lblJhbmdvICYmICFkaWFPYmouZXNJbmljaW8gJiYgIWRpYU9iai5lc0ZpblwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY2Npb25hckRpYShkaWFPYmopXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFkaWFPYmouZXNNZXNBY3R1YWxcIj5cbiAgICAgICAgICAgICAge3sgZGlhT2JqLmRpYSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEN1cnJlbnQgbW9udGggY2FsZW5kYXIgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItY2FsZW5kYXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWhlYWRlclwiPlxuICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIHN0eWxlPVwidmlzaWJpbGl0eTogaGlkZGVuO1wiPlxuICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgdmlld0JveD1cIjAgMCAxNiAxNlwiPlxuICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCIgZD1cIk0xMS4zNTQgMS42NDZhLjUuNSAwIDAgMSAwIC43MDhMNS43MDcgOGw1LjY0NyA1LjY0NmEuNS41IDAgMCAxLS43MDguNzA4bC02LTZhLjUuNSAwIDAgMSAwLS43MDhsNi02YS41LjUgMCAwIDEgLjcwOCAwelwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxzcGFuPnt7IG5vbWJyZU1lc0FjdHVhbCgpIH19PC9zcGFuPlxuICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJjYW1iaWFyTWVzKDEpXCI+XG4gICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCI+XG4gICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIiBkPVwiTTQuNjQ2IDEuNjQ2YS41LjUgMCAwIDEgLjcwOCAwbDYgNmEuNS41IDAgMCAxIDAgLjcwOGwtNiA2YS41LjUgMCAwIDEtLjcwOC0uNzA4TDEwLjI5MyA4IDQuNjQ2IDIuMzU0YS41LjUgMCAwIDEgMC0uNzA4elwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLXdlZWtkYXlzXCI+XG4gICAgICAgICAgQGZvciAoZGF5TmFtZSBvZiBkaWFzU2VtYW5hKCk7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgICAgPHNwYW4+e3sgZGF5TmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItZGF5c1wiPlxuICAgICAgICAgIEBmb3IgKGRpYU9iaiBvZiBkaWFzTWVzQWN0dWFsKCk7IHRyYWNrIGRpYU9iai5mZWNoYSB8fCAkaW5kZXgpIHtcbiAgICAgICAgICAgIDxidXR0b24gXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImRhdGUtcGlja2VyLWRheVwiIFxuICAgICAgICAgICAgICBbY2xhc3MuZW1wdHldPVwiIWRpYU9iai5lc01lc0FjdHVhbFwiXG4gICAgICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJkaWFPYmouZXNJbmljaW8gfHwgZGlhT2JqLmVzRmluXCJcbiAgICAgICAgICAgICAgW2NsYXNzLmluLXJhbmdlXT1cImRpYU9iai5lblJhbmdvICYmICFkaWFPYmouZXNJbmljaW8gJiYgIWRpYU9iai5lc0ZpblwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY2Npb25hckRpYShkaWFPYmopXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFkaWFPYmouZXNNZXNBY3R1YWxcIj5cbiAgICAgICAgICAgICAge3sgZGlhT2JqLmRpYSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBGb290ZXIgd2l0aCBjbGVhciBidXR0b24gLS0+XG4gICAgQGlmIChzaG93Q2xlYXJCdXR0b24pIHtcbiAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItZm9vdGVyXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1jbGVhclwiIChjbGljayk9XCJsaW1waWFyKClcIiB0aXRsZT1cIkNsZWFyIHNlbGVjdGlvblwiPlxuICAgICAgICBDbGVhclxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cbiAgfVxuPC9kaXY+XG4iXX0=
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter, HostListener, Output, Input, Component } from '@angular/core';
|
|
2
|
+
import { EventEmitter, signal, computed, effect, forwardRef, HostListener, Output, Input, Component } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
|
-
import { FormsModule } from '@angular/forms';
|
|
5
|
+
import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
6
|
|
|
7
7
|
class DualDatepickerComponent {
|
|
8
8
|
elementRef;
|
|
@@ -10,7 +10,7 @@ class DualDatepickerComponent {
|
|
|
10
10
|
fechaInicio = '';
|
|
11
11
|
fechaFin = '';
|
|
12
12
|
showPresets = true;
|
|
13
|
-
showClearButton =
|
|
13
|
+
showClearButton = false;
|
|
14
14
|
closeOnSelection = true;
|
|
15
15
|
closeOnPresetSelection = true;
|
|
16
16
|
closeOnClickOutside = true;
|
|
@@ -28,22 +28,38 @@ class DualDatepickerComponent {
|
|
|
28
28
|
locale = {};
|
|
29
29
|
dateRangeChange = new EventEmitter();
|
|
30
30
|
dateRangeSelected = new EventEmitter();
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
// Signals for reactive state
|
|
32
|
+
mostrarDatePicker = signal(false);
|
|
33
|
+
rangoFechas = signal('');
|
|
34
|
+
fechaSeleccionandoInicio = signal(true);
|
|
35
|
+
mesActual = signal(new Date());
|
|
36
|
+
mesAnterior = signal(new Date());
|
|
37
|
+
diasMesActual = signal([]);
|
|
38
|
+
diasMesAnterior = signal([]);
|
|
39
|
+
isDisabled = signal(false);
|
|
40
|
+
// Computed values
|
|
41
|
+
nombreMesActual = computed(() => this.getNombreMes(this.mesActual()));
|
|
42
|
+
nombreMesAnterior = computed(() => this.getNombreMes(this.mesAnterior()));
|
|
43
|
+
diasSemana = computed(() => this.getDayNames());
|
|
38
44
|
defaultMonthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
39
45
|
defaultMonthNamesShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
40
46
|
defaultDayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
41
47
|
defaultDayNamesShort = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
|
|
48
|
+
// ControlValueAccessor callbacks
|
|
49
|
+
onChange = () => { };
|
|
50
|
+
onTouched = () => { };
|
|
42
51
|
constructor(elementRef) {
|
|
43
52
|
this.elementRef = elementRef;
|
|
53
|
+
// Effect to emit changes when dates change
|
|
54
|
+
effect(() => {
|
|
55
|
+
const rango = this.rangoFechas();
|
|
56
|
+
if (this.fechaInicio || this.fechaFin) {
|
|
57
|
+
this.onChange(this.getDateRangeValue());
|
|
58
|
+
}
|
|
59
|
+
});
|
|
44
60
|
}
|
|
45
61
|
onClickOutside(event) {
|
|
46
|
-
if (this.mostrarDatePicker && this.closeOnClickOutside) {
|
|
62
|
+
if (this.mostrarDatePicker() && this.closeOnClickOutside) {
|
|
47
63
|
const clickedInside = this.elementRef.nativeElement.contains(event.target);
|
|
48
64
|
if (!clickedInside) {
|
|
49
65
|
this.cerrarDatePicker();
|
|
@@ -63,7 +79,7 @@ class DualDatepickerComponent {
|
|
|
63
79
|
this.generarCalendarios();
|
|
64
80
|
}
|
|
65
81
|
else if (!this.fechaInicio && !this.fechaFin) {
|
|
66
|
-
this.rangoFechas
|
|
82
|
+
this.rangoFechas.set('');
|
|
67
83
|
}
|
|
68
84
|
}
|
|
69
85
|
}
|
|
@@ -84,26 +100,29 @@ class DualDatepickerComponent {
|
|
|
84
100
|
if (this.fechaInicio && this.fechaFin) {
|
|
85
101
|
const inicio = this.formatearFechaDisplay(this.fechaInicio);
|
|
86
102
|
const fin = this.formatearFechaDisplay(this.fechaFin);
|
|
87
|
-
this.rangoFechas
|
|
103
|
+
this.rangoFechas.set(`${inicio} - ${fin}`);
|
|
88
104
|
}
|
|
89
105
|
else {
|
|
90
|
-
this.rangoFechas
|
|
106
|
+
this.rangoFechas.set('');
|
|
91
107
|
}
|
|
92
108
|
}
|
|
93
109
|
toggleDatePicker() {
|
|
94
|
-
this.mostrarDatePicker
|
|
95
|
-
if (this.mostrarDatePicker) {
|
|
96
|
-
this.fechaSeleccionandoInicio
|
|
97
|
-
|
|
110
|
+
this.mostrarDatePicker.update(value => !value);
|
|
111
|
+
if (this.mostrarDatePicker()) {
|
|
112
|
+
this.fechaSeleccionandoInicio.set(true);
|
|
113
|
+
const mesActualValue = this.mesActual();
|
|
114
|
+
this.mesAnterior.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() - 1, 1));
|
|
98
115
|
this.generarCalendarios();
|
|
99
116
|
}
|
|
117
|
+
this.onTouched();
|
|
100
118
|
}
|
|
101
119
|
cerrarDatePicker() {
|
|
102
|
-
this.mostrarDatePicker
|
|
120
|
+
this.mostrarDatePicker.set(false);
|
|
121
|
+
this.onTouched();
|
|
103
122
|
}
|
|
104
123
|
generarCalendarios() {
|
|
105
|
-
this.diasMesAnterior
|
|
106
|
-
this.diasMesActual
|
|
124
|
+
this.diasMesAnterior.set(this.generarCalendarioMes(this.mesAnterior()));
|
|
125
|
+
this.diasMesActual.set(this.generarCalendarioMes(this.mesActual()));
|
|
107
126
|
}
|
|
108
127
|
generarCalendarioMes(fecha) {
|
|
109
128
|
const año = fecha.getFullYear();
|
|
@@ -136,13 +155,13 @@ class DualDatepickerComponent {
|
|
|
136
155
|
return fechaStr >= this.fechaInicio && fechaStr <= this.fechaFin;
|
|
137
156
|
}
|
|
138
157
|
seleccionarDia(diaObj) {
|
|
139
|
-
if (!diaObj.esMesActual)
|
|
158
|
+
if (!diaObj.esMesActual || this.isDisabled())
|
|
140
159
|
return;
|
|
141
|
-
if (this.fechaSeleccionandoInicio) {
|
|
160
|
+
if (this.fechaSeleccionandoInicio()) {
|
|
142
161
|
this.fechaInicio = diaObj.fecha;
|
|
143
162
|
this.fechaFin = '';
|
|
144
|
-
this.rangoFechas
|
|
145
|
-
this.fechaSeleccionandoInicio
|
|
163
|
+
this.rangoFechas.set('');
|
|
164
|
+
this.fechaSeleccionandoInicio.set(false);
|
|
146
165
|
this.emitirCambio();
|
|
147
166
|
}
|
|
148
167
|
else {
|
|
@@ -155,17 +174,19 @@ class DualDatepickerComponent {
|
|
|
155
174
|
}
|
|
156
175
|
this.actualizarRangoFechasTexto();
|
|
157
176
|
if (this.closeOnSelection) {
|
|
158
|
-
this.mostrarDatePicker
|
|
177
|
+
this.mostrarDatePicker.set(false);
|
|
159
178
|
}
|
|
160
|
-
this.fechaSeleccionandoInicio
|
|
179
|
+
this.fechaSeleccionandoInicio.set(true);
|
|
161
180
|
this.emitirCambio();
|
|
162
181
|
this.emitirSeleccion();
|
|
163
182
|
}
|
|
164
183
|
this.generarCalendarios();
|
|
165
184
|
}
|
|
166
185
|
cambiarMes(direccion) {
|
|
167
|
-
|
|
168
|
-
this.
|
|
186
|
+
const mesActualValue = this.mesActual();
|
|
187
|
+
this.mesActual.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() + direccion, 1));
|
|
188
|
+
const nuevoMesActual = this.mesActual();
|
|
189
|
+
this.mesAnterior.set(new Date(nuevoMesActual.getFullYear(), nuevoMesActual.getMonth() - 1, 1));
|
|
169
190
|
this.generarCalendarios();
|
|
170
191
|
}
|
|
171
192
|
getNombreMes(fecha) {
|
|
@@ -184,38 +205,83 @@ class DualDatepickerComponent {
|
|
|
184
205
|
this.actualizarRangoFechasTexto();
|
|
185
206
|
this.generarCalendarios();
|
|
186
207
|
if (this.closeOnPresetSelection) {
|
|
187
|
-
this.mostrarDatePicker
|
|
208
|
+
this.mostrarDatePicker.set(false);
|
|
188
209
|
}
|
|
189
210
|
this.emitirSeleccion();
|
|
190
211
|
}
|
|
191
212
|
limpiar() {
|
|
192
213
|
this.fechaInicio = '';
|
|
193
214
|
this.fechaFin = '';
|
|
194
|
-
this.rangoFechas
|
|
195
|
-
this.mostrarDatePicker
|
|
196
|
-
this.fechaSeleccionandoInicio
|
|
215
|
+
this.rangoFechas.set('');
|
|
216
|
+
this.mostrarDatePicker.set(false);
|
|
217
|
+
this.fechaSeleccionandoInicio.set(true);
|
|
197
218
|
this.emitirCambio();
|
|
219
|
+
this.onTouched();
|
|
198
220
|
}
|
|
199
221
|
emitirCambio() {
|
|
200
222
|
this.dateRangeChange.emit({
|
|
201
223
|
fechaInicio: this.fechaInicio,
|
|
202
224
|
fechaFin: this.fechaFin,
|
|
203
|
-
rangoTexto: this.rangoFechas
|
|
225
|
+
rangoTexto: this.rangoFechas()
|
|
204
226
|
});
|
|
205
227
|
}
|
|
206
228
|
emitirSeleccion() {
|
|
207
229
|
this.dateRangeSelected.emit({
|
|
208
230
|
fechaInicio: this.fechaInicio,
|
|
209
231
|
fechaFin: this.fechaFin,
|
|
210
|
-
rangoTexto: this.rangoFechas
|
|
232
|
+
rangoTexto: this.rangoFechas()
|
|
211
233
|
});
|
|
212
234
|
}
|
|
235
|
+
getDateRangeValue() {
|
|
236
|
+
return {
|
|
237
|
+
fechaInicio: this.fechaInicio,
|
|
238
|
+
fechaFin: this.fechaFin,
|
|
239
|
+
rangoTexto: this.rangoFechas()
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
// ControlValueAccessor implementation
|
|
243
|
+
writeValue(value) {
|
|
244
|
+
if (value) {
|
|
245
|
+
this.fechaInicio = value.fechaInicio || '';
|
|
246
|
+
this.fechaFin = value.fechaFin || '';
|
|
247
|
+
if (this.fechaInicio && this.fechaFin) {
|
|
248
|
+
this.actualizarRangoFechasTexto();
|
|
249
|
+
this.generarCalendarios();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
this.fechaInicio = '';
|
|
254
|
+
this.fechaFin = '';
|
|
255
|
+
this.rangoFechas.set('');
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
registerOnChange(fn) {
|
|
259
|
+
this.onChange = fn;
|
|
260
|
+
}
|
|
261
|
+
registerOnTouched(fn) {
|
|
262
|
+
this.onTouched = fn;
|
|
263
|
+
}
|
|
264
|
+
setDisabledState(isDisabled) {
|
|
265
|
+
this.isDisabled.set(isDisabled);
|
|
266
|
+
}
|
|
213
267
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DualDatepickerComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
214
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DualDatepickerComponent, isStandalone: true, selector: "ngx-dual-datepicker", inputs: { placeholder: "placeholder", fechaInicio: "fechaInicio", fechaFin: "fechaFin", showPresets: "showPresets", showClearButton: "showClearButton", closeOnSelection: "closeOnSelection", closeOnPresetSelection: "closeOnPresetSelection", closeOnClickOutside: "closeOnClickOutside", presets: "presets", inputBackgroundColor: "inputBackgroundColor", inputTextColor: "inputTextColor", inputBorderColor: "inputBorderColor", inputBorderColorHover: "inputBorderColorHover", inputBorderColorFocus: "inputBorderColorFocus", inputPadding: "inputPadding", locale: "locale" }, outputs: { dateRangeChange: "dateRangeChange", dateRangeSelected: "dateRangeSelected" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ getNombreMes(mesAnterior) }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of getDayNames(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior; track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ getNombreMes(mesActual) }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of getDayNames(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual; track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".datepicker-wrapper{position:relative;width:100%}.datepicker-wrapper .datepicker-input{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;cursor:pointer}.datepicker-wrapper .datepicker-input:hover{border-color:var(--input-border-hover, #ced4da)}.datepicker-wrapper .datepicker-input:focus{border-color:var(--input-border-focus, #80bdff);box-shadow:0 0 0 .2rem #007bff40;outline:0}.datepicker-wrapper .datepicker-input::placeholder{color:#6c757d;opacity:1}.datepicker-wrapper .datepicker-input:disabled,.datepicker-wrapper .datepicker-input[readonly]{background-color:#e9ecef;opacity:1}.date-picker-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e1e4e8;border-radius:8px;box-shadow:0 4px 12px #00000014,0 0 1px #00000014;padding:16px;z-index:1060;min-width:680px}@media (max-width: 768px){.date-picker-dropdown{min-width:100%;left:0;right:0}}.date-picker-header-only-close{display:flex;justify-content:flex-end;margin-bottom:12px}.date-picker-header-only-close .btn-close-calendar{background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;border-radius:6px;cursor:pointer;transition:all .15s ease;font-size:1.5rem;line-height:1}.date-picker-header-only-close .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-header-only-close .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-presets{display:flex;gap:6px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #e5e7eb;align-items:center}@media (max-width: 768px){.date-picker-presets{flex-wrap:wrap}}.date-picker-presets button{font-size:.75rem;padding:6px 14px;border:none;background-color:#f9fafb;color:#374151;border-radius:6px;transition:all .15s ease;font-weight:500;cursor:pointer;border:1px solid #e5e7eb}.date-picker-presets button:hover{background-color:#f3f4f6;border-color:#d1d5db;transform:translateY(-1px);box-shadow:0 2px 4px #0000000f}.date-picker-presets button:active{transform:translateY(0);box-shadow:none}.date-picker-presets .btn-close-calendar{margin-left:auto;background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;font-size:1.5rem;line-height:1}.date-picker-presets .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-presets .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-calendars{display:flex;gap:32px}@media (max-width: 768px){.date-picker-calendars{flex-direction:column;gap:16px}}.date-picker-calendar{flex:1}.date-picker-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding:0 4px}.date-picker-header span{font-size:.813rem;font-weight:600;color:#111827}.date-picker-header button{padding:4px;color:#6b7280;text-decoration:none;border-radius:6px;transition:all .15s ease;border:none;background:transparent;cursor:pointer}.date-picker-header button:hover{background-color:#f3f4f6;color:#111827}.date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.date-picker-weekdays span{text-align:center;font-size:.625rem;font-weight:600;color:#6b7280;padding:6px}.date-picker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.date-picker-day{aspect-ratio:1;border:none;background:transparent;border-radius:50%;font-size:.75rem;cursor:pointer;transition:all .15s ease;color:#374151;font-weight:400}.date-picker-day:hover:not(:disabled):not(.selected){background-color:#f3f4f6;color:#111827}.date-picker-day.empty{visibility:hidden}.date-picker-day.selected{background-color:#222;color:#fff;font-weight:600}.date-picker-day.in-range{background-color:#f9fafb;border-radius:0}.date-picker-day:disabled{cursor:not-allowed;opacity:.3}.date-picker-footer{padding:12px;border-top:1px solid #e1e4e8;display:flex;justify-content:center;gap:8px}.date-picker-footer .btn-clear{padding:8px 16px;background-color:#f6f8fa;border:1px solid #d0d7de;border-radius:6px;font-size:.875rem;font-weight:500;color:#24292f;cursor:pointer;transition:all .15s ease}.date-picker-footer .btn-clear:hover{background-color:#f3f4f6;border-color:#8c959f;transform:translateY(-1px);box-shadow:0 2px 4px #0000000d}.date-picker-footer .btn-clear:active{transform:translateY(0);box-shadow:none;background-color:#e9ecef}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }] });
|
|
268
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DualDatepickerComponent, isStandalone: true, selector: "ngx-dual-datepicker", inputs: { placeholder: "placeholder", fechaInicio: "fechaInicio", fechaFin: "fechaFin", showPresets: "showPresets", showClearButton: "showClearButton", closeOnSelection: "closeOnSelection", closeOnPresetSelection: "closeOnPresetSelection", closeOnClickOutside: "closeOnClickOutside", presets: "presets", inputBackgroundColor: "inputBackgroundColor", inputTextColor: "inputTextColor", inputBorderColor: "inputBorderColor", inputBorderColorHover: "inputBorderColorHover", inputBorderColorFocus: "inputBorderColorFocus", inputPadding: "inputPadding", locale: "locale" }, outputs: { dateRangeChange: "dateRangeChange", dateRangeSelected: "dateRangeSelected" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
|
|
269
|
+
{
|
|
270
|
+
provide: NG_VALUE_ACCESSOR,
|
|
271
|
+
useExisting: forwardRef(() => DualDatepickerComponent),
|
|
272
|
+
multi: true
|
|
273
|
+
}
|
|
274
|
+
], usesOnChanges: true, ngImport: i0, template: "<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas()\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [disabled]=\"isDisabled()\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker()) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesAnterior() }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesActual() }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".datepicker-wrapper{position:relative;width:100%}.datepicker-wrapper .datepicker-input{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;cursor:pointer}.datepicker-wrapper .datepicker-input:hover{border-color:var(--input-border-hover, #ced4da)}.datepicker-wrapper .datepicker-input:focus{border-color:var(--input-border-focus, #80bdff);box-shadow:0 0 0 .2rem #007bff40;outline:0}.datepicker-wrapper .datepicker-input::placeholder{color:#6c757d;opacity:1}.datepicker-wrapper .datepicker-input:disabled,.datepicker-wrapper .datepicker-input[readonly]{background-color:#e9ecef;opacity:1}.date-picker-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e1e4e8;border-radius:8px;box-shadow:0 4px 12px #00000014,0 0 1px #00000014;padding:16px;z-index:1060;min-width:680px}@media (max-width: 768px){.date-picker-dropdown{min-width:100%;left:0;right:0}}.date-picker-header-only-close{display:flex;justify-content:flex-end;margin-bottom:12px}.date-picker-header-only-close .btn-close-calendar{background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;border-radius:6px;cursor:pointer;transition:all .15s ease;font-size:1.5rem;line-height:1}.date-picker-header-only-close .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-header-only-close .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-presets{display:flex;gap:6px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #e5e7eb;align-items:center}@media (max-width: 768px){.date-picker-presets{flex-wrap:wrap}}.date-picker-presets button{font-size:.75rem;padding:6px 14px;border:none;background-color:#f9fafb;color:#374151;border-radius:6px;transition:all .15s ease;font-weight:500;cursor:pointer;border:1px solid #e5e7eb}.date-picker-presets button:hover{background-color:#f3f4f6;border-color:#d1d5db;transform:translateY(-1px);box-shadow:0 2px 4px #0000000f}.date-picker-presets button:active{transform:translateY(0);box-shadow:none}.date-picker-presets .btn-close-calendar{margin-left:auto;background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;font-size:1.5rem;line-height:1}.date-picker-presets .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-presets .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-calendars{display:flex;gap:32px}@media (max-width: 768px){.date-picker-calendars{flex-direction:column;gap:16px}}.date-picker-calendar{flex:1}.date-picker-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding:0 4px}.date-picker-header span{font-size:.813rem;font-weight:600;color:#111827}.date-picker-header button{padding:4px;color:#6b7280;text-decoration:none;border-radius:6px;transition:all .15s ease;border:none;background:transparent;cursor:pointer}.date-picker-header button:hover{background-color:#f3f4f6;color:#111827}.date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.date-picker-weekdays span{text-align:center;font-size:.625rem;font-weight:600;color:#6b7280;padding:6px}.date-picker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.date-picker-day{aspect-ratio:1;border:none;background:transparent;border-radius:50%;font-size:.75rem;cursor:pointer;transition:all .15s ease;color:#374151;font-weight:400}.date-picker-day:hover:not(:disabled):not(.selected){background-color:#f3f4f6;color:#111827}.date-picker-day.empty{visibility:hidden}.date-picker-day.selected{background-color:#222;color:#fff;font-weight:600}.date-picker-day.in-range{background-color:#f9fafb;border-radius:0}.date-picker-day:disabled{cursor:not-allowed;opacity:.3}.date-picker-footer{padding:12px;border-top:1px solid #e1e4e8;display:flex;justify-content:center;gap:8px}.date-picker-footer .btn-clear{padding:8px 16px;background-color:#f6f8fa;border:1px solid #d0d7de;border-radius:6px;font-size:.875rem;font-weight:500;color:#24292f;cursor:pointer;transition:all .15s ease}.date-picker-footer .btn-clear:hover{background-color:#f3f4f6;border-color:#8c959f;transform:translateY(-1px);box-shadow:0 2px 4px #0000000d}.date-picker-footer .btn-clear:active{transform:translateY(0);box-shadow:none;background-color:#e9ecef}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
|
|
215
275
|
}
|
|
216
276
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DualDatepickerComponent, decorators: [{
|
|
217
277
|
type: Component,
|
|
218
|
-
args: [{ selector: 'ngx-dual-datepicker', standalone: true, imports: [CommonModule, FormsModule
|
|
278
|
+
args: [{ selector: 'ngx-dual-datepicker', standalone: true, imports: [CommonModule, FormsModule, ReactiveFormsModule], providers: [
|
|
279
|
+
{
|
|
280
|
+
provide: NG_VALUE_ACCESSOR,
|
|
281
|
+
useExisting: forwardRef(() => DualDatepickerComponent),
|
|
282
|
+
multi: true
|
|
283
|
+
}
|
|
284
|
+
], template: "<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas()\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [disabled]=\"isDisabled()\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker()) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesAnterior() }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesActual() }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".datepicker-wrapper{position:relative;width:100%}.datepicker-wrapper .datepicker-input{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;cursor:pointer}.datepicker-wrapper .datepicker-input:hover{border-color:var(--input-border-hover, #ced4da)}.datepicker-wrapper .datepicker-input:focus{border-color:var(--input-border-focus, #80bdff);box-shadow:0 0 0 .2rem #007bff40;outline:0}.datepicker-wrapper .datepicker-input::placeholder{color:#6c757d;opacity:1}.datepicker-wrapper .datepicker-input:disabled,.datepicker-wrapper .datepicker-input[readonly]{background-color:#e9ecef;opacity:1}.date-picker-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e1e4e8;border-radius:8px;box-shadow:0 4px 12px #00000014,0 0 1px #00000014;padding:16px;z-index:1060;min-width:680px}@media (max-width: 768px){.date-picker-dropdown{min-width:100%;left:0;right:0}}.date-picker-header-only-close{display:flex;justify-content:flex-end;margin-bottom:12px}.date-picker-header-only-close .btn-close-calendar{background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;border-radius:6px;cursor:pointer;transition:all .15s ease;font-size:1.5rem;line-height:1}.date-picker-header-only-close .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-header-only-close .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-presets{display:flex;gap:6px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #e5e7eb;align-items:center}@media (max-width: 768px){.date-picker-presets{flex-wrap:wrap}}.date-picker-presets button{font-size:.75rem;padding:6px 14px;border:none;background-color:#f9fafb;color:#374151;border-radius:6px;transition:all .15s ease;font-weight:500;cursor:pointer;border:1px solid #e5e7eb}.date-picker-presets button:hover{background-color:#f3f4f6;border-color:#d1d5db;transform:translateY(-1px);box-shadow:0 2px 4px #0000000f}.date-picker-presets button:active{transform:translateY(0);box-shadow:none}.date-picker-presets .btn-close-calendar{margin-left:auto;background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;font-size:1.5rem;line-height:1}.date-picker-presets .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-presets .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-calendars{display:flex;gap:32px}@media (max-width: 768px){.date-picker-calendars{flex-direction:column;gap:16px}}.date-picker-calendar{flex:1}.date-picker-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding:0 4px}.date-picker-header span{font-size:.813rem;font-weight:600;color:#111827}.date-picker-header button{padding:4px;color:#6b7280;text-decoration:none;border-radius:6px;transition:all .15s ease;border:none;background:transparent;cursor:pointer}.date-picker-header button:hover{background-color:#f3f4f6;color:#111827}.date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.date-picker-weekdays span{text-align:center;font-size:.625rem;font-weight:600;color:#6b7280;padding:6px}.date-picker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.date-picker-day{aspect-ratio:1;border:none;background:transparent;border-radius:50%;font-size:.75rem;cursor:pointer;transition:all .15s ease;color:#374151;font-weight:400}.date-picker-day:hover:not(:disabled):not(.selected){background-color:#f3f4f6;color:#111827}.date-picker-day.empty{visibility:hidden}.date-picker-day.selected{background-color:#222;color:#fff;font-weight:600}.date-picker-day.in-range{background-color:#f9fafb;border-radius:0}.date-picker-day:disabled{cursor:not-allowed;opacity:.3}.date-picker-footer{padding:12px;border-top:1px solid #e1e4e8;display:flex;justify-content:center;gap:8px}.date-picker-footer .btn-clear{padding:8px 16px;background-color:#f6f8fa;border:1px solid #d0d7de;border-radius:6px;font-size:.875rem;font-weight:500;color:#24292f;cursor:pointer;transition:all .15s ease}.date-picker-footer .btn-clear:hover{background-color:#f3f4f6;border-color:#8c959f;transform:translateY(-1px);box-shadow:0 2px 4px #0000000d}.date-picker-footer .btn-clear:active{transform:translateY(0);box-shadow:none;background-color:#e9ecef}\n"] }]
|
|
219
285
|
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { placeholder: [{
|
|
220
286
|
type: Input
|
|
221
287
|
}], fechaInicio: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oneluiz-dual-datepicker.mjs","sources":["../../src/dual-datepicker.component.ts","../../src/dual-datepicker.component.html","../../src/public-api.ts","../../src/oneluiz-dual-datepicker.ts"],"sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, HostListener, ElementRef } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\n\nexport interface DateRange {\n fechaInicio: string;\n fechaFin: string;\n rangoTexto: string;\n}\n\nexport interface PresetConfig {\n label: string;\n daysAgo: number;\n}\n\nexport interface LocaleConfig {\n monthNames?: string[];\n monthNamesShort?: string[];\n dayNames?: string[];\n dayNamesShort?: string[];\n firstDayOfWeek?: number; // 0 = Sunday, 1 = Monday, etc.\n}\n\n@Component({\n selector: 'ngx-dual-datepicker',\n standalone: true,\n imports: [CommonModule, FormsModule],\n templateUrl: './dual-datepicker.component.html',\n styleUrl: './dual-datepicker.component.scss'\n})\nexport class DualDatepickerComponent implements OnInit, OnChanges {\n @Input() placeholder: string = 'Select date range';\n @Input() fechaInicio: string = '';\n @Input() fechaFin: string = '';\n @Input() showPresets: boolean = true;\n @Input() showClearButton: boolean = true;\n @Input() closeOnSelection: boolean = true;\n @Input() closeOnPresetSelection: boolean = true;\n @Input() closeOnClickOutside: boolean = true;\n @Input() presets: PresetConfig[] = [\n { label: 'Last month', daysAgo: 30 },\n { label: 'Last 6 months', daysAgo: 180 },\n { label: 'Last year', daysAgo: 365 }\n ];\n @Input() inputBackgroundColor: string = '#fff';\n @Input() inputTextColor: string = '#495057';\n @Input() inputBorderColor: string = '#ced4da';\n @Input() inputBorderColorHover: string = '#ced4da';\n @Input() inputBorderColorFocus: string = '#80bdff';\n @Input() inputPadding: string = '0.375rem 0.75rem';\n @Input() locale: LocaleConfig = {};\n\n @Output() dateRangeChange = new EventEmitter<DateRange>();\n @Output() dateRangeSelected = new EventEmitter<DateRange>();\n\n mostrarDatePicker = false;\n rangoFechas = '';\n fechaSeleccionandoInicio = true;\n mesActual = new Date();\n mesAnterior = new Date();\n diasMesActual: any[] = [];\n diasMesAnterior: any[] = [];\n\n private readonly defaultMonthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\n private readonly defaultMonthNamesShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n private readonly defaultDayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n private readonly defaultDayNamesShort = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];\n\n constructor(private elementRef: ElementRef) {}\n\n @HostListener('document:click', ['$event'])\n onClickOutside(event: MouseEvent): void {\n if (this.mostrarDatePicker && this.closeOnClickOutside) {\n const clickedInside = this.elementRef.nativeElement.contains(event.target);\n if (!clickedInside) {\n this.cerrarDatePicker();\n }\n }\n }\n\n ngOnInit(): void {\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['fechaInicio'] || changes['fechaFin']) {\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n } else if (!this.fechaInicio && !this.fechaFin) {\n this.rangoFechas = '';\n }\n }\n }\n\n formatearFecha(fecha: Date): string {\n const year = fecha.getFullYear();\n const month = String(fecha.getMonth() + 1).padStart(2, '0');\n const day = String(fecha.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n formatearFechaDisplay(fechaStr: string): string {\n if (!fechaStr) return '';\n const fecha = new Date(fechaStr + 'T00:00:00');\n const monthNames = this.locale.monthNamesShort || this.defaultMonthNamesShort;\n return `${fecha.getDate()} ${monthNames[fecha.getMonth()]}`;\n }\n\n actualizarRangoFechasTexto(): void {\n if (this.fechaInicio && this.fechaFin) {\n const inicio = this.formatearFechaDisplay(this.fechaInicio);\n const fin = this.formatearFechaDisplay(this.fechaFin);\n this.rangoFechas = `${inicio} - ${fin}`;\n } else {\n this.rangoFechas = '';\n }\n }\n\n toggleDatePicker(): void {\n this.mostrarDatePicker = !this.mostrarDatePicker;\n if (this.mostrarDatePicker) {\n this.fechaSeleccionandoInicio = true;\n this.mesAnterior = new Date(this.mesActual.getFullYear(), this.mesActual.getMonth() - 1, 1);\n this.generarCalendarios();\n }\n }\n\n cerrarDatePicker(): void {\n this.mostrarDatePicker = false;\n }\n\n generarCalendarios(): void {\n this.diasMesAnterior = this.generarCalendarioMes(this.mesAnterior);\n this.diasMesActual = this.generarCalendarioMes(this.mesActual);\n }\n\n generarCalendarioMes(fecha: Date): any[] {\n const año = fecha.getFullYear();\n const mes = fecha.getMonth();\n const primerDia = new Date(año, mes, 1);\n const ultimoDia = new Date(año, mes + 1, 0);\n const diasEnMes = ultimoDia.getDate();\n const primerDiaSemana = primerDia.getDay();\n\n const diasMes = [];\n\n for (let i = 0; i < primerDiaSemana; i++) {\n diasMes.push({ dia: null, esMesActual: false });\n }\n\n for (let dia = 1; dia <= diasEnMes; dia++) {\n const fechaDia = new Date(año, mes, dia);\n const fechaStr = this.formatearFecha(fechaDia);\n diasMes.push({\n dia: dia,\n fecha: fechaStr,\n esMesActual: true,\n esInicio: this.fechaInicio === fechaStr,\n esFin: this.fechaFin === fechaStr,\n enRango: this.estaEnRango(fechaStr)\n });\n }\n\n return diasMes;\n }\n\n estaEnRango(fechaStr: string): boolean {\n if (!this.fechaInicio || !this.fechaFin) return false;\n return fechaStr >= this.fechaInicio && fechaStr <= this.fechaFin;\n }\n\n seleccionarDia(diaObj: any): void {\n if (!diaObj.esMesActual) return;\n\n if (this.fechaSeleccionandoInicio) {\n this.fechaInicio = diaObj.fecha;\n this.fechaFin = '';\n this.rangoFechas = '';\n this.fechaSeleccionandoInicio = false;\n this.emitirCambio();\n } else {\n if (diaObj.fecha < this.fechaInicio) {\n this.fechaFin = this.fechaInicio;\n this.fechaInicio = diaObj.fecha;\n } else {\n this.fechaFin = diaObj.fecha;\n }\n this.actualizarRangoFechasTexto();\n if (this.closeOnSelection) {\n this.mostrarDatePicker = false;\n }\n this.fechaSeleccionandoInicio = true;\n this.emitirCambio();\n this.emitirSeleccion();\n }\n this.generarCalendarios();\n }\n\n cambiarMes(direccion: number): void {\n this.mesActual = new Date(this.mesActual.getFullYear(), this.mesActual.getMonth() + direccion, 1);\n this.mesAnterior = new Date(this.mesActual.getFullYear(), this.mesActual.getMonth() - 1, 1);\n this.generarCalendarios();\n }\n\n getNombreMes(fecha: Date): string {\n const monthNames = this.locale.monthNames || this.defaultMonthNames;\n return `${monthNames[fecha.getMonth()]} ${fecha.getFullYear()}`;\n }\n\n getDayNames(): string[] {\n return this.locale.dayNamesShort || this.defaultDayNamesShort;\n }\n\n seleccionarRangoPredefinido(preset: PresetConfig): void {\n const hoy = new Date();\n const fechaInicio = new Date(hoy);\n fechaInicio.setDate(hoy.getDate() - preset.daysAgo);\n\n this.fechaInicio = this.formatearFecha(fechaInicio);\n this.fechaFin = this.formatearFecha(hoy);\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n if (this.closeOnPresetSelection) {\n this.mostrarDatePicker = false;\n }\n this.emitirSeleccion();\n }\n\n limpiar(): void {\n this.fechaInicio = '';\n this.fechaFin = '';\n this.rangoFechas = '';\n this.mostrarDatePicker = false;\n this.fechaSeleccionandoInicio = true;\n this.emitirCambio();\n }\n\n private emitirCambio(): void {\n this.dateRangeChange.emit({\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas\n });\n }\n\n private emitirSeleccion(): void {\n this.dateRangeSelected.emit({\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas\n });\n }\n}\n","<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n ×\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n ×\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ getNombreMes(mesAnterior) }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of getDayNames(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior; track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ getNombreMes(mesActual) }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of getDayNames(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual; track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n","/**\n * Public API Surface of @oneluiz/dual-datepicker\n */\n\nexport { DualDatepickerComponent } from './dual-datepicker.component';\nexport type { DateRange, PresetConfig, LocaleConfig } from './dual-datepicker.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"oneluiz-dual-datepicker.mjs","sources":["../../src/dual-datepicker.component.ts","../../src/dual-datepicker.component.html","../../src/public-api.ts","../../src/oneluiz-dual-datepicker.ts"],"sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, HostListener, ElementRef, forwardRef, signal, computed, effect } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport interface DateRange {\n fechaInicio: string;\n fechaFin: string;\n rangoTexto: string;\n}\n\nexport interface PresetConfig {\n label: string;\n daysAgo: number;\n}\n\nexport interface LocaleConfig {\n monthNames?: string[];\n monthNamesShort?: string[];\n dayNames?: string[];\n dayNamesShort?: string[];\n firstDayOfWeek?: number; // 0 = Sunday, 1 = Monday, etc.\n}\n\n@Component({\n selector: 'ngx-dual-datepicker',\n standalone: true,\n imports: [CommonModule, FormsModule, ReactiveFormsModule],\n templateUrl: './dual-datepicker.component.html',\n styleUrl: './dual-datepicker.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DualDatepickerComponent),\n multi: true\n }\n ]\n})\nexport class DualDatepickerComponent implements OnInit, OnChanges, ControlValueAccessor {\n @Input() placeholder: string = 'Select date range';\n @Input() fechaInicio: string = '';\n @Input() fechaFin: string = '';\n @Input() showPresets: boolean = true;\n @Input() showClearButton: boolean = false;\n @Input() closeOnSelection: boolean = true;\n @Input() closeOnPresetSelection: boolean = true;\n @Input() closeOnClickOutside: boolean = true;\n @Input() presets: PresetConfig[] = [\n { label: 'Last month', daysAgo: 30 },\n { label: 'Last 6 months', daysAgo: 180 },\n { label: 'Last year', daysAgo: 365 }\n ];\n @Input() inputBackgroundColor: string = '#fff';\n @Input() inputTextColor: string = '#495057';\n @Input() inputBorderColor: string = '#ced4da';\n @Input() inputBorderColorHover: string = '#ced4da';\n @Input() inputBorderColorFocus: string = '#80bdff';\n @Input() inputPadding: string = '0.375rem 0.75rem';\n @Input() locale: LocaleConfig = {};\n\n @Output() dateRangeChange = new EventEmitter<DateRange>();\n @Output() dateRangeSelected = new EventEmitter<DateRange>();\n\n // Signals for reactive state\n mostrarDatePicker = signal(false);\n rangoFechas = signal('');\n fechaSeleccionandoInicio = signal(true);\n mesActual = signal(new Date());\n mesAnterior = signal(new Date());\n diasMesActual = signal<any[]>([]);\n diasMesAnterior = signal<any[]>([]);\n isDisabled = signal(false);\n\n // Computed values\n nombreMesActual = computed(() => this.getNombreMes(this.mesActual()));\n nombreMesAnterior = computed(() => this.getNombreMes(this.mesAnterior()));\n diasSemana = computed(() => this.getDayNames());\n\n private readonly defaultMonthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\n private readonly defaultMonthNamesShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n private readonly defaultDayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n private readonly defaultDayNamesShort = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];\n\n // ControlValueAccessor callbacks\n private onChange: (value: DateRange | null) => void = () => {};\n private onTouched: () => void = () => {};\n\n constructor(private elementRef: ElementRef) {\n // Effect to emit changes when dates change\n effect(() => {\n const rango = this.rangoFechas();\n if (this.fechaInicio || this.fechaFin) {\n this.onChange(this.getDateRangeValue());\n }\n });\n }\n\n @HostListener('document:click', ['$event'])\n onClickOutside(event: MouseEvent): void {\n if (this.mostrarDatePicker() && this.closeOnClickOutside) {\n const clickedInside = this.elementRef.nativeElement.contains(event.target);\n if (!clickedInside) {\n this.cerrarDatePicker();\n }\n }\n }\n\n ngOnInit(): void {\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['fechaInicio'] || changes['fechaFin']) {\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n } else if (!this.fechaInicio && !this.fechaFin) {\n this.rangoFechas.set('');\n }\n }\n }\n\n formatearFecha(fecha: Date): string {\n const year = fecha.getFullYear();\n const month = String(fecha.getMonth() + 1).padStart(2, '0');\n const day = String(fecha.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n formatearFechaDisplay(fechaStr: string): string {\n if (!fechaStr) return '';\n const fecha = new Date(fechaStr + 'T00:00:00');\n const monthNames = this.locale.monthNamesShort || this.defaultMonthNamesShort;\n return `${fecha.getDate()} ${monthNames[fecha.getMonth()]}`;\n }\n\n actualizarRangoFechasTexto(): void {\n if (this.fechaInicio && this.fechaFin) {\n const inicio = this.formatearFechaDisplay(this.fechaInicio);\n const fin = this.formatearFechaDisplay(this.fechaFin);\n this.rangoFechas.set(`${inicio} - ${fin}`);\n } else {\n this.rangoFechas.set('');\n }\n }\n\n toggleDatePicker(): void {\n this.mostrarDatePicker.update(value => !value);\n if (this.mostrarDatePicker()) {\n this.fechaSeleccionandoInicio.set(true);\n const mesActualValue = this.mesActual();\n this.mesAnterior.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() - 1, 1));\n this.generarCalendarios();\n }\n this.onTouched();\n }\n\n cerrarDatePicker(): void {\n this.mostrarDatePicker.set(false);\n this.onTouched();\n }\n\n generarCalendarios(): void {\n this.diasMesAnterior.set(this.generarCalendarioMes(this.mesAnterior()));\n this.diasMesActual.set(this.generarCalendarioMes(this.mesActual()));\n }\n\n generarCalendarioMes(fecha: Date): any[] {\n const año = fecha.getFullYear();\n const mes = fecha.getMonth();\n const primerDia = new Date(año, mes, 1);\n const ultimoDia = new Date(año, mes + 1, 0);\n const diasEnMes = ultimoDia.getDate();\n const primerDiaSemana = primerDia.getDay();\n\n const diasMes = [];\n\n for (let i = 0; i < primerDiaSemana; i++) {\n diasMes.push({ dia: null, esMesActual: false });\n }\n\n for (let dia = 1; dia <= diasEnMes; dia++) {\n const fechaDia = new Date(año, mes, dia);\n const fechaStr = this.formatearFecha(fechaDia);\n diasMes.push({\n dia: dia,\n fecha: fechaStr,\n esMesActual: true,\n esInicio: this.fechaInicio === fechaStr,\n esFin: this.fechaFin === fechaStr,\n enRango: this.estaEnRango(fechaStr)\n });\n }\n\n return diasMes;\n }\n\n estaEnRango(fechaStr: string): boolean {\n if (!this.fechaInicio || !this.fechaFin) return false;\n return fechaStr >= this.fechaInicio && fechaStr <= this.fechaFin;\n }\n\n seleccionarDia(diaObj: any): void {\n if (!diaObj.esMesActual || this.isDisabled()) return;\n\n if (this.fechaSeleccionandoInicio()) {\n this.fechaInicio = diaObj.fecha;\n this.fechaFin = '';\n this.rangoFechas.set('');\n this.fechaSeleccionandoInicio.set(false);\n this.emitirCambio();\n } else {\n if (diaObj.fecha < this.fechaInicio) {\n this.fechaFin = this.fechaInicio;\n this.fechaInicio = diaObj.fecha;\n } else {\n this.fechaFin = diaObj.fecha;\n }\n this.actualizarRangoFechasTexto();\n if (this.closeOnSelection) {\n this.mostrarDatePicker.set(false);\n }\n this.fechaSeleccionandoInicio.set(true);\n this.emitirCambio();\n this.emitirSeleccion();\n }\n this.generarCalendarios();\n }\n\n cambiarMes(direccion: number): void {\n const mesActualValue = this.mesActual();\n this.mesActual.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() + direccion, 1));\n const nuevoMesActual = this.mesActual();\n this.mesAnterior.set(new Date(nuevoMesActual.getFullYear(), nuevoMesActual.getMonth() - 1, 1));\n this.generarCalendarios();\n }\n\n getNombreMes(fecha: Date): string {\n const monthNames = this.locale.monthNames || this.defaultMonthNames;\n return `${monthNames[fecha.getMonth()]} ${fecha.getFullYear()}`;\n }\n\n getDayNames(): string[] {\n return this.locale.dayNamesShort || this.defaultDayNamesShort;\n }\n\n seleccionarRangoPredefinido(preset: PresetConfig): void {\n const hoy = new Date();\n const fechaInicio = new Date(hoy);\n fechaInicio.setDate(hoy.getDate() - preset.daysAgo);\n\n this.fechaInicio = this.formatearFecha(fechaInicio);\n this.fechaFin = this.formatearFecha(hoy);\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n if (this.closeOnPresetSelection) {\n this.mostrarDatePicker.set(false);\n }\n this.emitirSeleccion();\n }\n\n limpiar(): void {\n this.fechaInicio = '';\n this.fechaFin = '';\n this.rangoFechas.set('');\n this.mostrarDatePicker.set(false);\n this.fechaSeleccionandoInicio.set(true);\n this.emitirCambio();\n this.onTouched();\n }\n\n private emitirCambio(): void {\n this.dateRangeChange.emit({\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas()\n });\n }\n\n private emitirSeleccion(): void {\n this.dateRangeSelected.emit({\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas()\n });\n }\n\n private getDateRangeValue(): DateRange {\n return {\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas()\n };\n }\n\n // ControlValueAccessor implementation\n writeValue(value: DateRange | null): void {\n if (value) {\n this.fechaInicio = value.fechaInicio || '';\n this.fechaFin = value.fechaFin || '';\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n }\n } else {\n this.fechaInicio = '';\n this.fechaFin = '';\n this.rangoFechas.set('');\n }\n }\n\n registerOnChange(fn: (value: DateRange | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.isDisabled.set(isDisabled);\n }\n}\n","<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas()\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [disabled]=\"isDisabled()\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker()) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n ×\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n ×\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesAnterior() }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesActual() }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n","/**\n * Public API Surface of @oneluiz/dual-datepicker\n */\n\nexport { DualDatepickerComponent } from './dual-datepicker.component';\nexport type { DateRange, PresetConfig, LocaleConfig } from './dual-datepicker.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneluiz/dual-datepicker",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "A customizable dual-calendar date range picker component for Angular 17+",
|
|
3
|
+
"version": "2.4.0",
|
|
4
|
+
"description": "A customizable dual-calendar date range picker component for Angular 17+ with Reactive Forms and Signals support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
7
7
|
"datepicker",
|
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
"date-picker",
|
|
12
12
|
"angular-component",
|
|
13
13
|
"standalone",
|
|
14
|
-
"typescript"
|
|
14
|
+
"typescript",
|
|
15
|
+
"reactive-forms",
|
|
16
|
+
"signals",
|
|
17
|
+
"control-value-accessor"
|
|
15
18
|
],
|
|
16
19
|
"author": "Luis Cortes",
|
|
17
20
|
"license": "MIT",
|