@oneluiz/dual-datepicker 3.5.0 → 3.6.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.
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Native Date Adapter Implementation
3
+ *
4
+ * Default adapter using JavaScript Date with timezone-safe operations.
5
+ *
6
+ * Zero dependencies. Conservative implementation that:
7
+ * - Normalizes all dates to start of day (00:00:00.000)
8
+ * - Uses manual YYYY-MM-DD construction (avoids toISOString() timezone shift)
9
+ * - Parses ISO dates to local timezone (avoids UTC interpretation)
10
+ * - Handles month overflow correctly (Jan 31 + 1 month = Feb 28, not Mar 3)
11
+ * - All comparisons work on normalized dates
12
+ *
13
+ * Limitations:
14
+ * - No timezone awareness (all operations in local timezone)
15
+ * - No DST-safe calculations across timezone changes
16
+ * - For advanced timezone needs, use LuxonDateAdapter or DayJSDateAdapter
17
+ *
18
+ * Perfect for:
19
+ * ✅ Most enterprise apps (ERP, POS, BI) where local timezone is sufficient
20
+ * ✅ Applications without cross-timezone requirements
21
+ * ✅ Minimizing bundle size (zero deps)
22
+ * ✅ Simple, predictable date handling
23
+ */
24
+ import { Injectable } from '@angular/core';
25
+ import * as i0 from "@angular/core";
26
+ export class NativeDateAdapter {
27
+ /**
28
+ * Normalize date to start of day (00:00:00.000) in local timezone
29
+ *
30
+ * This is the foundation of timezone-safe operations.
31
+ * All other methods use normalized dates for comparisons.
32
+ */
33
+ normalize(date) {
34
+ const normalized = new Date(date);
35
+ normalized.setHours(0, 0, 0, 0);
36
+ return normalized;
37
+ }
38
+ /**
39
+ * Check if two dates are the same calendar day
40
+ *
41
+ * Implementation: Compare YYYY-MM-DD components directly
42
+ * Avoids timezone issues from valueOf() comparisons
43
+ */
44
+ isSameDay(a, b) {
45
+ return (a.getFullYear() === b.getFullYear() &&
46
+ a.getMonth() === b.getMonth() &&
47
+ a.getDate() === b.getDate());
48
+ }
49
+ /**
50
+ * Check if date A is before date B (calendar day level)
51
+ *
52
+ * Implementation: Compare normalized dates using valueOf()
53
+ */
54
+ isBeforeDay(a, b) {
55
+ return this.normalize(a).valueOf() < this.normalize(b).valueOf();
56
+ }
57
+ /**
58
+ * Check if date A is after date B (calendar day level)
59
+ *
60
+ * Implementation: Compare normalized dates using valueOf()
61
+ */
62
+ isAfterDay(a, b) {
63
+ return this.normalize(a).valueOf() > this.normalize(b).valueOf();
64
+ }
65
+ /**
66
+ * Add days to a date
67
+ *
68
+ * Implementation: Use setDate() which handles month rollover automatically
69
+ *
70
+ * Example:
71
+ * Jan 31 + 3 days → Feb 3 ✅
72
+ * Feb 28 + 1 day → Mar 1 ✅ (non-leap year)
73
+ */
74
+ addDays(date, days) {
75
+ const result = new Date(date);
76
+ result.setDate(result.getDate() + days);
77
+ return this.normalize(result);
78
+ }
79
+ /**
80
+ * Add months to a date
81
+ *
82
+ * CRITICAL: Handles month overflow correctly
83
+ *
84
+ * Algorithm:
85
+ * 1. Add months using setMonth()
86
+ * 2. If day-of-month changed (overflow), set to last day of target month
87
+ *
88
+ * Examples:
89
+ * - Jan 31 + 1 month → Feb 28 (or Feb 29 in leap year) ✅
90
+ * - Jan 31 + 2 months → Mar 31 ✅
91
+ * - Mar 31 + 1 month → Apr 30 ✅
92
+ * - Dec 31 + 1 month → Jan 31 (next year) ✅
93
+ */
94
+ addMonths(date, months) {
95
+ const result = new Date(date);
96
+ const originalDay = result.getDate();
97
+ // Add months
98
+ result.setMonth(result.getMonth() + months);
99
+ // Check for day overflow (e.g., Jan 31 → Feb 31 becomes Mar 3)
100
+ if (result.getDate() !== originalDay) {
101
+ // Overflow detected: set to last day of target month
102
+ // Go to 1st of next month, then subtract 1 day
103
+ result.setDate(0); // Sets to last day of previous month
104
+ }
105
+ return this.normalize(result);
106
+ }
107
+ /**
108
+ * Get start of day (00:00:00.000)
109
+ *
110
+ * Alias for normalize() with explicit intent
111
+ */
112
+ startOfDay(date) {
113
+ return this.normalize(date);
114
+ }
115
+ /**
116
+ * Get end of day (23:59:59.999)
117
+ *
118
+ * Useful for inclusive range queries
119
+ */
120
+ endOfDay(date) {
121
+ const result = new Date(date);
122
+ result.setHours(23, 59, 59, 999);
123
+ return result;
124
+ }
125
+ /**
126
+ * Get first day of month (00:00:00.000)
127
+ */
128
+ startOfMonth(date) {
129
+ const result = new Date(date);
130
+ result.setDate(1);
131
+ return this.normalize(result);
132
+ }
133
+ /**
134
+ * Get last day of month (23:59:59.999)
135
+ *
136
+ * Algorithm: Go to 1st of next month, subtract 1 day
137
+ */
138
+ endOfMonth(date) {
139
+ const result = new Date(date);
140
+ result.setMonth(result.getMonth() + 1, 0); // Day 0 = last day of previous month
141
+ return this.endOfDay(result);
142
+ }
143
+ /**
144
+ * Get year (4-digit)
145
+ */
146
+ getYear(date) {
147
+ return date.getFullYear();
148
+ }
149
+ /**
150
+ * Get month (0-11)
151
+ */
152
+ getMonth(date) {
153
+ return date.getMonth();
154
+ }
155
+ /**
156
+ * Get day of month (1-31)
157
+ */
158
+ getDate(date) {
159
+ return date.getDate();
160
+ }
161
+ /**
162
+ * Get day of week (0-6, Sunday=0)
163
+ */
164
+ getDay(date) {
165
+ return date.getDay();
166
+ }
167
+ /**
168
+ * Convert Date to ISO date string (YYYY-MM-DD)
169
+ *
170
+ * CRITICAL: DO NOT use toISOString() - it converts to UTC!
171
+ *
172
+ * Manual construction ensures local timezone is preserved:
173
+ *
174
+ * Example problem with toISOString():
175
+ * ```
176
+ * // Local timezone: GMT-6 (CST)
177
+ * const date = new Date('2026-02-21T23:00:00'); // 11 PM Feb 21 local
178
+ *
179
+ * // WRONG ❌
180
+ * date.toISOString().split('T')[0]
181
+ * // Returns "2026-02-22" (converted to UTC = Feb 22 05:00 AM)
182
+ *
183
+ * // CORRECT ✅
184
+ * toISODate(date)
185
+ * // Returns "2026-02-21" (local date preserved)
186
+ * ```
187
+ *
188
+ * Implementation: Build YYYY-MM-DD manually from local date components
189
+ */
190
+ toISODate(date) {
191
+ const year = date.getFullYear();
192
+ const month = String(date.getMonth() + 1).padStart(2, '0');
193
+ const day = String(date.getDate()).padStart(2, '0');
194
+ return `${year}-${month}-${day}`;
195
+ }
196
+ /**
197
+ * Parse ISO date string (YYYY-MM-DD) to Date
198
+ *
199
+ * CRITICAL: DO NOT use new Date(isoString) - may parse as UTC!
200
+ *
201
+ * Example problem with Date constructor:
202
+ * ```
203
+ * // Local timezone: GMT-6 (CST)
204
+ *
205
+ * // WRONG ❌
206
+ * new Date('2026-02-21')
207
+ * // Parsed as UTC: 2026-02-21T00:00:00Z
208
+ * // In local timezone: Feb 20, 2026 6:00 PM (previous day!)
209
+ *
210
+ * // CORRECT ✅
211
+ * parseISODate('2026-02-21')
212
+ * // Returns: 2026-02-21T00:00:00 local time
213
+ * ```
214
+ *
215
+ * Implementation: Parse components and construct Date in local timezone
216
+ */
217
+ parseISODate(isoDate) {
218
+ if (!isoDate || typeof isoDate !== 'string') {
219
+ return null;
220
+ }
221
+ // Match YYYY-MM-DD format
222
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(isoDate.trim());
223
+ if (!match) {
224
+ return null;
225
+ }
226
+ const year = parseInt(match[1], 10);
227
+ const month = parseInt(match[2], 10) - 1; // 0-indexed
228
+ const day = parseInt(match[3], 10);
229
+ // Validate ranges
230
+ if (month < 0 || month > 11) {
231
+ return null;
232
+ }
233
+ if (day < 1 || day > 31) {
234
+ return null;
235
+ }
236
+ // Construct date in local timezone
237
+ const date = new Date(year, month, day);
238
+ // Verify date is valid (e.g., Feb 31 would roll to Mar 3)
239
+ if (date.getFullYear() !== year ||
240
+ date.getMonth() !== month ||
241
+ date.getDate() !== day) {
242
+ return null;
243
+ }
244
+ return this.normalize(date);
245
+ }
246
+ /**
247
+ * Get week start day for locale
248
+ *
249
+ * Default: Sunday (0) for most locales
250
+ * Monday (1) for Europe, ISO 8601
251
+ *
252
+ * Implementation: Simple locale detection
253
+ * For advanced needs, use Intl.Locale or external library
254
+ */
255
+ getWeekStart(locale) {
256
+ if (!locale) {
257
+ locale = typeof navigator !== 'undefined' ? navigator.language : 'en-US';
258
+ }
259
+ // ISO 8601: Monday start
260
+ const mondayStartLocales = [
261
+ 'en-GB', 'en-IE', 'en-AU', 'en-NZ', 'en-CA',
262
+ 'es', 'es-ES', 'es-MX',
263
+ 'fr', 'fr-FR', 'fr-CA',
264
+ 'de', 'de-DE', 'de-AT', 'de-CH',
265
+ 'it', 'it-IT',
266
+ 'pt', 'pt-PT', 'pt-BR',
267
+ 'nl', 'nl-NL', 'nl-BE',
268
+ 'ru', 'ru-RU',
269
+ 'zh', 'zh-CN', 'zh-TW',
270
+ 'ja', 'ja-JP',
271
+ 'ko', 'ko-KR'
272
+ ];
273
+ const normalizedLocale = locale.toLowerCase();
274
+ const startsWithMonday = mondayStartLocales.some(loc => normalizedLocale.startsWith(loc.toLowerCase()));
275
+ return startsWithMonday ? 1 : 0;
276
+ }
277
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NativeDateAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
278
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NativeDateAdapter, providedIn: 'root' });
279
+ }
280
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NativeDateAdapter, decorators: [{
281
+ type: Injectable,
282
+ args: [{
283
+ providedIn: 'root'
284
+ }]
285
+ }] });
286
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF0aXZlLWRhdGUtYWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb3JlL25hdGl2ZS1kYXRlLWFkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQkc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQU0zQyxNQUFNLE9BQU8saUJBQWlCO0lBQzVCOzs7OztPQUtHO0lBQ0gsU0FBUyxDQUFDLElBQVU7UUFDbEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNoQyxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxTQUFTLENBQUMsQ0FBTyxFQUFFLENBQU87UUFDeEIsT0FBTyxDQUNMLENBQUMsQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUMsV0FBVyxFQUFFO1lBQ25DLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsUUFBUSxFQUFFO1lBQzdCLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQzVCLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFdBQVcsQ0FBQyxDQUFPLEVBQUUsQ0FBTztRQUMxQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNuRSxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFVBQVUsQ0FBQyxDQUFPLEVBQUUsQ0FBTztRQUN6QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFD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QixJQUFJLEVBQUUsT0FBTztZQUNiLElBQUksRUFBRSxPQUFPO1NBQ2QsQ0FBQztRQUVGLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzlDLE1BQU0sZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQ3JELGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FDL0MsQ0FBQztRQUVGLE9BQU8sZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7d0dBOVJVLGlCQUFpQjs0R0FBakIsaUJBQWlCLGNBRmhCLE1BQU07OzRGQUVQLGlCQUFpQjtrQkFIN0IsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE5hdGl2ZSBEYXRlIEFkYXB0ZXIgSW1wbGVtZW50YXRpb25cbiAqIFxuICogRGVmYXVsdCBhZGFwdGVyIHVzaW5nIEphdmFTY3JpcHQgRGF0ZSB3aXRoIHRpbWV6b25lLXNhZmUgb3BlcmF0aW9ucy5cbiAqIFxuICogWmVybyBkZXBlbmRlbmNpZXMuIENvbnNlcnZhdGl2ZSBpbXBsZW1lbnRhdGlvbiB0aGF0OlxuICogLSBOb3JtYWxpemVzIGFsbCBkYXRlcyB0byBzdGFydCBvZiBkYXkgKDAwOjAwOjAwLjAwMClcbiAqIC0gVXNlcyBtYW51YWwgWVlZWS1NTS1ERCBjb25zdHJ1Y3Rpb24gKGF2b2lkcyB0b0lTT1N0cmluZygpIHRpbWV6b25lIHNoaWZ0KVxuICogLSBQYXJzZXMgSVNPIGRhdGVzIHRvIGxvY2FsIHRpbWV6b25lIChhdm9pZHMgVVRDIGludGVycHJldGF0aW9uKVxuICogLSBIYW5kbGVzIG1vbnRoIG92ZXJmbG93IGNvcnJlY3RseSAoSmFuIDMxICsgMSBtb250aCA9IEZlYiAyOCwgbm90IE1hciAzKVxuICogLSBBbGwgY29tcGFyaXNvbnMgd29yayBvbiBub3JtYWxpemVkIGRhdGVzXG4gKiBcbiAqIExpbWl0YXRpb25zOlxuICogLSBObyB0aW1lem9uZSBhd2FyZW5lc3MgKGFsbCBvcGVyYXRpb25zIGluIGxvY2FsIHRpbWV6b25lKVxuICogLSBObyBEU1Qtc2FmZSBjYWxjdWxhdGlvbnMgYWNyb3NzIHRpbWV6b25lIGNoYW5nZXNcbiAqIC0gRm9yIGFkdmFuY2VkIHRpbWV6b25lIG5lZWRzLCB1c2UgTHV4b25EYXRlQWRhcHRlciBvciBEYXlKU0RhdGVBZGFwdGVyXG4gKiBcbiAqIFBlcmZlY3QgZm9yOlxuICog4pyFIE1vc3QgZW50ZXJwcmlzZSBhcHBzIChFUlAsIFBPUywgQkkpIHdoZXJlIGxvY2FsIHRpbWV6b25lIGlzIHN1ZmZpY2llbnRcbiAqIOKchSBBcHBsaWNhdGlvbnMgd2l0aG91dCBjcm9zcy10aW1lem9uZSByZXF1aXJlbWVudHNcbiAqIOKchSBNaW5pbWl6aW5nIGJ1bmRsZSBzaXplICh6ZXJvIGRlcHMpXG4gKiDinIUgU2ltcGxlLCBwcmVkaWN0YWJsZSBkYXRlIGhhbmRsaW5nXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRGF0ZUFkYXB0ZXIgfSBmcm9tICcuL2RhdGUtYWRhcHRlcic7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIE5hdGl2ZURhdGVBZGFwdGVyIGltcGxlbWVudHMgRGF0ZUFkYXB0ZXIge1xuICAvKipcbiAgICogTm9ybWFsaXplIGRhdGUgdG8gc3RhcnQgb2YgZGF5ICgwMDowMDowMC4wMDApIGluIGxvY2FsIHRpbWV6b25lXG4gICAqIFxuICAgKiBUaGlzIGlzIHRoZSBmb3VuZGF0aW9uIG9mIHRpbWV6b25lLXNhZmUgb3BlcmF0aW9ucy5cbiAgICogQWxsIG90aGVyIG1ldGhvZHMgdXNlIG5vcm1hbGl6ZWQgZGF0ZXMgZm9yIGNvbXBhcmlzb25zLlxuICAgKi9cbiAgbm9ybWFsaXplKGRhdGU6IERhdGUpOiBEYXRlIHtcbiAgICBjb25zdCBub3JtYWxpemVkID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgbm9ybWFsaXplZC5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgICByZXR1cm4gbm9ybWFsaXplZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0d28gZGF0ZXMgYXJlIHRoZSBzYW1lIGNhbGVuZGFyIGRheVxuICAgKiBcbiAgICogSW1wbGVtZW50YXRpb246IENvbXBhcmUgWVlZWS1NTS1ERCBjb21wb25lbnRzIGRpcmVjdGx5XG4gICAqIEF2b2lkcyB0aW1lem9uZSBpc3N1ZXMgZnJvbSB2YWx1ZU9mKCkgY29tcGFyaXNvbnNcbiAgICovXG4gIGlzU2FtZURheShhOiBEYXRlLCBiOiBEYXRlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGEuZ2V0RnVsbFllYXIoKSA9PT0gYi5nZXRGdWxsWWVhcigpICYmXG4gICAgICBhLmdldE1vbnRoKCkgPT09IGIuZ2V0TW9udGgoKSAmJlxuICAgICAgYS5nZXREYXRlKCkgPT09IGIuZ2V0RGF0ZSgpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBkYXRlIEEgaXMgYmVmb3JlIGRhdGUgQiAoY2FsZW5kYXIgZGF5IGxldmVsKVxuICAgKiBcbiAgICogSW1wbGVtZW50YXRpb246IENvbXBhcmUgbm9ybWFsaXplZCBkYXRlcyB1c2luZyB2YWx1ZU9mKClcbiAgICovXG4gIGlzQmVmb3JlRGF5KGE6IERhdGUsIGI6IERhdGUpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemUoYSkudmFsdWVPZigpIDwgdGhpcy5ub3JtYWxpemUoYikudmFsdWVPZigpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGRhdGUgQSBpcyBhZnRlciBkYXRlIEIgKGNhbGVuZGFyIGRheSBsZXZlbClcbiAgICogXG4gICAqIEltcGxlbWVudGF0aW9uOiBDb21wYXJlIG5vcm1hbGl6ZWQgZGF0ZXMgdXNpbmcgdmFsdWVPZigpXG4gICAqL1xuICBpc0FmdGVyRGF5KGE6IERhdGUsIGI6IERhdGUpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemUoYSkudmFsdWVPZigpID4gdGhpcy5ub3JtYWxpemUoYikudmFsdWVPZigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBkYXlzIHRvIGEgZGF0ZVxuICAgKiBcbiAgICogSW1wbGVtZW50YXRpb246IFVzZSBzZXREYXRlKCkgd2hpY2ggaGFuZGxlcyBtb250aCByb2xsb3ZlciBhdXRvbWF0aWNhbGx5XG4gICAqIFxuICAgKiBFeGFtcGxlOlxuICAgKiBKYW4gMzEgKyAzIGRheXMg4oaSIEZlYiAzIOKchVxuICAgKiBGZWIgMjggKyAxIGRheSDihpIgTWFyIDEg4pyFIChub24tbGVhcCB5ZWFyKVxuICAgKi9cbiAgYWRkRGF5cyhkYXRlOiBEYXRlLCBkYXlzOiBudW1iZXIpOiBEYXRlIHtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICByZXN1bHQuc2V0RGF0ZShyZXN1bHQuZ2V0RGF0ZSgpICsgZGF5cyk7XG4gICAgcmV0dXJuIHRoaXMubm9ybWFsaXplKHJlc3VsdCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIG1vbnRocyB0byBhIGRhdGVcbiAgICogXG4gICAqIENSSVRJQ0FMOiBIYW5kbGVzIG1vbnRoIG92ZXJmbG93IGNvcnJlY3RseVxuICAgKiBcbiAgICogQWxnb3JpdGhtOlxuICAgKiAxLiBBZGQgbW9udGhzIHVzaW5nIHNldE1vbnRoKClcbiAgICogMi4gSWYgZGF5LW9mLW1vbnRoIGNoYW5nZWQgKG92ZXJmbG93KSwgc2V0IHRvIGxhc3QgZGF5IG9mIHRhcmdldCBtb250aFxuICAgKiBcbiAgICogRXhhbXBsZXM6XG4gICAqIC0gSmFuIDMxICsgMSBtb250aCDihpIgRmViIDI4IChvciBGZWIgMjkgaW4gbGVhcCB5ZWFyKSDinIVcbiAgICogLSBKYW4gMzEgKyAyIG1vbnRocyDihpIgTWFyIDMxIOKchVxuICAgKiAtIE1hciAzMSArIDEgbW9udGgg4oaSIEFwciAzMCDinIVcbiAgICogLSBEZWMgMzEgKyAxIG1vbnRoIOKGkiBKYW4gMzEgKG5leHQgeWVhcikg4pyFXG4gICAqL1xuICBhZGRNb250aHMoZGF0ZTogRGF0ZSwgbW9udGhzOiBudW1iZXIpOiBEYXRlIHtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICBjb25zdCBvcmlnaW5hbERheSA9IHJlc3VsdC5nZXREYXRlKCk7XG4gICAgXG4gICAgLy8gQWRkIG1vbnRoc1xuICAgIHJlc3VsdC5zZXRNb250aChyZXN1bHQuZ2V0TW9udGgoKSArIG1vbnRocyk7XG4gICAgXG4gICAgLy8gQ2hlY2sgZm9yIGRheSBvdmVyZmxvdyAoZS5nLiwgSmFuIDMxIOKGkiBGZWIgMzEgYmVjb21lcyBNYXIgMylcbiAgICBpZiAocmVzdWx0LmdldERhdGUoKSAhPT0gb3JpZ2luYWxEYXkpIHtcbiAgICAgIC8vIE92ZXJmbG93IGRldGVjdGVkOiBzZXQgdG8gbGFzdCBkYXkgb2YgdGFyZ2V0IG1vbnRoXG4gICAgICAvLyBHbyB0byAxc3Qgb2YgbmV4dCBtb250aCwgdGhlbiBzdWJ0cmFjdCAxIGRheVxuICAgICAgcmVzdWx0LnNldERhdGUoMCk7IC8vIFNldHMgdG8gbGFzdCBkYXkgb2YgcHJldmlvdXMgbW9udGhcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHRoaXMubm9ybWFsaXplKHJlc3VsdCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHN0YXJ0IG9mIGRheSAoMDA6MDA6MDAuMDAwKVxuICAgKiBcbiAgICogQWxpYXMgZm9yIG5vcm1hbGl6ZSgpIHdpdGggZXhwbGljaXQgaW50ZW50XG4gICAqL1xuICBzdGFydE9mRGF5KGRhdGU6IERhdGUpOiBEYXRlIHtcbiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemUoZGF0ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGVuZCBvZiBkYXkgKDIzOjU5OjU5Ljk5OSlcbiAgICogXG4gICAqIFVzZWZ1bCBmb3IgaW5jbHVzaXZlIHJhbmdlIHF1ZXJpZXNcbiAgICovXG4gIGVuZE9mRGF5KGRhdGU6IERhdGUpOiBEYXRlIHtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICByZXN1bHQuc2V0SG91cnMoMjMsIDU5LCA1OSwgOTk5KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBmaXJzdCBkYXkgb2YgbW9udGggKDAwOjAwOjAwLjAwMClcbiAgICovXG4gIHN0YXJ0T2ZNb250aChkYXRlOiBEYXRlKTogRGF0ZSB7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgcmVzdWx0LnNldERhdGUoMSk7XG4gICAgcmV0dXJuIHRoaXMubm9ybWFsaXplKHJlc3VsdCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGxhc3QgZGF5IG9mIG1vbnRoICgyMzo1OTo1OS45OTkpXG4gICAqIFxuICAgKiBBbGdvcml0aG06IEdvIHRvIDFzdCBvZiBuZXh0IG1vbnRoLCBzdWJ0cmFjdCAxIGRheVxuICAgKi9cbiAgZW5kT2ZNb250aChkYXRlOiBEYXRlKTogRGF0ZSB7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgcmVzdWx0LnNldE1vbnRoKHJlc3VsdC5nZXRNb250aCgpICsgMSwgMCk7IC8vIERheSAwID0gbGFzdCBkYXkgb2YgcHJldmlvdXMgbW9udGhcbiAgICByZXR1cm4gdGhpcy5lbmRPZkRheShyZXN1bHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB5ZWFyICg0LWRpZ2l0KVxuICAgKi9cbiAgZ2V0WWVhcihkYXRlOiBEYXRlKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZGF0ZS5nZXRGdWxsWWVhcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBtb250aCAoMC0xMSlcbiAgICovXG4gIGdldE1vbnRoKGRhdGU6IERhdGUpOiBudW1iZXIge1xuICAgIHJldHVybiBkYXRlLmdldE1vbnRoKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGRheSBvZiBtb250aCAoMS0zMSlcbiAgICovXG4gIGdldERhdGUoZGF0ZTogRGF0ZSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0RGF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBkYXkgb2Ygd2VlayAoMC02LCBTdW5kYXk9MClcbiAgICovXG4gIGdldERheShkYXRlOiBEYXRlKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZGF0ZS5nZXREYXkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IERhdGUgdG8gSVNPIGRhdGUgc3RyaW5nIChZWVlZLU1NLUREKVxuICAgKiBcbiAgICogQ1JJVElDQUw6IERPIE5PVCB1c2UgdG9JU09TdHJpbmcoKSAtIGl0IGNvbnZlcnRzIHRvIFVUQyFcbiAgICogXG4gICAqIE1hbnVhbCBjb25zdHJ1Y3Rpb24gZW5zdXJlcyBsb2NhbCB0aW1lem9uZSBpcyBwcmVzZXJ2ZWQ6XG4gICAqIFxuICAgKiBFeGFtcGxlIHByb2JsZW0gd2l0aCB0b0lTT1N0cmluZygpOlxuICAgKiBgYGBcbiAgICogLy8gTG9jYWwgdGltZXpvbmU6IEdNVC02IChDU1QpXG4gICAqIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgnMjAyNi0wMi0yMVQyMzowMDowMCcpOyAvLyAxMSBQTSBGZWIgMjEgbG9jYWxcbiAgICogXG4gICAqIC8vIFdST05HIOKdjFxuICAgKiBkYXRlLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXVxuICAgKiAvLyBSZXR1cm5zIFwiMjAyNi0wMi0yMlwiIChjb252ZXJ0ZWQgdG8gVVRDID0gRmViIDIyIDA1OjAwIEFNKVxuICAgKiBcbiAgICogLy8gQ09SUkVDVCDinIVcbiAgICogdG9JU09EYXRlKGRhdGUpXG4gICAqIC8vIFJldHVybnMgXCIyMDI2LTAyLTIxXCIgKGxvY2FsIGRhdGUgcHJlc2VydmVkKVxuICAgKiBgYGBcbiAgICogXG4gICAqIEltcGxlbWVudGF0aW9uOiBCdWlsZCBZWVlZLU1NLUREIG1hbnVhbGx5IGZyb20gbG9jYWwgZGF0ZSBjb21wb25lbnRzXG4gICAqL1xuICB0b0lTT0RhdGUoZGF0ZTogRGF0ZSk6IHN0cmluZyB7XG4gICAgY29uc3QgeWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICBjb25zdCBtb250aCA9IFN0cmluZyhkYXRlLmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIGNvbnN0IGRheSA9IFN0cmluZyhkYXRlLmdldERhdGUoKSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICByZXR1cm4gYCR7eWVhcn0tJHttb250aH0tJHtkYXl9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBJU08gZGF0ZSBzdHJpbmcgKFlZWVktTU0tREQpIHRvIERhdGVcbiAgICogXG4gICAqIENSSVRJQ0FMOiBETyBOT1QgdXNlIG5ldyBEYXRlKGlzb1N0cmluZykgLSBtYXkgcGFyc2UgYXMgVVRDIVxuICAgKiBcbiAgICogRXhhbXBsZSBwcm9ibGVtIHdpdGggRGF0ZSBjb25zdHJ1Y3RvcjpcbiAgICogYGBgXG4gICAqIC8vIExvY2FsIHRpbWV6b25lOiBHTVQtNiAoQ1NUKVxuICAgKiBcbiAgICogLy8gV1JPTkcg4p2MXG4gICAqIG5ldyBEYXRlKCcyMDI2LTAyLTIxJylcbiAgICogLy8gUGFyc2VkIGFzIFVUQzogMjAyNi0wMi0yMVQwMDowMDowMFpcbiAgICogLy8gSW4gbG9jYWwgdGltZXpvbmU6IEZlYiAyMCwgMjAyNiA2OjAwIFBNIChwcmV2aW91cyBkYXkhKVxuICAgKiBcbiAgICogLy8gQ09SUkVDVCDinIVcbiAgICogcGFyc2VJU09EYXRlKCcyMDI2LTAyLTIxJylcbiAgICogLy8gUmV0dXJuczogMjAyNi0wMi0yMVQwMDowMDowMCBsb2NhbCB0aW1lXG4gICAqIGBgYFxuICAgKiBcbiAgICogSW1wbGVtZW50YXRpb246IFBhcnNlIGNvbXBvbmVudHMgYW5kIGNvbnN0cnVjdCBEYXRlIGluIGxvY2FsIHRpbWV6b25lXG4gICAqL1xuICBwYXJzZUlTT0RhdGUoaXNvRGF0ZTogc3RyaW5nKTogRGF0ZSB8IG51bGwge1xuICAgIGlmICghaXNvRGF0ZSB8fCB0eXBlb2YgaXNvRGF0ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIE1hdGNoIFlZWVktTU0tREQgZm9ybWF0XG4gICAgY29uc3QgbWF0Y2ggPSAvXihcXGR7NH0pLShcXGR7Mn0pLShcXGR7Mn0pJC8uZXhlYyhpc29EYXRlLnRyaW0oKSk7XG4gICAgXG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgeWVhciA9IHBhcnNlSW50KG1hdGNoWzFdLCAxMCk7XG4gICAgY29uc3QgbW9udGggPSBwYXJzZUludChtYXRjaFsyXSwgMTApIC0gMTsgLy8gMC1pbmRleGVkXG4gICAgY29uc3QgZGF5ID0gcGFyc2VJbnQobWF0Y2hbM10sIDEwKTtcblxuICAgIC8vIFZhbGlkYXRlIHJhbmdlc1xuICAgIGlmIChtb250aCA8IDAgfHwgbW9udGggPiAxMSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGRheSA8IDEgfHwgZGF5ID4gMzEpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIENvbnN0cnVjdCBkYXRlIGluIGxvY2FsIHRpbWV6b25lXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXkpO1xuICAgIFxuICAgIC8vIFZlcmlmeSBkYXRlIGlzIHZhbGlkIChlLmcuLCBGZWIgMzEgd291bGQgcm9sbCB0byBNYXIgMylcbiAgICBpZiAoXG4gICAgICBkYXRlLmdldEZ1bGxZZWFyKCkgIT09IHllYXIgfHxcbiAgICAgIGRhdGUuZ2V0TW9udGgoKSAhPT0gbW9udGggfHxcbiAgICAgIGRhdGUuZ2V0RGF0ZSgpICE9PSBkYXlcbiAgICApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZShkYXRlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgd2VlayBzdGFydCBkYXkgZm9yIGxvY2FsZVxuICAgKiBcbiAgICogRGVmYXVsdDogU3VuZGF5ICgwKSBmb3IgbW9zdCBsb2NhbGVzXG4gICAqIE1vbmRheSAoMSkgZm9yIEV1cm9wZSwgSVNPIDg2MDFcbiAgICogXG4gICAqIEltcGxlbWVudGF0aW9uOiBTaW1wbGUgbG9jYWxlIGRldGVjdGlvblxuICAgKiBGb3IgYWR2YW5jZWQgbmVlZHMsIHVzZSBJbnRsLkxvY2FsZSBvciBleHRlcm5hbCBsaWJyYXJ5XG4gICAqL1xuICBnZXRXZWVrU3RhcnQobG9jYWxlPzogc3RyaW5nKTogMCB8IDEgfCAyIHwgMyB8IDQgfCA1IHwgNiB7XG4gICAgaWYgKCFsb2NhbGUpIHtcbiAgICAgIGxvY2FsZSA9IHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnID8gbmF2aWdhdG9yLmxhbmd1YWdlIDogJ2VuLVVTJztcbiAgICB9XG5cbiAgICAvLyBJU08gODYwMTogTW9uZGF5IHN0YXJ0XG4gICAgY29uc3QgbW9uZGF5U3RhcnRMb2NhbGVzID0gW1xuICAgICAgJ2VuLUdCJywgJ2VuLUlFJywgJ2VuLUFVJywgJ2VuLU5aJywgJ2VuLUNBJyxcbiAgICAgICdlcycsICdlcy1FUycsICdlcy1NWCcsXG4gICAgICAnZnInLCAnZnItRlInLCAnZnItQ0EnLFxuICAgICAgJ2RlJywgJ2RlLURFJywgJ2RlLUFUJywgJ2RlLUNIJyxcbiAgICAgICdpdCcsICdpdC1JVCcsXG4gICAgICAncHQnLCAncHQtUFQnLCAncHQtQlInLFxuICAgICAgJ25sJywgJ25sLU5MJywgJ25sLUJFJyxcbiAgICAgICdydScsICdydS1SVScsXG4gICAgICAnemgnLCAnemgtQ04nLCAnemgtVFcnLFxuICAgICAgJ2phJywgJ2phLUpQJyxcbiAgICAgICdrbycsICdrby1LUidcbiAgICBdO1xuXG4gICAgY29uc3Qgbm9ybWFsaXplZExvY2FsZSA9IGxvY2FsZS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IHN0YXJ0c1dpdGhNb25kYXkgPSBtb25kYXlTdGFydExvY2FsZXMuc29tZShsb2MgPT4gXG4gICAgICBub3JtYWxpemVkTG9jYWxlLnN0YXJ0c1dpdGgobG9jLnRvTG93ZXJDYXNlKCkpXG4gICAgKTtcblxuICAgIHJldHVybiBzdGFydHNXaXRoTW9uZGF5ID8gMSA6IDA7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Provider Functions for Built-in Presets
3
+ *
4
+ * Version: 3.6.0
5
+ *
6
+ * Automatic registration of built-in date range presets.
7
+ * These providers ensure backward compatibility by auto-registering
8
+ * all standard presets (TODAY, LAST_7_DAYS, THIS_MONTH, etc.)
9
+ *
10
+ * USAGE IN LIBRARY (Internal):
11
+ * Built-in presets are registered automatically via Angular providers.
12
+ * Library consumers don't need to do anything.
13
+ *
14
+ * USAGE IN APP (Custom Presets):
15
+ * ```typescript
16
+ * // app.config.ts
17
+ * export const appConfig: ApplicationConfig = {
18
+ * providers: [
19
+ * // ... other providers
20
+ * provideCustomPresets([
21
+ * {
22
+ * key: 'THIS_FISCAL_QUARTER',
23
+ * resolve: (clock, adapter) => {
24
+ * const now = clock.now();
25
+ * // ... fiscal logic
26
+ * return { start, end };
27
+ * }
28
+ * }
29
+ * ])
30
+ * ]
31
+ * };
32
+ * ```
33
+ */
34
+ import { APP_INITIALIZER, makeEnvironmentProviders } from '@angular/core';
35
+ import { PresetRegistry } from './preset-registry';
36
+ import { BUILT_IN_PRESETS } from './built-in-presets';
37
+ /**
38
+ * Initializer function that registers built-in presets
39
+ *
40
+ * Runs at application startup (APP_INITIALIZER)
41
+ *
42
+ * @param registry - PresetRegistry instance
43
+ * @returns Initialization function
44
+ */
45
+ function initializeBuiltInPresets(registry) {
46
+ return () => {
47
+ // Register all built-in presets
48
+ BUILT_IN_PRESETS.forEach(preset => {
49
+ registry.register(preset);
50
+ });
51
+ // Log registration for debugging (can be removed in production)
52
+ if (typeof console !== 'undefined' && console.debug) {
53
+ console.debug(`[ng-dual-datepicker] Registered ${BUILT_IN_PRESETS.length} built-in presets:`, BUILT_IN_PRESETS.map(p => p.key).join(', '));
54
+ }
55
+ };
56
+ }
57
+ /**
58
+ * Provide built-in date range presets
59
+ *
60
+ * This provider is automatically included in the library's root providers.
61
+ * Library consumers don't need to add this manually.
62
+ *
63
+ * @returns EnvironmentProviders for built-in presets
64
+ *
65
+ * @internal
66
+ */
67
+ export function provideBuiltInPresets() {
68
+ return makeEnvironmentProviders([
69
+ {
70
+ provide: APP_INITIALIZER,
71
+ multi: true,
72
+ useFactory: initializeBuiltInPresets,
73
+ deps: [PresetRegistry]
74
+ }
75
+ ]);
76
+ }
77
+ /**
78
+ * Provide custom date range presets
79
+ *
80
+ * Use this to register your own industry-specific presets:
81
+ * - Fiscal presets
82
+ * - Hotel/hospitality presets
83
+ * - Logistics presets
84
+ * - Custom business logic
85
+ *
86
+ * @param presets - Array of custom RangePresetPlugin implementations
87
+ * @returns EnvironmentProviders for custom presets
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * // Fiscal presets
92
+ * const FISCAL_PRESETS: RangePresetPlugin[] = [
93
+ * {
94
+ * key: 'THIS_FISCAL_QUARTER',
95
+ * resolve: (clock, adapter) => {
96
+ * const now = clock.now();
97
+ * const month = adapter.getMonth(now);
98
+ *
99
+ * // Fiscal year starts April (month 3)
100
+ * const fiscalMonth = (month + 9) % 12;
101
+ * const quarterStart = Math.floor(fiscalMonth / 3) * 3;
102
+ * const calendarMonth = (quarterStart - 9 + 12) % 12;
103
+ *
104
+ * const year = adapter.getYear(now);
105
+ * const fiscalYear = month < 3 ? year - 1 : year;
106
+ *
107
+ * const start = new Date(fiscalYear, calendarMonth, 1);
108
+ * const end = new Date(fiscalYear, calendarMonth + 3, 0);
109
+ *
110
+ * return {
111
+ * start: adapter.normalize(start),
112
+ * end: adapter.normalize(end)
113
+ * };
114
+ * }
115
+ * },
116
+ * {
117
+ * key: 'FISCAL_YEAR_TO_DATE',
118
+ * resolve: (clock, adapter) => {
119
+ * const now = clock.now();
120
+ * const month = adapter.getMonth(now);
121
+ * const year = adapter.getYear(now);
122
+ *
123
+ * // Fiscal year starts April 1
124
+ * const fiscalYearStart = month >= 3
125
+ * ? new Date(year, 3, 1)
126
+ * : new Date(year - 1, 3, 1);
127
+ *
128
+ * return {
129
+ * start: adapter.normalize(fiscalYearStart),
130
+ * end: adapter.normalize(now)
131
+ * };
132
+ * }
133
+ * }
134
+ * ];
135
+ *
136
+ * // In app.config.ts
137
+ * export const appConfig: ApplicationConfig = {
138
+ * providers: [
139
+ * provideCustomPresets(FISCAL_PRESETS)
140
+ * ]
141
+ * };
142
+ *
143
+ * // Use in components
144
+ * store.applyPreset('THIS_FISCAL_QUARTER');
145
+ * store.applyPreset('FISCAL_YEAR_TO_DATE');
146
+ * ```
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * // Hotel presets
151
+ * const HOTEL_PRESETS: RangePresetPlugin[] = [
152
+ * {
153
+ * key: 'CHECK_IN_WEEK',
154
+ * resolve: (clock, adapter) => {
155
+ * const now = clock.now();
156
+ * const dayOfWeek = adapter.getDayOfWeek(now);
157
+ *
158
+ * // Check-in week: Friday to Friday
159
+ * const daysToNextFriday = dayOfWeek <= 5
160
+ * ? 5 - dayOfWeek
161
+ * : 7 - dayOfWeek + 5;
162
+ *
163
+ * const nextFriday = adapter.addDays(now, daysToNextFriday);
164
+ * const followingFriday = adapter.addDays(nextFriday, 7);
165
+ *
166
+ * return { start: nextFriday, end: followingFriday };
167
+ * }
168
+ * },
169
+ * {
170
+ * key: 'NEXT_30_NIGHTS',
171
+ * resolve: (clock, adapter) => {
172
+ * const now = clock.now();
173
+ * const tomorrow = adapter.addDays(now, 1);
174
+ * const end = adapter.addDays(tomorrow, 30);
175
+ * return { start: tomorrow, end };
176
+ * }
177
+ * }
178
+ * ];
179
+ *
180
+ * providers: [provideCustomPresets(HOTEL_PRESETS)]
181
+ * ```
182
+ */
183
+ export function provideCustomPresets(presets) {
184
+ return makeEnvironmentProviders([
185
+ {
186
+ provide: APP_INITIALIZER,
187
+ multi: true,
188
+ useFactory: (registry) => {
189
+ return () => {
190
+ presets.forEach(preset => {
191
+ registry.register(preset);
192
+ });
193
+ if (typeof console !== 'undefined' && console.debug) {
194
+ console.debug(`[ng-dual-datepicker] Registered ${presets.length} custom presets:`, presets.map(p => p.key).join(', '));
195
+ }
196
+ };
197
+ },
198
+ deps: [PresetRegistry]
199
+ }
200
+ ]);
201
+ }
202
+ /**
203
+ * Provide preset package
204
+ *
205
+ * Convenience function for external preset packages.
206
+ *
207
+ * @param packageName - Name of the preset package (for logging)
208
+ * @param presets - Array of presets from the package
209
+ * @returns EnvironmentProviders
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * // @acme/fiscal-presets package
214
+ * export function provideFiscalPresets(): EnvironmentProviders {
215
+ * return providePresetPackage('@acme/fiscal-presets', FISCAL_PRESETS);
216
+ * }
217
+ *
218
+ * // In app
219
+ * import { provideFiscalPresets } from '@acme/fiscal-presets';
220
+ *
221
+ * providers: [provideFiscalPresets()]
222
+ * ```
223
+ */
224
+ export function providePresetPackage(packageName, presets) {
225
+ return makeEnvironmentProviders([
226
+ {
227
+ provide: APP_INITIALIZER,
228
+ multi: true,
229
+ useFactory: (registry) => {
230
+ return () => {
231
+ presets.forEach(preset => {
232
+ registry.register(preset);
233
+ });
234
+ if (typeof console !== 'undefined' && console.debug) {
235
+ console.debug(`[${packageName}] Registered ${presets.length} presets:`, presets.map(p => p.key).join(', '));
236
+ }
237
+ };
238
+ },
239
+ deps: [PresetRegistry]
240
+ }
241
+ ]);
242
+ }
243
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlc2V0LXByb3ZpZGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb3JlL3ByZXNldC1wcm92aWRlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBRUgsT0FBTyxFQUFFLGVBQWUsRUFBd0Isd0JBQXdCLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDeEcsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBR3REOzs7Ozs7O0dBT0c7QUFDSCxTQUFTLHdCQUF3QixDQUFDLFFBQXdCO0lBQ3hELE9BQU8sR0FBRyxFQUFFO1FBQ1YsZ0NBQWdDO1FBQ2hDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNoQyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDO1FBRUgsZ0VBQWdFO1FBQ2hFLElBQUksT0FBTyxPQUFPLEtBQUssV0FBVyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNwRCxPQUFPLENBQUMsS0FBSyxDQUNYLG1DQUFtQyxnQkFBZ0IsQ0FBQyxNQUFNLG9CQUFvQixFQUM5RSxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUM1QyxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCO0lBQ25DLE9BQU8sd0JBQXdCLENBQUM7UUFDOUI7WUFDRSxPQUFPLEVBQUUsZUFBZTtZQUN4QixLQUFLLEVBQUUsSUFBSTtZQUNYLFVBQVUsRUFBRSx3QkFBd0I7WUFDcEMsSUFBSSxFQUFFLENBQUMsY0FBYyxDQUFDO1NBQ3ZCO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5R0c7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsT0FBNEI7SUFDL0QsT0FBTyx3QkFBd0IsQ0FBQztRQUM5QjtZQUNFLE9BQU8sRUFBRSxlQUFlO1lBQ3hCLEtBQUssRUFBRSxJQUFJO1lBQ1gsVUFBVSxFQUFFLENBQUMsUUFBd0IsRUFBRSxFQUFFO2dCQUN2QyxPQUFPLEdBQUcsRUFBRTtvQkFDVixPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO3dCQUN2QixRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUM1QixDQUFDLENBQUMsQ0FBQztvQkFFSCxJQUFJLE9BQU8sT0FBTyxLQUFLLFdBQVcsSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7d0JBQ3BELE9BQU8sQ0FBQyxLQUFLLENBQ1gsbUNBQW1DLE9BQU8sQ0FBQyxNQUFNLGtCQUFrQixFQUNuRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDbkMsQ0FBQztvQkFDSixDQUFDO2dCQUNILENBQUMsQ0FBQztZQUNKLENBQUM7WUFDRCxJQUFJLEVBQUUsQ0FBQyxjQUFjLENBQUM7U0FDdkI7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FDbEMsV0FBbUIsRUFDbkIsT0FBNEI7SUFFNUIsT0FBTyx3QkFBd0IsQ0FBQztRQUM5QjtZQUNFLE9BQU8sRUFBRSxlQUFlO1lBQ3hCLEtBQUssRUFBRSxJQUFJO1lBQ1gsVUFBVSxFQUFFLENBQUMsUUFBd0IsRUFBRSxFQUFFO2dCQUN2QyxPQUFPLEdBQUcsRUFBRTtvQkFDVixPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO3dCQUN2QixRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUM1QixDQUFDLENBQUMsQ0FBQztvQkFFSCxJQUFJLE9BQU8sT0FBTyxLQUFLLFdBQVcsSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7d0JBQ3BELE9BQU8sQ0FBQyxLQUFLLENBQ1gsSUFBSSxXQUFXLGdCQUFnQixPQUFPLENBQUMsTUFBTSxXQUFXLEVBQ3hELE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUNuQyxDQUFDO29CQUNKLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDO1lBQ0osQ0FBQztZQUNELElBQUksRUFBRSxDQUFDLGNBQWMsQ0FBQztTQUN2QjtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFByb3ZpZGVyIEZ1bmN0aW9ucyBmb3IgQnVpbHQtaW4gUHJlc2V0c1xuICogXG4gKiBWZXJzaW9uOiAzLjYuMFxuICogXG4gKiBBdXRvbWF0aWMgcmVnaXN0cmF0aW9uIG9mIGJ1aWx0LWluIGRhdGUgcmFuZ2UgcHJlc2V0cy5cbiAqIFRoZXNlIHByb3ZpZGVycyBlbnN1cmUgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBieSBhdXRvLXJlZ2lzdGVyaW5nXG4gKiBhbGwgc3RhbmRhcmQgcHJlc2V0cyAoVE9EQVksIExBU1RfN19EQVlTLCBUSElTX01PTlRILCBldGMuKVxuICogXG4gKiBVU0FHRSBJTiBMSUJSQVJZIChJbnRlcm5hbCk6XG4gKiBCdWlsdC1pbiBwcmVzZXRzIGFyZSByZWdpc3RlcmVkIGF1dG9tYXRpY2FsbHkgdmlhIEFuZ3VsYXIgcHJvdmlkZXJzLlxuICogTGlicmFyeSBjb25zdW1lcnMgZG9uJ3QgbmVlZCB0byBkbyBhbnl0aGluZy5cbiAqIFxuICogVVNBR0UgSU4gQVBQIChDdXN0b20gUHJlc2V0cyk6XG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBhcHAuY29uZmlnLnRzXG4gKiBleHBvcnQgY29uc3QgYXBwQ29uZmlnOiBBcHBsaWNhdGlvbkNvbmZpZyA9IHtcbiAqICAgcHJvdmlkZXJzOiBbXG4gKiAgICAgLy8gLi4uIG90aGVyIHByb3ZpZGVyc1xuICogICAgIHByb3ZpZGVDdXN0b21QcmVzZXRzKFtcbiAqICAgICAgIHtcbiAqICAgICAgICAga2V5OiAnVEhJU19GSVNDQUxfUVVBUlRFUicsXG4gKiAgICAgICAgIHJlc29sdmU6IChjbG9jaywgYWRhcHRlcikgPT4ge1xuICogICAgICAgICAgIGNvbnN0IG5vdyA9IGNsb2NrLm5vdygpO1xuICogICAgICAgICAgIC8vIC4uLiBmaXNjYWwgbG9naWNcbiAqICAgICAgICAgICByZXR1cm4geyBzdGFydCwgZW5kIH07XG4gKiAgICAgICAgIH1cbiAqICAgICAgIH1cbiAqICAgICBdKVxuICogICBdXG4gKiB9O1xuICogYGBgXG4gKi9cblxuaW1wb3J0IHsgQVBQX0lOSVRJQUxJWkVSLCBFbnZpcm9ubWVudFByb3ZpZGVycywgbWFrZUVudmlyb25tZW50UHJvdmlkZXJzLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFByZXNldFJlZ2lzdHJ5IH0gZnJvbSAnLi9wcmVzZXQtcmVnaXN0cnknO1xuaW1wb3J0IHsgQlVJTFRfSU5fUFJFU0VUUyB9IGZyb20gJy4vYnVpbHQtaW4tcHJlc2V0cyc7XG5pbXBvcnQgeyBSYW5nZVByZXNldFBsdWdpbiB9IGZyb20gJy4vcmFuZ2UtcHJlc2V0LnBsdWdpbic7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXIgZnVuY3Rpb24gdGhhdCByZWdpc3RlcnMgYnVpbHQtaW4gcHJlc2V0c1xuICogXG4gKiBSdW5zIGF0IGFwcGxpY2F0aW9uIHN0YXJ0dXAgKEFQUF9JTklUSUFMSVpFUilcbiAqIFxuICogQHBhcmFtIHJlZ2lzdHJ5IC0gUHJlc2V0UmVnaXN0cnkgaW5zdGFuY2VcbiAqIEByZXR1cm5zIEluaXRpYWxpemF0aW9uIGZ1bmN0aW9uXG4gKi9cbmZ1bmN0aW9uIGluaXRpYWxpemVCdWlsdEluUHJlc2V0cyhyZWdpc3RyeTogUHJlc2V0UmVnaXN0cnkpOiAoKSA9PiB2b2lkIHtcbiAgcmV0dXJuICgpID0+IHtcbiAgICAvLyBSZWdpc3RlciBhbGwgYnVpbHQtaW4gcHJlc2V0c1xuICAgIEJVSUxUX0lOX1BSRVNFVFMuZm9yRWFjaChwcmVzZXQgPT4ge1xuICAgICAgcmVnaXN0cnkucmVnaXN0ZXIocHJlc2V0KTtcbiAgICB9KTtcblxuICAgIC8vIExvZyByZWdpc3RyYXRpb24gZm9yIGRlYnVnZ2luZyAoY2FuIGJlIHJlbW92ZWQgaW4gcHJvZHVjdGlvbilcbiAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmIGNvbnNvbGUuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoXG4gICAgICAgIGBbbmctZHVhbC1kYXRlcGlja2VyXSBSZWdpc3RlcmVkICR7QlVJTFRfSU5fUFJFU0VUUy5sZW5ndGh9IGJ1aWx0LWluIHByZXNldHM6YCxcbiAgICAgICAgQlVJTFRfSU5fUFJFU0VUUy5tYXAocCA9PiBwLmtleSkuam9pbignLCAnKVxuICAgICAgKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogUHJvdmlkZSBidWlsdC1pbiBkYXRlIHJhbmdlIHByZXNldHNcbiAqIFxuICogVGhpcyBwcm92aWRlciBpcyBhdXRvbWF0aWNhbGx5IGluY2x1ZGVkIGluIHRoZSBsaWJyYXJ5J3Mgcm9vdCBwcm92aWRlcnMuXG4gKiBMaWJyYXJ5IGNvbnN1bWVycyBkb24ndCBuZWVkIHRvIGFkZCB0aGlzIG1hbnVhbGx5LlxuICogXG4gKiBAcmV0dXJucyBFbnZpcm9ubWVudFByb3ZpZGVycyBmb3IgYnVpbHQtaW4gcHJlc2V0c1xuICogXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb3ZpZGVCdWlsdEluUHJlc2V0cygpOiBFbnZpcm9ubWVudFByb3ZpZGVycyB7XG4gIHJldHVybiBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMoW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IEFQUF9JTklUSUFMSVpFUixcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgICAgdXNlRmFjdG9yeTogaW5pdGlhbGl6ZUJ1aWx0SW5QcmVzZXRzLFxuICAgICAgZGVwczogW1ByZXNldFJlZ2lzdHJ5XVxuICAgIH1cbiAgXSk7XG59XG5cbi8qKlxuICogUHJvdmlkZSBjdXN0b20gZGF0ZSByYW5nZSBwcmVzZXRzXG4gKiBcbiAqIFVzZSB0aGlzIHRvIHJlZ2lzdGVyIHlvdXIgb3duIGluZHVzdHJ5LXNwZWNpZmljIHByZXNldHM6XG4gKiAtIEZpc2NhbCBwcmVzZXRzXG4gKiAtIEhvdGVsL2hvc3BpdGFsaXR5IHByZXNldHNcbiAqIC0gTG9naXN0aWNzIHByZXNldHNcbiAqIC0gQ3VzdG9tIGJ1c2luZXNzIGxvZ2ljXG4gKiBcbiAqIEBwYXJhbSBwcmVzZXRzIC0gQXJyYXkgb2YgY3VzdG9tIFJhbmdlUHJlc2V0UGx1Z2luIGltcGxlbWVudGF0aW9uc1xuICogQHJldHVybnMgRW52aXJvbm1lbnRQcm92aWRlcnMgZm9yIGN1c3RvbSBwcmVzZXRzXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBGaXNjYWwgcHJlc2V0c1xuICogY29uc3QgRklTQ0FMX1BSRVNFVFM6IFJhbmdlUHJlc2V0UGx1Z2luW10gPSBbXG4gKiAgIHtcbiAqICAgICBrZXk6ICdUSElTX0ZJU0NBTF9RVUFSVEVSJyxcbiAqICAgICByZXNvbHZlOiAoY2xvY2ssIGFkYXB0ZXIpID0+IHtcbiAqICAgICAgIGNvbnN0IG5vdyA9IGNsb2NrLm5vdygpO1xuICogICAgICAgY29uc3QgbW9udGggPSBhZGFwdGVyLmdldE1vbnRoKG5vdyk7XG4gKiAgICAgICBcbiAqICAgICAgIC8vIEZpc2NhbCB5ZWFyIHN0YXJ0cyBBcHJpbCAobW9udGggMylcbiAqICAgICAgIGNvbnN0IGZpc2NhbE1vbnRoID0gKG1vbnRoICsgOSkgJSAxMjtcbiAqICAgICAgIGNvbnN0IHF1YXJ0ZXJTdGFydCA9IE1hdGguZmxvb3IoZmlzY2FsTW9udGggLyAzKSAqIDM7XG4gKiAgICAgICBjb25zdCBjYWxlbmRhck1vbnRoID0gKHF1YXJ0ZXJTdGFydCAtIDkgKyAxMikgJSAxMjtcbiAqICAgICAgIFxuICogICAgICAgY29uc3QgeWVhciA9IGFkYXB0ZXIuZ2V0WWVhcihub3cpO1xuICogICAgICAgY29uc3QgZmlzY2FsWWVhciA9IG1vbnRoIDwgMyA/IHllYXIgLSAxIDogeWVhcjtcbiAqICAgICAgIFxuICogICAgICAgY29uc3Qgc3RhcnQgPSBuZXcgRGF0ZShmaXNjYWxZZWFyLCBjYWxlbmRhck1vbnRoLCAxKTtcbiAqICAgICAgIGNvbnN0IGVuZCA9IG5ldyBEYXRlKGZpc2NhbFllYXIsIGNhbGVuZGFyTW9udGggKyAzLCAwKTtcbiAqICAgICAgIFxuICogICAgICAgcmV0dXJuIHtcbiAqICAgICAgICAgc3RhcnQ6IGFkYXB0ZXIubm9ybWFsaXplKHN0YXJ0KSxcbiAqICAgICAgICAgZW5kOiBhZGFwdGVyLm5vcm1hbGl6ZShlbmQpXG4gKiAgICAgICB9O1xuICogICAgIH1cbiAqICAgfSxcbiAqICAge1xuICogICAgIGtleTogJ0ZJU0NBTF9ZRUFSX1RPX0RBVEUnLFxuICogICAgIHJlc29sdmU6IChjbG9jaywgYWRhcHRlcikgPT4ge1xuICogICAgICAgY29uc3Qgbm93ID0gY2xvY2subm93KCk7XG4gKiAgICAgICBjb25zdCBtb250aCA9IGFkYXB0ZXIuZ2V0TW9udGgobm93KTtcbiAqICAgICAgIGNvbnN0IHllYXIgPSBhZGFwdGVyLmdldFllYXIobm93KTtcbiAqICAgICAgIFxuICogICAgICAgLy8gRmlzY2FsIHllYXIgc3RhcnRzIEFwcmlsIDFcbiAqICAgICAgIGNvbnN0IGZpc2NhbFllYXJTdGFydCA9IG1vbnRoID49IDMgXG4gKiAgICAgICAgID8gbmV3IERhdGUoeWVhciwgMywgMSlcbiAqICAgICAgICAgOiBuZXcgRGF0ZSh5ZWFyIC0gMSwgMywgMSk7XG4gKiAgICAgICBcbiAqICAgICAgIHJldHVybiB7XG4gKiAgICAgICAgIHN0YXJ0OiBhZGFwdGVyLm5vcm1hbGl6ZShmaXNjYWxZZWFyU3RhcnQpLFxuICogICAgICAgICBlbmQ6IGFkYXB0ZXIubm9ybWFsaXplKG5vdylcbiAqICAgICAgIH07XG4gKiAgICAgfVxuICogICB9XG4gKiBdO1xuICogXG4gKiAvLyBJbiBhcHAuY29uZmlnLnRzXG4gKiBleHBvcnQgY29uc3QgYXBwQ29uZmlnOiBBcHBsaWNhdGlvbkNvbmZpZyA9IHtcbiAqICAgcHJvdmlkZXJzOiBbXG4gKiAgICAgcHJvdmlkZUN1c3RvbVByZXNldHMoRklTQ0FMX1BSRVNFVFMpXG4gKiAgIF1cbiAqIH07XG4gKiBcbiAqIC8vIFVzZSBpbiBjb21wb25lbnRzXG4gKiBzdG9yZS5hcHBseVByZXNldCgnVEhJU19GSVNDQUxfUVVBUlRFUicpO1xuICogc3RvcmUuYXBwbHlQcmVzZXQoJ0ZJU0NBTF9ZRUFSX1RPX0RBVEUnKTtcbiAqIGBgYFxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gSG90ZWwgcHJlc2V0c1xuICogY29uc3QgSE9URUxfUFJFU0VUUzogUmFuZ2VQcmVzZXRQbHVnaW5bXSA9IFtcbiAqICAge1xuICogICAgIGtleTogJ0NIRUNLX0lOX1dFRUsnLFxuICogICAgIHJlc29sdmU6IChjbG9jaywgYWRhcHRlcikgPT4ge1xuICogICAgICAgY29uc3Qgbm93ID0gY2xvY2subm93KCk7XG4gKiAgICAgICBjb25zdCBkYXlPZldlZWsgPSBhZGFwdGVyLmdldERheU9mV2Vlayhub3cpO1xuICogICAgICAgXG4gKiAgICAgICAvLyBDaGVjay1pbiB3ZWVrOiBGcmlkYXkgdG8gRnJpZGF5XG4gKiAgICAgICBjb25zdCBkYXlzVG9OZXh0RnJpZGF5ID0gZGF5T2ZXZWVrIDw9IDUgXG4gKiAgICAgICAgID8gNSAtIGRheU9mV2VlayBcbiAqICAgICAgICAgOiA3IC0gZGF5T2ZXZWVrICsgNTtcbiAqICAgICAgIFxuICogICAgICAgY29uc3QgbmV4dEZyaWRheSA9IGFkYXB0ZXIuYWRkRGF5cyhub3csIGRheXNUb05leHRGcmlkYXkpO1xuICogICAgICAgY29uc3QgZm9sbG93aW5nRnJpZGF5ID0gYWRhcHRlci5hZGREYXlzKG5leHRGcmlkYXksIDcpO1xuICogICAgICAgXG4gKiAgICAgICByZXR1cm4geyBzdGFydDogbmV4dEZyaWRheSwgZW5kOiBmb2xsb3dpbmdGcmlkYXkgfTtcbiAqICAgICB9XG4gKiAgIH0sXG4gKiAgIHtcbiAqICAgICBrZXk6ICdORVhUXzMwX05JR0hUUycsXG4gKiAgICAgcmVzb2x2ZTogKGNsb2NrLCBhZGFwdGVyKSA9PiB7XG4gKiAgICAgICBjb25zdCBub3cgPSBjbG9jay5ub3coKTtcbiAqICAgICAgIGNvbnN0IHRvbW9ycm93ID0gYWRhcHRlci5hZGREYXlzKG5vdywgMSk7XG4gKiAgICAgICBjb25zdCBlbmQgPSBhZGFwdGVyLmFkZERheXModG9tb3Jyb3csIDMwKTtcbiAqICAgICAgIHJldHVybiB7IHN0YXJ0OiB0b21vcnJvdywgZW5kIH07XG4gKiAgICAgfVxuICogICB9XG4gKiBdO1xuICogXG4gKiBwcm92aWRlcnM6IFtwcm92aWRlQ3VzdG9tUHJlc2V0cyhIT1RFTF9QUkVTRVRTKV1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZUN1c3RvbVByZXNldHMocHJlc2V0czogUmFuZ2VQcmVzZXRQbHVnaW5bXSk6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcbiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbXG4gICAge1xuICAgICAgcHJvdmlkZTogQVBQX0lOSVRJQUxJWkVSLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgICB1c2VGYWN0b3J5OiAocmVnaXN0cnk6IFByZXNldFJlZ2lzdHJ5KSA9PiB7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgcHJlc2V0cy5mb3JFYWNoKHByZXNldCA9PiB7XG4gICAgICAgICAgICByZWdpc3RyeS5yZWdpc3RlcihwcmVzZXQpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJiBjb25zb2xlLmRlYnVnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFxuICAgICAgICAgICAgICBgW25nLWR1YWwtZGF0ZXBpY2tlcl0gUmVnaXN0ZXJlZCAke3ByZXNldHMubGVuZ3RofSBjdXN0b20gcHJlc2V0czpgLFxuICAgICAgICAgICAgICBwcmVzZXRzLm1hcChwID0+IHAua2V5KS5qb2luKCcsICcpXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBkZXBzOiBbUHJlc2V0UmVnaXN0cnldXG4gICAgfVxuICBdKTtcbn1cblxuLyoqXG4gKiBQcm92aWRlIHByZXNldCBwYWNrYWdlXG4gKiBcbiAqIENvbnZlbmllbmNlIGZ1bmN0aW9uIGZvciBleHRlcm5hbCBwcmVzZXQgcGFja2FnZXMuXG4gKiBcbiAqIEBwYXJhbSBwYWNrYWdlTmFtZSAtIE5hbWUgb2YgdGhlIHByZXNldCBwYWNrYWdlIChmb3IgbG9nZ2luZylcbiAqIEBwYXJhbSBwcmVzZXRzIC0gQXJyYXkgb2YgcHJlc2V0cyBmcm9tIHRoZSBwYWNrYWdlXG4gKiBAcmV0dXJucyBFbnZpcm9ubWVudFByb3ZpZGVyc1xuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQGFjbWUvZmlzY2FsLXByZXNldHMgcGFja2FnZVxuICogZXhwb3J0IGZ1bmN0aW9uIHByb3ZpZGVGaXNjYWxQcmVzZXRzKCk6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcbiAqICAgcmV0dXJuIHByb3ZpZGVQcmVzZXRQYWNrYWdlKCdAYWNtZS9maXNjYWwtcHJlc2V0cycsIEZJU0NBTF9QUkVTRVRTKTtcbiAqIH1cbiAqIFxuICogLy8gSW4gYXBwXG4gKiBpbXBvcnQgeyBwcm92aWRlRmlzY2FsUHJlc2V0cyB9IGZyb20gJ0BhY21lL2Zpc2NhbC1wcmVzZXRzJztcbiAqIFxuICogcHJvdmlkZXJzOiBbcHJvdmlkZUZpc2NhbFByZXNldHMoKV1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZVByZXNldFBhY2thZ2UoXG4gIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gIHByZXNldHM6IFJhbmdlUHJlc2V0UGx1Z2luW11cbik6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcbiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbXG4gICAge1xuICAgICAgcHJvdmlkZTogQVBQX0lOSVRJQUxJWkVSLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgICB1c2VGYWN0b3J5OiAocmVnaXN0cnk6IFByZXNldFJlZ2lzdHJ5KSA9PiB7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgcHJlc2V0cy5mb3JFYWNoKHByZXNldCA9PiB7XG4gICAgICAgICAgICByZWdpc3RyeS5yZWdpc3RlcihwcmVzZXQpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJiBjb25zb2xlLmRlYnVnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFxuICAgICAgICAgICAgICBgWyR7cGFja2FnZU5hbWV9XSBSZWdpc3RlcmVkICR7cHJlc2V0cy5sZW5ndGh9IHByZXNldHM6YCxcbiAgICAgICAgICAgICAgcHJlc2V0cy5tYXAocCA9PiBwLmtleSkuam9pbignLCAnKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZGVwczogW1ByZXNldFJlZ2lzdHJ5XVxuICAgIH1cbiAgXSk7XG59XG4iXX0=