@oneluiz/dual-datepicker 4.0.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -2
- package/fesm2022/oneluiz-dual-datepicker.mjs +75 -71
- package/fesm2022/oneluiz-dual-datepicker.mjs.map +1 -1
- package/package.json +8 -9
- package/types/oneluiz-dual-datepicker.d.ts +1618 -0
- package/dual-datepicker.component.d.ts +0 -243
- package/esm2022/core/built-in-presets.mjs +0 -289
- package/esm2022/core/calendar-grid/cache.config.mjs +0 -35
- package/esm2022/core/calendar-grid/calendar-grid.cache.mjs +0 -98
- package/esm2022/core/calendar-grid/calendar-grid.factory.mjs +0 -97
- package/esm2022/core/calendar-grid/calendar-grid.types.mjs +0 -8
- package/esm2022/core/calendar-grid/range-highlighter.cache.mjs +0 -200
- package/esm2022/core/calendar-grid/range-highlighter.mjs +0 -185
- package/esm2022/core/calendar-grid/range-highlighter.types.mjs +0 -11
- package/esm2022/core/calendar-grid/virtual-weeks.logic.mjs +0 -149
- package/esm2022/core/calendar-grid/virtual-weeks.types.mjs +0 -11
- package/esm2022/core/date-adapter.mjs +0 -77
- package/esm2022/core/date-clock.mjs +0 -65
- package/esm2022/core/dual-date-range.store.mjs +0 -329
- package/esm2022/core/internal.mjs +0 -92
- package/esm2022/core/native-date-adapter.mjs +0 -286
- package/esm2022/core/preset-providers.mjs +0 -243
- package/esm2022/core/preset-registry.mjs +0 -277
- package/esm2022/core/preset.engine.mjs +0 -179
- package/esm2022/core/public.mjs +0 -94
- package/esm2022/core/range-preset.plugin.mjs +0 -70
- package/esm2022/core/range.validator.mjs +0 -105
- package/esm2022/core/system-clock.mjs +0 -34
- package/esm2022/core/testing/date.helpers.mjs +0 -49
- package/esm2022/core/testing/fixed-clock.mjs +0 -30
- package/esm2022/core/testing/index.mjs +0 -8
- package/esm2022/dual-datepicker.component.mjs +0 -1314
- package/esm2022/oneluiz-dual-datepicker.mjs +0 -5
- package/esm2022/public-api.mjs +0 -43
- package/index.d.ts +0 -5
- package/public-api.d.ts +0 -44
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Grid Cache
|
|
3
|
-
*
|
|
4
|
-
* LRU cache for calendar month grids to avoid recomputing the same month grid
|
|
5
|
-
* multiple times when only decorations (selected dates, hover, etc.) change.
|
|
6
|
-
*
|
|
7
|
-
* Strategy:
|
|
8
|
-
* - Key: year-month-weekStart-locale
|
|
9
|
-
* - LRU eviction (least recently used) when limit is reached
|
|
10
|
-
* - Default limit: 48 months (covers 2 years of navigation)
|
|
11
|
-
*
|
|
12
|
-
* Performance impact:
|
|
13
|
-
* - Eliminates ~90% of grid recalculations in typical usage
|
|
14
|
-
* - Memory footprint: ~10KB per cached month (negligible)
|
|
15
|
-
*
|
|
16
|
-
* Memory safety (v3.9.2):
|
|
17
|
-
* - MAX_CACHE_ENTRIES prevents unbounded growth in long-running sessions
|
|
18
|
-
* - Critical for: ERP, BI dashboards, hotel reservation systems
|
|
19
|
-
* - FIFO eviction when limit exceeded
|
|
20
|
-
*/
|
|
21
|
-
import { Injectable } from '@angular/core';
|
|
22
|
-
import { MAX_CACHE_ENTRIES } from './cache.config';
|
|
23
|
-
import * as i0 from "@angular/core";
|
|
24
|
-
import * as i1 from "./calendar-grid.factory";
|
|
25
|
-
export class CalendarGridCache {
|
|
26
|
-
factory;
|
|
27
|
-
cache = new Map();
|
|
28
|
-
maxSize = MAX_CACHE_ENTRIES;
|
|
29
|
-
constructor(factory) {
|
|
30
|
-
this.factory = factory;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Get or create a calendar grid
|
|
34
|
-
*
|
|
35
|
-
* @param monthDate - Any date within the target month
|
|
36
|
-
* @param weekStart - First day of week (0 = Sunday, 1 = Monday, etc.)
|
|
37
|
-
* @param locale - Locale identifier (optional)
|
|
38
|
-
* @returns CalendarGrid - cached or newly created
|
|
39
|
-
*/
|
|
40
|
-
get(monthDate, weekStart = 0, locale) {
|
|
41
|
-
const key = this.buildKey(monthDate, weekStart, locale);
|
|
42
|
-
// Check cache
|
|
43
|
-
const cached = this.cache.get(key);
|
|
44
|
-
if (cached) {
|
|
45
|
-
// Move to end (LRU)
|
|
46
|
-
this.cache.delete(key);
|
|
47
|
-
this.cache.set(key, cached);
|
|
48
|
-
return cached;
|
|
49
|
-
}
|
|
50
|
-
// Generate new grid
|
|
51
|
-
const grid = this.factory.createGrid(monthDate, weekStart, locale);
|
|
52
|
-
// Store in cache
|
|
53
|
-
this.cache.set(key, grid);
|
|
54
|
-
// Evict oldest if over limit (LRU)
|
|
55
|
-
if (this.cache.size > this.maxSize) {
|
|
56
|
-
const firstKey = this.cache.keys().next().value;
|
|
57
|
-
this.cache.delete(firstKey);
|
|
58
|
-
}
|
|
59
|
-
return grid;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Build cache key from month parameters
|
|
63
|
-
*
|
|
64
|
-
* Format: "year-month-weekStart-locale"
|
|
65
|
-
* Example: "2026-1-0-en" (Feb 2026, Sunday start, English)
|
|
66
|
-
*/
|
|
67
|
-
buildKey(monthDate, weekStart, locale) {
|
|
68
|
-
const year = monthDate.getFullYear();
|
|
69
|
-
const month = monthDate.getMonth();
|
|
70
|
-
return `${year}-${month}-${weekStart}${locale ? '-' + locale : ''}`;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Clear entire cache (for testing or manual reset)
|
|
74
|
-
*/
|
|
75
|
-
clear() {
|
|
76
|
-
this.cache.clear();
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Get cache size (for debugging/testing)
|
|
80
|
-
*/
|
|
81
|
-
size() {
|
|
82
|
-
return this.cache.size;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Check if a specific month is cached
|
|
86
|
-
*/
|
|
87
|
-
has(monthDate, weekStart = 0, locale) {
|
|
88
|
-
const key = this.buildKey(monthDate, weekStart, locale);
|
|
89
|
-
return this.cache.has(key);
|
|
90
|
-
}
|
|
91
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CalendarGridCache, deps: [{ token: i1.CalendarGridFactory }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
92
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CalendarGridCache, providedIn: 'root' });
|
|
93
|
-
}
|
|
94
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CalendarGridCache, decorators: [{
|
|
95
|
-
type: Injectable,
|
|
96
|
-
args: [{ providedIn: 'root' }]
|
|
97
|
-
}], ctorParameters: () => [{ type: i1.CalendarGridFactory }] });
|
|
98
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXItZ3JpZC5jYWNoZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL2NhbGVuZGFyLWdyaWQvY2FsZW5kYXItZ3JpZC5jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHM0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQUduRCxNQUFNLE9BQU8saUJBQWlCO0lBSVI7SUFIWixLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQXdCLENBQUM7SUFDL0IsT0FBTyxHQUFXLGlCQUFpQixDQUFDO0lBRXJELFlBQW9CLE9BQTRCO1FBQTVCLFlBQU8sR0FBUCxPQUFPLENBQXFCO0lBQUcsQ0FBQztJQUVwRDs7Ozs7OztPQU9HO0lBQ0gsR0FBRyxDQUFDLFNBQWUsRUFBRSxZQUFvQixDQUFDLEVBQUUsTUFBZTtRQUN6RCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFeEQsY0FBYztRQUNkLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxvQkFBb0I7WUFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7UUFFRCxvQkFBb0I7UUFDcEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVuRSxpQkFBaUI7UUFDakIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTFCLG1DQUFtQztRQUNuQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNuQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQztZQUNoRCxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM5QixDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxRQUFRLENBQUMsU0FBZSxFQUFFLFNBQWlCLEVBQUUsTUFBZTtRQUNsRSxNQUFNLElBQUksR0FBRyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckMsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ25DLE9BQU8sR0FBRyxJQUFJLElBQUksS0FBSyxJQUFJLFNBQVMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO0lBQ3RFLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUs7UUFDSCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUk7UUFDRixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7T0FFRztJQUNILEdBQUcsQ0FBQyxTQUFlLEVBQUUsWUFBb0IsQ0FBQyxFQUFFLE1BQWU7UUFDekQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDN0IsQ0FBQzt3R0F6RVUsaUJBQWlCOzRHQUFqQixpQkFBaUIsY0FESixNQUFNOzs0RkFDbkIsaUJBQWlCO2tCQUQ3QixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2FsZW5kYXIgR3JpZCBDYWNoZVxuICpcbiAqIExSVSBjYWNoZSBmb3IgY2FsZW5kYXIgbW9udGggZ3JpZHMgdG8gYXZvaWQgcmVjb21wdXRpbmcgdGhlIHNhbWUgbW9udGggZ3JpZFxuICogbXVsdGlwbGUgdGltZXMgd2hlbiBvbmx5IGRlY29yYXRpb25zIChzZWxlY3RlZCBkYXRlcywgaG92ZXIsIGV0Yy4pIGNoYW5nZS5cbiAqXG4gKiBTdHJhdGVneTpcbiAqIC0gS2V5OiB5ZWFyLW1vbnRoLXdlZWtTdGFydC1sb2NhbGVcbiAqIC0gTFJVIGV2aWN0aW9uIChsZWFzdCByZWNlbnRseSB1c2VkKSB3aGVuIGxpbWl0IGlzIHJlYWNoZWRcbiAqIC0gRGVmYXVsdCBsaW1pdDogNDggbW9udGhzIChjb3ZlcnMgMiB5ZWFycyBvZiBuYXZpZ2F0aW9uKVxuICpcbiAqIFBlcmZvcm1hbmNlIGltcGFjdDpcbiAqIC0gRWxpbWluYXRlcyB+OTAlIG9mIGdyaWQgcmVjYWxjdWxhdGlvbnMgaW4gdHlwaWNhbCB1c2FnZVxuICogLSBNZW1vcnkgZm9vdHByaW50OiB+MTBLQiBwZXIgY2FjaGVkIG1vbnRoIChuZWdsaWdpYmxlKVxuICogXG4gKiBNZW1vcnkgc2FmZXR5ICh2My45LjIpOlxuICogLSBNQVhfQ0FDSEVfRU5UUklFUyBwcmV2ZW50cyB1bmJvdW5kZWQgZ3Jvd3RoIGluIGxvbmctcnVubmluZyBzZXNzaW9uc1xuICogLSBDcml0aWNhbCBmb3I6IEVSUCwgQkkgZGFzaGJvYXJkcywgaG90ZWwgcmVzZXJ2YXRpb24gc3lzdGVtc1xuICogLSBGSUZPIGV2aWN0aW9uIHdoZW4gbGltaXQgZXhjZWVkZWRcbiAqL1xuXG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDYWxlbmRhckdyaWRGYWN0b3J5IH0gZnJvbSAnLi9jYWxlbmRhci1ncmlkLmZhY3RvcnknO1xuaW1wb3J0IHsgQ2FsZW5kYXJHcmlkLCBDYWxlbmRhckdyaWRDYWNoZUtleSB9IGZyb20gJy4vY2FsZW5kYXItZ3JpZC50eXBlcyc7XG5pbXBvcnQgeyBNQVhfQ0FDSEVfRU5UUklFUyB9IGZyb20gJy4vY2FjaGUuY29uZmlnJztcblxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckdyaWRDYWNoZSB7XG4gIHByaXZhdGUgY2FjaGUgPSBuZXcgTWFwPHN0cmluZywgQ2FsZW5kYXJHcmlkPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG1heFNpemU6IG51bWJlciA9IE1BWF9DQUNIRV9FTlRSSUVTO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZmFjdG9yeTogQ2FsZW5kYXJHcmlkRmFjdG9yeSkge31cblxuICAvKipcbiAgICogR2V0IG9yIGNyZWF0ZSBhIGNhbGVuZGFyIGdyaWRcbiAgICpcbiAgICogQHBhcmFtIG1vbnRoRGF0ZSAtIEFueSBkYXRlIHdpdGhpbiB0aGUgdGFyZ2V0IG1vbnRoXG4gICAqIEBwYXJhbSB3ZWVrU3RhcnQgLSBGaXJzdCBkYXkgb2Ygd2VlayAoMCA9IFN1bmRheSwgMSA9IE1vbmRheSwgZXRjLilcbiAgICogQHBhcmFtIGxvY2FsZSAtIExvY2FsZSBpZGVudGlmaWVyIChvcHRpb25hbClcbiAgICogQHJldHVybnMgQ2FsZW5kYXJHcmlkIC0gY2FjaGVkIG9yIG5ld2x5IGNyZWF0ZWRcbiAgICovXG4gIGdldChtb250aERhdGU6IERhdGUsIHdlZWtTdGFydDogbnVtYmVyID0gMCwgbG9jYWxlPzogc3RyaW5nKTogQ2FsZW5kYXJHcmlkIHtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmJ1aWxkS2V5KG1vbnRoRGF0ZSwgd2Vla1N0YXJ0LCBsb2NhbGUpO1xuXG4gICAgLy8gQ2hlY2sgY2FjaGVcbiAgICBjb25zdCBjYWNoZWQgPSB0aGlzLmNhY2hlLmdldChrZXkpO1xuICAgIGlmIChjYWNoZWQpIHtcbiAgICAgIC8vIE1vdmUgdG8gZW5kIChMUlUpXG4gICAgICB0aGlzLmNhY2hlLmRlbGV0ZShrZXkpO1xuICAgICAgdGhpcy5jYWNoZS5zZXQoa2V5LCBjYWNoZWQpO1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSBuZXcgZ3JpZFxuICAgIGNvbnN0IGdyaWQgPSB0aGlzLmZhY3RvcnkuY3JlYXRlR3JpZChtb250aERhdGUsIHdlZWtTdGFydCwgbG9jYWxlKTtcblxuICAgIC8vIFN0b3JlIGluIGNhY2hlXG4gICAgdGhpcy5jYWNoZS5zZXQoa2V5LCBncmlkKTtcblxuICAgIC8vIEV2aWN0IG9sZGVzdCBpZiBvdmVyIGxpbWl0IChMUlUpXG4gICAgaWYgKHRoaXMuY2FjaGUuc2l6ZSA+IHRoaXMubWF4U2l6ZSkge1xuICAgICAgY29uc3QgZmlyc3RLZXkgPSB0aGlzLmNhY2hlLmtleXMoKS5uZXh0KCkudmFsdWU7XG4gICAgICB0aGlzLmNhY2hlLmRlbGV0ZShmaXJzdEtleSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdyaWQ7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgY2FjaGUga2V5IGZyb20gbW9udGggcGFyYW1ldGVyc1xuICAgKlxuICAgKiBGb3JtYXQ6IFwieWVhci1tb250aC13ZWVrU3RhcnQtbG9jYWxlXCJcbiAgICogRXhhbXBsZTogXCIyMDI2LTEtMC1lblwiIChGZWIgMjAyNiwgU3VuZGF5IHN0YXJ0LCBFbmdsaXNoKVxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZEtleShtb250aERhdGU6IERhdGUsIHdlZWtTdGFydDogbnVtYmVyLCBsb2NhbGU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHllYXIgPSBtb250aERhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICBjb25zdCBtb250aCA9IG1vbnRoRGF0ZS5nZXRNb250aCgpO1xuICAgIHJldHVybiBgJHt5ZWFyfS0ke21vbnRofS0ke3dlZWtTdGFydH0ke2xvY2FsZSA/ICctJyArIGxvY2FsZSA6ICcnfWA7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgZW50aXJlIGNhY2hlIChmb3IgdGVzdGluZyBvciBtYW51YWwgcmVzZXQpXG4gICAqL1xuICBjbGVhcigpOiB2b2lkIHtcbiAgICB0aGlzLmNhY2hlLmNsZWFyKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNhY2hlIHNpemUgKGZvciBkZWJ1Z2dpbmcvdGVzdGluZylcbiAgICovXG4gIHNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5zaXplO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgc3BlY2lmaWMgbW9udGggaXMgY2FjaGVkXG4gICAqL1xuICBoYXMobW9udGhEYXRlOiBEYXRlLCB3ZWVrU3RhcnQ6IG51bWJlciA9IDAsIGxvY2FsZT86IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGtleSA9IHRoaXMuYnVpbGRLZXkobW9udGhEYXRlLCB3ZWVrU3RhcnQsIGxvY2FsZSk7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuaGFzKGtleSk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Grid Factory
|
|
3
|
-
*
|
|
4
|
-
* Generates calendar month grids using DateAdapter for deterministic,
|
|
5
|
-
* timezone-safe date operations.
|
|
6
|
-
*
|
|
7
|
-
* Grid structure:
|
|
8
|
-
* - Always 6 weeks x 7 days (42 cells) for layout stability
|
|
9
|
-
* - Includes padding days from previous/next month
|
|
10
|
-
* - No decorations (selected, disabled, etc.) - those are applied separately
|
|
11
|
-
*/
|
|
12
|
-
import { Injectable, Inject } from '@angular/core';
|
|
13
|
-
import { DATE_ADAPTER } from '../date-adapter';
|
|
14
|
-
import * as i0 from "@angular/core";
|
|
15
|
-
export class CalendarGridFactory {
|
|
16
|
-
adapter;
|
|
17
|
-
constructor(adapter) {
|
|
18
|
-
this.adapter = adapter;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Create a calendar grid for a given month
|
|
22
|
-
*
|
|
23
|
-
* @param monthDate - Any date within the target month (will be normalized to start of month)
|
|
24
|
-
* @param weekStart - First day of week (0 = Sunday, 1 = Monday, etc.)
|
|
25
|
-
* @param locale - Locale identifier (optional, for future use)
|
|
26
|
-
* @returns CalendarGrid - 6 weeks x 7 days grid
|
|
27
|
-
*/
|
|
28
|
-
createGrid(monthDate, weekStart = 0, locale) {
|
|
29
|
-
// Normalize to start of month
|
|
30
|
-
const year = this.adapter.getYear(monthDate);
|
|
31
|
-
const month = this.adapter.getMonth(monthDate);
|
|
32
|
-
const firstDayOfMonth = new Date(year, month, 1);
|
|
33
|
-
const normalizedFirst = this.adapter.normalize(firstDayOfMonth);
|
|
34
|
-
// Get days in month (day 0 of next month = last day of current month)
|
|
35
|
-
const lastDayOfMonth = new Date(year, month + 1, 0);
|
|
36
|
-
const daysInMonth = this.adapter.getDate(lastDayOfMonth);
|
|
37
|
-
// Get first day of week offset
|
|
38
|
-
const firstDayOfWeek = this.adapter.getDay(normalizedFirst);
|
|
39
|
-
const offset = this.calculateOffset(firstDayOfWeek, weekStart);
|
|
40
|
-
// Generate 42 cells (6 weeks x 7 days)
|
|
41
|
-
const cells = [];
|
|
42
|
-
let currentDate = this.adapter.addDays(normalizedFirst, -offset);
|
|
43
|
-
for (let i = 0; i < 42; i++) {
|
|
44
|
-
const cellDate = this.adapter.normalize(currentDate);
|
|
45
|
-
const cellYear = this.adapter.getYear(cellDate);
|
|
46
|
-
const cellMonth = this.adapter.getMonth(cellDate);
|
|
47
|
-
const cellDay = this.adapter.getDate(cellDate);
|
|
48
|
-
const cellDayOfWeek = this.adapter.getDay(cellDate);
|
|
49
|
-
cells.push({
|
|
50
|
-
date: cellDate,
|
|
51
|
-
inCurrentMonth: cellYear === year && cellMonth === month,
|
|
52
|
-
iso: this.adapter.toISODate(cellDate),
|
|
53
|
-
day: cellDay,
|
|
54
|
-
month: cellMonth,
|
|
55
|
-
year: cellYear,
|
|
56
|
-
dayOfWeek: cellDayOfWeek
|
|
57
|
-
});
|
|
58
|
-
currentDate = this.adapter.addDays(currentDate, 1);
|
|
59
|
-
}
|
|
60
|
-
// Split into weeks
|
|
61
|
-
const weeks = [];
|
|
62
|
-
for (let i = 0; i < 6; i++) {
|
|
63
|
-
weeks.push(cells.slice(i * 7, (i + 1) * 7));
|
|
64
|
-
}
|
|
65
|
-
return {
|
|
66
|
-
month: { year, month },
|
|
67
|
-
weekStart,
|
|
68
|
-
locale,
|
|
69
|
-
weeks,
|
|
70
|
-
cells
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Calculate offset (number of padding days from previous month)
|
|
75
|
-
*
|
|
76
|
-
* @param firstDayOfWeek - Day of week for first day of month (0-6)
|
|
77
|
-
* @param weekStart - Desired week start (0-6)
|
|
78
|
-
* @returns Number of padding days needed
|
|
79
|
-
*/
|
|
80
|
-
calculateOffset(firstDayOfWeek, weekStart) {
|
|
81
|
-
let offset = firstDayOfWeek - weekStart;
|
|
82
|
-
if (offset < 0) {
|
|
83
|
-
offset += 7;
|
|
84
|
-
}
|
|
85
|
-
return offset;
|
|
86
|
-
}
|
|
87
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CalendarGridFactory, deps: [{ token: DATE_ADAPTER }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
88
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CalendarGridFactory, providedIn: 'root' });
|
|
89
|
-
}
|
|
90
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CalendarGridFactory, decorators: [{
|
|
91
|
-
type: Injectable,
|
|
92
|
-
args: [{ providedIn: 'root' }]
|
|
93
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
94
|
-
type: Inject,
|
|
95
|
-
args: [DATE_ADAPTER]
|
|
96
|
-
}] }] });
|
|
97
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXItZ3JpZC5mYWN0b3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvcmUvY2FsZW5kYXItZ3JpZC9jYWxlbmRhci1ncmlkLmZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBZSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFJNUQsTUFBTSxPQUFPLG1CQUFtQjtJQUVFO0lBRGhDLFlBQ2dDLE9BQW9CO1FBQXBCLFlBQU8sR0FBUCxPQUFPLENBQWE7SUFDakQsQ0FBQztJQUVKOzs7Ozs7O09BT0c7SUFDSCxVQUFVLENBQUMsU0FBZSxFQUFFLFlBQW9CLENBQUMsRUFBRSxNQUFlO1FBQ2hFLDhCQUE4QjtRQUM5QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM3QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMvQyxNQUFNLGVBQWUsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRWhFLHNFQUFzRTtRQUN0RSxNQUFNLGNBQWMsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUV6RCwrQkFBK0I7UUFDL0IsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDNUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxjQUFjLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFL0QsdUNBQXVDO1FBQ3ZDLE1BQU0sS0FBSyxHQUFtQixFQUFFLENBQUM7UUFDakMsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFakUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzVCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3JELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2hELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2xELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQy9DLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRXBELEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ1QsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsY0FBYyxFQUFFLFFBQVEsS0FBSyxJQUFJLElBQUksU0FBUyxLQUFLLEtBQUs7Z0JBQ3hELEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUM7Z0JBQ3JDLEdBQUcsRUFBRSxPQUFPO2dCQUNaLEtBQUssRUFBRSxTQUFTO2dCQUNoQixJQUFJLEVBQUUsUUFBUTtnQkFDZCxTQUFTLEVBQUUsYUFBYTthQUN6QixDQUFDLENBQUM7WUFFSCxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFFRCxtQkFBbUI7UUFDbkIsTUFBTSxLQUFLLEdBQXFCLEVBQUUsQ0FBQztRQUNuQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDM0IsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBRUQsT0FBTztZQUNMLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUU7WUFDdEIsU0FBUztZQUNULE1BQU07WUFDTixLQUFLO1lBQ0wsS0FBSztTQUNOLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssZUFBZSxDQUFDLGNBQXNCLEVBQUUsU0FBaUI7UUFDL0QsSUFBSSxNQUFNLEdBQUcsY0FBYyxHQUFHLFNBQVMsQ0FBQztRQUN4QyxJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxDQUFDLENBQUM7UUFDZCxDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQzt3R0FoRlUsbUJBQW1CLGtCQUVwQixZQUFZOzRHQUZYLG1CQUFtQixjQUROLE1BQU07OzRGQUNuQixtQkFBbUI7a0JBRC9CLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFOzswQkFHN0IsTUFBTTsyQkFBQyxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDYWxlbmRhciBHcmlkIEZhY3RvcnlcbiAqXG4gKiBHZW5lcmF0ZXMgY2FsZW5kYXIgbW9udGggZ3JpZHMgdXNpbmcgRGF0ZUFkYXB0ZXIgZm9yIGRldGVybWluaXN0aWMsXG4gKiB0aW1lem9uZS1zYWZlIGRhdGUgb3BlcmF0aW9ucy5cbiAqXG4gKiBHcmlkIHN0cnVjdHVyZTpcbiAqIC0gQWx3YXlzIDYgd2Vla3MgeCA3IGRheXMgKDQyIGNlbGxzKSBmb3IgbGF5b3V0IHN0YWJpbGl0eVxuICogLSBJbmNsdWRlcyBwYWRkaW5nIGRheXMgZnJvbSBwcmV2aW91cy9uZXh0IG1vbnRoXG4gKiAtIE5vIGRlY29yYXRpb25zIChzZWxlY3RlZCwgZGlzYWJsZWQsIGV0Yy4pIC0gdGhvc2UgYXJlIGFwcGxpZWQgc2VwYXJhdGVseVxuICovXG5cbmltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRGF0ZUFkYXB0ZXIsIERBVEVfQURBUFRFUiB9IGZyb20gJy4uL2RhdGUtYWRhcHRlcic7XG5pbXBvcnQgeyBDYWxlbmRhckNlbGwsIENhbGVuZGFyR3JpZCB9IGZyb20gJy4vY2FsZW5kYXItZ3JpZC50eXBlcyc7XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQ2FsZW5kYXJHcmlkRmFjdG9yeSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoREFURV9BREFQVEVSKSBwcml2YXRlIGFkYXB0ZXI6IERhdGVBZGFwdGVyXG4gICkge31cblxuICAvKipcbiAgICogQ3JlYXRlIGEgY2FsZW5kYXIgZ3JpZCBmb3IgYSBnaXZlbiBtb250aFxuICAgKlxuICAgKiBAcGFyYW0gbW9udGhEYXRlIC0gQW55IGRhdGUgd2l0aGluIHRoZSB0YXJnZXQgbW9udGggKHdpbGwgYmUgbm9ybWFsaXplZCB0byBzdGFydCBvZiBtb250aClcbiAgICogQHBhcmFtIHdlZWtTdGFydCAtIEZpcnN0IGRheSBvZiB3ZWVrICgwID0gU3VuZGF5LCAxID0gTW9uZGF5LCBldGMuKVxuICAgKiBAcGFyYW0gbG9jYWxlIC0gTG9jYWxlIGlkZW50aWZpZXIgKG9wdGlvbmFsLCBmb3IgZnV0dXJlIHVzZSlcbiAgICogQHJldHVybnMgQ2FsZW5kYXJHcmlkIC0gNiB3ZWVrcyB4IDcgZGF5cyBncmlkXG4gICAqL1xuICBjcmVhdGVHcmlkKG1vbnRoRGF0ZTogRGF0ZSwgd2Vla1N0YXJ0OiBudW1iZXIgPSAwLCBsb2NhbGU/OiBzdHJpbmcpOiBDYWxlbmRhckdyaWQge1xuICAgIC8vIE5vcm1hbGl6ZSB0byBzdGFydCBvZiBtb250aFxuICAgIGNvbnN0IHllYXIgPSB0aGlzLmFkYXB0ZXIuZ2V0WWVhcihtb250aERhdGUpO1xuICAgIGNvbnN0IG1vbnRoID0gdGhpcy5hZGFwdGVyLmdldE1vbnRoKG1vbnRoRGF0ZSk7XG4gICAgY29uc3QgZmlyc3REYXlPZk1vbnRoID0gbmV3IERhdGUoeWVhciwgbW9udGgsIDEpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRGaXJzdCA9IHRoaXMuYWRhcHRlci5ub3JtYWxpemUoZmlyc3REYXlPZk1vbnRoKTtcblxuICAgIC8vIEdldCBkYXlzIGluIG1vbnRoIChkYXkgMCBvZiBuZXh0IG1vbnRoID0gbGFzdCBkYXkgb2YgY3VycmVudCBtb250aClcbiAgICBjb25zdCBsYXN0RGF5T2ZNb250aCA9IG5ldyBEYXRlKHllYXIsIG1vbnRoICsgMSwgMCk7XG4gICAgY29uc3QgZGF5c0luTW9udGggPSB0aGlzLmFkYXB0ZXIuZ2V0RGF0ZShsYXN0RGF5T2ZNb250aCk7XG5cbiAgICAvLyBHZXQgZmlyc3QgZGF5IG9mIHdlZWsgb2Zmc2V0XG4gICAgY29uc3QgZmlyc3REYXlPZldlZWsgPSB0aGlzLmFkYXB0ZXIuZ2V0RGF5KG5vcm1hbGl6ZWRGaXJzdCk7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5jYWxjdWxhdGVPZmZzZXQoZmlyc3REYXlPZldlZWssIHdlZWtTdGFydCk7XG5cbiAgICAvLyBHZW5lcmF0ZSA0MiBjZWxscyAoNiB3ZWVrcyB4IDcgZGF5cylcbiAgICBjb25zdCBjZWxsczogQ2FsZW5kYXJDZWxsW10gPSBbXTtcbiAgICBsZXQgY3VycmVudERhdGUgPSB0aGlzLmFkYXB0ZXIuYWRkRGF5cyhub3JtYWxpemVkRmlyc3QsIC1vZmZzZXQpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCA0MjsgaSsrKSB7XG4gICAgICBjb25zdCBjZWxsRGF0ZSA9IHRoaXMuYWRhcHRlci5ub3JtYWxpemUoY3VycmVudERhdGUpO1xuICAgICAgY29uc3QgY2VsbFllYXIgPSB0aGlzLmFkYXB0ZXIuZ2V0WWVhcihjZWxsRGF0ZSk7XG4gICAgICBjb25zdCBjZWxsTW9udGggPSB0aGlzLmFkYXB0ZXIuZ2V0TW9udGgoY2VsbERhdGUpO1xuICAgICAgY29uc3QgY2VsbERheSA9IHRoaXMuYWRhcHRlci5nZXREYXRlKGNlbGxEYXRlKTtcbiAgICAgIGNvbnN0IGNlbGxEYXlPZldlZWsgPSB0aGlzLmFkYXB0ZXIuZ2V0RGF5KGNlbGxEYXRlKTtcblxuICAgICAgY2VsbHMucHVzaCh7XG4gICAgICAgIGRhdGU6IGNlbGxEYXRlLFxuICAgICAgICBpbkN1cnJlbnRNb250aDogY2VsbFllYXIgPT09IHllYXIgJiYgY2VsbE1vbnRoID09PSBtb250aCxcbiAgICAgICAgaXNvOiB0aGlzLmFkYXB0ZXIudG9JU09EYXRlKGNlbGxEYXRlKSxcbiAgICAgICAgZGF5OiBjZWxsRGF5LFxuICAgICAgICBtb250aDogY2VsbE1vbnRoLFxuICAgICAgICB5ZWFyOiBjZWxsWWVhcixcbiAgICAgICAgZGF5T2ZXZWVrOiBjZWxsRGF5T2ZXZWVrXG4gICAgICB9KTtcblxuICAgICAgY3VycmVudERhdGUgPSB0aGlzLmFkYXB0ZXIuYWRkRGF5cyhjdXJyZW50RGF0ZSwgMSk7XG4gICAgfVxuXG4gICAgLy8gU3BsaXQgaW50byB3ZWVrc1xuICAgIGNvbnN0IHdlZWtzOiBDYWxlbmRhckNlbGxbXVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHtcbiAgICAgIHdlZWtzLnB1c2goY2VsbHMuc2xpY2UoaSAqIDcsIChpICsgMSkgKiA3KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1vbnRoOiB7IHllYXIsIG1vbnRoIH0sXG4gICAgICB3ZWVrU3RhcnQsXG4gICAgICBsb2NhbGUsXG4gICAgICB3ZWVrcyxcbiAgICAgIGNlbGxzXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgb2Zmc2V0IChudW1iZXIgb2YgcGFkZGluZyBkYXlzIGZyb20gcHJldmlvdXMgbW9udGgpXG4gICAqXG4gICAqIEBwYXJhbSBmaXJzdERheU9mV2VlayAtIERheSBvZiB3ZWVrIGZvciBmaXJzdCBkYXkgb2YgbW9udGggKDAtNilcbiAgICogQHBhcmFtIHdlZWtTdGFydCAtIERlc2lyZWQgd2VlayBzdGFydCAoMC02KVxuICAgKiBAcmV0dXJucyBOdW1iZXIgb2YgcGFkZGluZyBkYXlzIG5lZWRlZFxuICAgKi9cbiAgcHJpdmF0ZSBjYWxjdWxhdGVPZmZzZXQoZmlyc3REYXlPZldlZWs6IG51bWJlciwgd2Vla1N0YXJ0OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBvZmZzZXQgPSBmaXJzdERheU9mV2VlayAtIHdlZWtTdGFydDtcbiAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgb2Zmc2V0ICs9IDc7XG4gICAgfVxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Grid Types
|
|
3
|
-
*
|
|
4
|
-
* Defines the structure for memoized calendar month grids.
|
|
5
|
-
* Separates base grid structure (cacheable) from decorations (dynamic).
|
|
6
|
-
*/
|
|
7
|
-
export {};
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXItZ3JpZC50eXBlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL2NhbGVuZGFyLWdyaWQvY2FsZW5kYXItZ3JpZC50eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2FsZW5kYXIgR3JpZCBUeXBlc1xuICpcbiAqIERlZmluZXMgdGhlIHN0cnVjdHVyZSBmb3IgbWVtb2l6ZWQgY2FsZW5kYXIgbW9udGggZ3JpZHMuXG4gKiBTZXBhcmF0ZXMgYmFzZSBncmlkIHN0cnVjdHVyZSAoY2FjaGVhYmxlKSBmcm9tIGRlY29yYXRpb25zIChkeW5hbWljKS5cbiAqL1xuXG4vKipcbiAqIEEgc2luZ2xlIGNhbGVuZGFyIGNlbGwgcmVwcmVzZW50aW5nIG9uZSBkYXlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDYWxlbmRhckNlbGwge1xuICAvKiogRGF0ZSBvYmplY3QgKG5vcm1hbGl6ZWQgdG8gc3RhcnQgb2YgZGF5KSAqL1xuICBkYXRlOiBEYXRlO1xuXG4gIC8qKiBXaGV0aGVyIHRoaXMgZGF5IGJlbG9uZ3MgdG8gdGhlIGN1cnJlbnQgcmVuZGVyZWQgbW9udGggKi9cbiAgaW5DdXJyZW50TW9udGg6IGJvb2xlYW47XG5cbiAgLyoqIElTTyBzdHJpbmcgJ1lZWVktTU0tREQnICh0aW1lem9uZS1zYWZlIHZpYSBEYXRlQWRhcHRlcikgKi9cbiAgaXNvOiBzdHJpbmc7XG5cbiAgLyoqIERheSBvZiBtb250aCAoMS0zMSkgKi9cbiAgZGF5OiBudW1iZXI7XG5cbiAgLyoqIE1vbnRoICgwLTExLCBKYXZhU2NyaXB0IGNvbnZlbnRpb24pICovXG4gIG1vbnRoOiBudW1iZXI7XG5cbiAgLyoqIEZ1bGwgeWVhciAqL1xuICB5ZWFyOiBudW1iZXI7XG5cbiAgLyoqIERheSBvZiB3ZWVrICgwID0gU3VuZGF5LCA2ID0gU2F0dXJkYXkpICovXG4gIGRheU9mV2VlazogbnVtYmVyO1xufVxuXG4vKipcbiAqIEEgY2FsZW5kYXIgZ3JpZCByZXByZXNlbnRpbmcgb25lIG1vbnRoXG4gKlxuICogR3JpZCBpcyBhbHdheXMgNiB3ZWVrcyB4IDcgZGF5cyAoNDIgY2VsbHMpIGZvciBsYXlvdXQgc3RhYmlsaXR5LlxuICogSW5jbHVkZXMgcGFkZGluZyBkYXlzIGZyb20gcHJldmlvdXMvbmV4dCBtb250aC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDYWxlbmRhckdyaWQge1xuICAvKiogTW9udGggaWRlbnRpZmllciAqL1xuICBtb250aDoge1xuICAgIC8qKiBZZWFyICovXG4gICAgeWVhcjogbnVtYmVyO1xuICAgIC8qKiBNb250aCAwLTExICovXG4gICAgbW9udGg6IG51bWJlcjtcbiAgfTtcblxuICAvKiogV2VlayBzdGFydCBkYXkgKDAgPSBTdW5kYXksIDEgPSBNb25kYXksIGV0Yy4pICovXG4gIHdlZWtTdGFydDogbnVtYmVyO1xuXG4gIC8qKiBMb2NhbGUgKGZvciBmdXR1cmUgaTE4biwgb3B0aW9uYWwpICovXG4gIGxvY2FsZT86IHN0cmluZztcblxuICAvKiogNiB3ZWVrcyB4IDcgZGF5cyBtYXRyaXggKi9cbiAgd2Vla3M6IENhbGVuZGFyQ2VsbFtdW107XG5cbiAgLyoqIEZsYXQgYXJyYXkgb2YgYWxsIGNlbGxzIChjb252ZW5pZW5jZSBhY2Nlc3NvcikgKi9cbiAgY2VsbHM6IENhbGVuZGFyQ2VsbFtdO1xufVxuXG4vKipcbiAqIENhY2hlIGtleSBmb3IgY2FsZW5kYXIgZ3JpZHNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDYWxlbmRhckdyaWRDYWNoZUtleSB7XG4gIHllYXI6IG51bWJlcjtcbiAgbW9udGg6IG51bWJlcjtcbiAgd2Vla1N0YXJ0OiBudW1iZXI7XG4gIGxvY2FsZT86IHN0cmluZztcbn1cbiJdfQ==
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Range Highlighter Cache
|
|
3
|
-
*
|
|
4
|
-
* LRU cache for decorated calendar grids.
|
|
5
|
-
* Eliminates redundant decoration computations when range/constraints don't change.
|
|
6
|
-
*
|
|
7
|
-
* @module core/calendar-grid/range-highlighter.cache
|
|
8
|
-
* @version 3.9.2
|
|
9
|
-
*/
|
|
10
|
-
import { Injectable, Inject } from '@angular/core';
|
|
11
|
-
import { DATE_ADAPTER } from '../date-adapter';
|
|
12
|
-
import { MAX_CACHE_ENTRIES } from './cache.config';
|
|
13
|
-
import * as i0 from "@angular/core";
|
|
14
|
-
import * as i1 from "./range-highlighter";
|
|
15
|
-
/**
|
|
16
|
-
* Range Highlighter Cache
|
|
17
|
-
*
|
|
18
|
-
* Memoizes decorated grids to avoid recomputing decorations.
|
|
19
|
-
*
|
|
20
|
-
* Cache strategy:
|
|
21
|
-
* - LRU eviction (Map preserves insertion order)
|
|
22
|
-
* - Max 48 entries (v3.9.2: Memory safety for long-running sessions)
|
|
23
|
-
* - Key: month + start + end + hover + disabled signature
|
|
24
|
-
*
|
|
25
|
-
* Performance:
|
|
26
|
-
* - Cache hit: ~0.1ms (object lookup)
|
|
27
|
-
* - Cache miss: ~1ms (decoration + store)
|
|
28
|
-
* - Hit rate: Expected >80% in typical usage
|
|
29
|
-
*
|
|
30
|
-
* Memory safety (v3.9.2):
|
|
31
|
-
* - MAX_CACHE_ENTRIES prevents unbounded growth
|
|
32
|
-
* - Critical for: ERP, BI dashboards, hotel systems
|
|
33
|
-
* - FIFO eviction when limit exceeded
|
|
34
|
-
* - ~720KB max memory footprint
|
|
35
|
-
*
|
|
36
|
-
* Edge cases handled:
|
|
37
|
-
* - Function predicates: Not cacheable (recompute every time)
|
|
38
|
-
* - Large disabled arrays: Sorted + joined for stable key
|
|
39
|
-
* - Hover changes: Separate cache entries
|
|
40
|
-
* - Multi-range mode: Included in key
|
|
41
|
-
*
|
|
42
|
-
* Usage:
|
|
43
|
-
* ```typescript
|
|
44
|
-
* const grid = calendarGridCache.get(monthDate, 0);
|
|
45
|
-
* const decorated = rangeHighlighterCache.get(grid, {
|
|
46
|
-
* start: startDate,
|
|
47
|
-
* end: endDate,
|
|
48
|
-
* hoverDate: '2026-01-20',
|
|
49
|
-
* disabledDates: [...]
|
|
50
|
-
* });
|
|
51
|
-
* // Same params = same object reference (===)
|
|
52
|
-
* ```
|
|
53
|
-
*/
|
|
54
|
-
export class RangeHighlighterCache {
|
|
55
|
-
highlighter;
|
|
56
|
-
adapter;
|
|
57
|
-
cache = new Map();
|
|
58
|
-
maxSize = MAX_CACHE_ENTRIES;
|
|
59
|
-
constructor(highlighter, adapter) {
|
|
60
|
-
this.highlighter = highlighter;
|
|
61
|
-
this.adapter = adapter;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Get decorated grid (cached or computed)
|
|
65
|
-
*
|
|
66
|
-
* If cache hit: Returns existing DecoratedGrid (same object reference)
|
|
67
|
-
* If cache miss: Computes decorations, stores in cache, returns new grid
|
|
68
|
-
*
|
|
69
|
-
* @param grid Base calendar grid (from CalendarGridCache)
|
|
70
|
-
* @param params Decoration parameters
|
|
71
|
-
* @returns Decorated grid with range highlights
|
|
72
|
-
*/
|
|
73
|
-
get(grid, params) {
|
|
74
|
-
// Build cache key
|
|
75
|
-
const cacheKey = this.buildKey(grid, params);
|
|
76
|
-
// Check cache (function predicates can't be cached reliably)
|
|
77
|
-
const hasFunction = typeof params.disabledDates === 'function';
|
|
78
|
-
if (!hasFunction && this.cache.has(cacheKey.full)) {
|
|
79
|
-
// Cache hit: Return existing grid
|
|
80
|
-
const cached = this.cache.get(cacheKey.full);
|
|
81
|
-
// LRU update: Delete and re-insert (moves to end)
|
|
82
|
-
this.cache.delete(cacheKey.full);
|
|
83
|
-
this.cache.set(cacheKey.full, cached);
|
|
84
|
-
return cached;
|
|
85
|
-
}
|
|
86
|
-
// Cache miss: Compute decorations
|
|
87
|
-
const decorated = this.highlighter.decorate(grid, params);
|
|
88
|
-
// Store in cache (only if not using function predicate)
|
|
89
|
-
if (!hasFunction) {
|
|
90
|
-
this.cache.set(cacheKey.full, decorated);
|
|
91
|
-
// Evict oldest if over limit
|
|
92
|
-
if (this.cache.size > this.maxSize) {
|
|
93
|
-
const oldestKey = this.cache.keys().next().value;
|
|
94
|
-
this.cache.delete(oldestKey);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return decorated;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Build cache key from grid and params
|
|
101
|
-
*
|
|
102
|
-
* Key structure:
|
|
103
|
-
* `${monthKey}|${startISO}|${endISO}|${minISO}|${maxISO}|${hoverISO}|${disabledSig}`
|
|
104
|
-
*
|
|
105
|
-
* Example:
|
|
106
|
-
* "2026-1-0-|2026-01-15|2026-01-25|null|null|2026-01-20|2026-01-10,2026-01-11"
|
|
107
|
-
*
|
|
108
|
-
* @param grid Base calendar grid
|
|
109
|
-
* @param params Decoration parameters
|
|
110
|
-
* @returns Cache key components
|
|
111
|
-
*/
|
|
112
|
-
buildKey(grid, params) {
|
|
113
|
-
// Month key (from base grid)
|
|
114
|
-
const monthKey = `${grid.month.year}-${grid.month.month}-${grid.weekStart}-${grid.locale || ''}`;
|
|
115
|
-
// Date ISOs (null if not provided)
|
|
116
|
-
const startISO = params.start ? this.adapter.toISODate(params.start) : 'null';
|
|
117
|
-
const endISO = params.end ? this.adapter.toISODate(params.end) : 'null';
|
|
118
|
-
const minISO = params.minDate ? this.adapter.toISODate(params.minDate) : 'null';
|
|
119
|
-
const maxISO = params.maxDate ? this.adapter.toISODate(params.maxDate) : 'null';
|
|
120
|
-
const hoverISO = params.hoverDate || 'null';
|
|
121
|
-
// Disabled dates signature
|
|
122
|
-
const disabledSignature = this.buildDisabledSignature(params.disabledDates);
|
|
123
|
-
// Multi-range flag (affects hover behavior)
|
|
124
|
-
const multiRangeFlag = params.multiRange ? '1' : '0';
|
|
125
|
-
const selectingStartFlag = params.selectingStartDate ? '1' : '0';
|
|
126
|
-
// Full key (pipe-separated for readability)
|
|
127
|
-
const full = `${monthKey}|${startISO}|${endISO}|${minISO}|${maxISO}|${hoverISO}|${disabledSignature}|${multiRangeFlag}|${selectingStartFlag}`;
|
|
128
|
-
return {
|
|
129
|
-
monthKey,
|
|
130
|
-
startISO,
|
|
131
|
-
endISO,
|
|
132
|
-
minISO,
|
|
133
|
-
maxISO,
|
|
134
|
-
hoverISO,
|
|
135
|
-
disabledSignature,
|
|
136
|
-
full
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Build signature for disabled dates
|
|
141
|
-
*
|
|
142
|
-
* Strategies:
|
|
143
|
-
* - null/undefined: 'none'
|
|
144
|
-
* - Function: 'function' (not cacheable)
|
|
145
|
-
* - Array: Sorted ISO dates joined with commas
|
|
146
|
-
*
|
|
147
|
-
* @param disabledDates Disabled dates specification
|
|
148
|
-
* @returns Signature string for cache key
|
|
149
|
-
*/
|
|
150
|
-
buildDisabledSignature(disabledDates) {
|
|
151
|
-
if (!disabledDates)
|
|
152
|
-
return 'none';
|
|
153
|
-
if (typeof disabledDates === 'function') {
|
|
154
|
-
return 'function';
|
|
155
|
-
}
|
|
156
|
-
if (Array.isArray(disabledDates)) {
|
|
157
|
-
if (disabledDates.length === 0)
|
|
158
|
-
return 'none';
|
|
159
|
-
// Convert to ISO dates, sort, join
|
|
160
|
-
const isoArray = disabledDates
|
|
161
|
-
.map(date => this.adapter.toISODate(date))
|
|
162
|
-
.sort();
|
|
163
|
-
return isoArray.join(',');
|
|
164
|
-
}
|
|
165
|
-
return 'none';
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Clear all cached grids
|
|
169
|
-
*/
|
|
170
|
-
clear() {
|
|
171
|
-
this.cache.clear();
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Get current cache size
|
|
175
|
-
*/
|
|
176
|
-
size() {
|
|
177
|
-
return this.cache.size;
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Check if key is cached
|
|
181
|
-
*
|
|
182
|
-
* @param grid Base calendar grid
|
|
183
|
-
* @param params Decoration parameters
|
|
184
|
-
* @returns True if this grid+params is cached
|
|
185
|
-
*/
|
|
186
|
-
has(grid, params) {
|
|
187
|
-
const key = this.buildKey(grid, params);
|
|
188
|
-
return this.cache.has(key.full);
|
|
189
|
-
}
|
|
190
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RangeHighlighterCache, deps: [{ token: i1.RangeHighlighter }, { token: DATE_ADAPTER }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
191
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RangeHighlighterCache, providedIn: 'root' });
|
|
192
|
-
}
|
|
193
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RangeHighlighterCache, decorators: [{
|
|
194
|
-
type: Injectable,
|
|
195
|
-
args: [{ providedIn: 'root' }]
|
|
196
|
-
}], ctorParameters: () => [{ type: i1.RangeHighlighter }, { type: undefined, decorators: [{
|
|
197
|
-
type: Inject,
|
|
198
|
-
args: [DATE_ADAPTER]
|
|
199
|
-
}] }] });
|
|
200
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZ2UtaGlnaGxpZ2h0ZXIuY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29yZS9jYWxlbmRhci1ncmlkL3JhbmdlLWhpZ2hsaWdodGVyLmNhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFlLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSTVELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFFbkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0NHO0FBRUgsTUFBTSxPQUFPLHFCQUFxQjtJQUt0QjtJQUNzQjtJQUx4QixLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7SUFDekMsT0FBTyxHQUFHLGlCQUFpQixDQUFDO0lBRXBDLFlBQ1UsV0FBNkIsRUFDUCxPQUFvQjtRQUQxQyxnQkFBVyxHQUFYLFdBQVcsQ0FBa0I7UUFDUCxZQUFPLEdBQVAsT0FBTyxDQUFhO0lBQ2pELENBQUM7SUFFSjs7Ozs7Ozs7O09BU0c7SUFDSCxHQUFHLENBQ0QsSUFBa0IsRUFDbEIsTUFBNkI7UUFFN0Isa0JBQWtCO1FBQ2xCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTdDLDZEQUE2RDtRQUM3RCxNQUFNLFdBQVcsR0FBRyxPQUFPLE1BQU0sQ0FBQyxhQUFhLEtBQUssVUFBVSxDQUFDO1FBQy9ELElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDbEQsa0NBQWtDO1lBQ2xDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMs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LEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDeEMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEMsQ0FBQzt3R0FuS1UscUJBQXFCLGtEQU10QixZQUFZOzRHQU5YLHFCQUFxQixjQURSLE1BQU07OzRGQUNuQixxQkFBcUI7a0JBRGpDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFOzswQkFPN0IsTUFBTTsyQkFBQyxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSYW5nZSBIaWdobGlnaHRlciBDYWNoZVxuICogXG4gKiBMUlUgY2FjaGUgZm9yIGRlY29yYXRlZCBjYWxlbmRhciBncmlkcy5cbiAqIEVsaW1pbmF0ZXMgcmVkdW5kYW50IGRlY29yYXRpb24gY29tcHV0YXRpb25zIHdoZW4gcmFuZ2UvY29uc3RyYWludHMgZG9uJ3QgY2hhbmdlLlxuICogXG4gKiBAbW9kdWxlIGNvcmUvY2FsZW5kYXItZ3JpZC9yYW5nZS1oaWdobGlnaHRlci5jYWNoZVxuICogQHZlcnNpb24gMy45LjJcbiAqL1xuXG5pbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERhdGVBZGFwdGVyLCBEQVRFX0FEQVBURVIgfSBmcm9tICcuLi9kYXRlLWFkYXB0ZXInO1xuaW1wb3J0IHsgQ2FsZW5kYXJHcmlkIH0gZnJvbSAnLi9jYWxlbmRhci1ncmlkLnR5cGVzJztcbmltcG9ydCB7IERlY29yYXRlZEdyaWQsIFJhbmdlRGVjb3JhdGlvblBhcmFtcywgRGVjb3JhdGVkR3JpZENhY2hlS2V5IH0gZnJvbSAnLi9yYW5nZS1oaWdobGlnaHRlci50eXBlcyc7XG5pbXBvcnQgeyBSYW5nZUhpZ2hsaWdodGVyIH0gZnJvbSAnLi9yYW5nZS1oaWdobGlnaHRlcic7XG5pbXBvcnQgeyBNQVhfQ0FDSEVfRU5UUklFUyB9IGZyb20gJy4vY2FjaGUuY29uZmlnJztcblxuLyoqXG4gKiBSYW5nZSBIaWdobGlnaHRlciBDYWNoZVxuICogXG4gKiBNZW1vaXplcyBkZWNvcmF0ZWQgZ3JpZHMgdG8gYXZvaWQgcmVjb21wdXRpbmcgZGVjb3JhdGlvbnMuXG4gKiBcbiAqIENhY2hlIHN0cmF0ZWd5OlxuICogLSBMUlUgZXZpY3Rpb24gKE1hcCBwcmVzZXJ2ZXMgaW5zZXJ0aW9uIG9yZGVyKVxuICogLSBNYXggNDggZW50cmllcyAodjMuOS4yOiBNZW1vcnkgc2FmZXR5IGZvciBsb25nLXJ1bm5pbmcgc2Vzc2lvbnMpXG4gKiAtIEtleTogbW9udGggKyBzdGFydCArIGVuZCArIGhvdmVyICsgZGlzYWJsZWQgc2lnbmF0dXJlXG4gKiBcbiAqIFBlcmZvcm1hbmNlOlxuICogLSBDYWNoZSBoaXQ6IH4wLjFtcyAob2JqZWN0IGxvb2t1cClcbiAqIC0gQ2FjaGUgbWlzczogfjFtcyAoZGVjb3JhdGlvbiArIHN0b3JlKVxuICogLSBIaXQgcmF0ZTogRXhwZWN0ZWQgPjgwJSBpbiB0eXBpY2FsIHVzYWdlXG4gKiBcbiAqIE1lbW9yeSBzYWZldHkgKHYzLjkuMik6XG4gKiAtIE1BWF9DQUNIRV9FTlRSSUVTIHByZXZlbnRzIHVuYm91bmRlZCBncm93dGhcbiAqIC0gQ3JpdGljYWwgZm9yOiBFUlAsIEJJIGRhc2hib2FyZHMsIGhvdGVsIHN5c3RlbXNcbiAqIC0gRklGTyBldmljdGlvbiB3aGVuIGxpbWl0IGV4Y2VlZGVkXG4gKiAtIH43MjBLQiBtYXggbWVtb3J5IGZvb3RwcmludFxuICogXG4gKiBFZGdlIGNhc2VzIGhhbmRsZWQ6XG4gKiAtIEZ1bmN0aW9uIHByZWRpY2F0ZXM6IE5vdCBjYWNoZWFibGUgKHJlY29tcHV0ZSBldmVyeSB0aW1lKVxuICogLSBMYXJnZSBkaXNhYmxlZCBhcnJheXM6IFNvcnRlZCArIGpvaW5lZCBmb3Igc3RhYmxlIGtleVxuICogLSBIb3ZlciBjaGFuZ2VzOiBTZXBhcmF0ZSBjYWNoZSBlbnRyaWVzXG4gKiAtIE11bHRpLXJhbmdlIG1vZGU6IEluY2x1ZGVkIGluIGtleVxuICogXG4gKiBVc2FnZTpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGdyaWQgPSBjYWxlbmRhckdyaWRDYWNoZS5nZXQobW9udGhEYXRlLCAwKTtcbiAqIGNvbnN0IGRlY29yYXRlZCA9IHJhbmdlSGlnaGxpZ2h0ZXJDYWNoZS5nZXQoZ3JpZCwge1xuICogICBzdGFydDogc3RhcnREYXRlLFxuICogICBlbmQ6IGVuZERhdGUsXG4gKiAgIGhvdmVyRGF0ZTogJzIwMjYtMDEtMjAnLFxuICogICBkaXNhYmxlZERhdGVzOiBbLi4uXVxuICogfSk7XG4gKiAvLyBTYW1lIHBhcmFtcyA9IHNhbWUgb2JqZWN0IHJlZmVyZW5jZSAoPT09KVxuICogYGBgXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgUmFuZ2VIaWdobGlnaHRlckNhY2hlIHtcbiAgcHJpdmF0ZSBjYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBEZWNvcmF0ZWRHcmlkPigpO1xuICBwcml2YXRlIG1heFNpemUgPSBNQVhfQ0FDSEVfRU5UUklFUztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGhpZ2hsaWdodGVyOiBSYW5nZUhpZ2hsaWdodGVyLFxuICAgIEBJbmplY3QoREFURV9BREFQVEVSKSBwcml2YXRlIGFkYXB0ZXI6IERhdGVBZGFwdGVyXG4gICkge31cblxuICAvKipcbiAgICogR2V0IGRlY29yYXRlZCBncmlkIChjYWNoZWQgb3IgY29tcHV0ZWQpXG4gICAqIFxuICAgKiBJZiBjYWNoZSBoaXQ6IFJldHVybnMgZXhpc3RpbmcgRGVjb3JhdGVkR3JpZCAoc2FtZSBvYmplY3QgcmVmZXJlbmNlKVxuICAgKiBJZiBjYWNoZSBtaXNzOiBDb21wdXRlcyBkZWNvcmF0aW9ucywgc3RvcmVzIGluIGNhY2hlLCByZXR1cm5zIG5ldyBncmlkXG4gICAqIFxuICAgKiBAcGFyYW0gZ3JpZCBCYXNlIGNhbGVuZGFyIGdyaWQgKGZyb20gQ2FsZW5kYXJHcmlkQ2FjaGUpXG4gICAqIEBwYXJhbSBwYXJhbXMgRGVjb3JhdGlvbiBwYXJhbWV0ZXJzXG4gICAqIEByZXR1cm5zIERlY29yYXRlZCBncmlkIHdpdGggcmFuZ2UgaGlnaGxpZ2h0c1xuICAgKi9cbiAgZ2V0KFxuICAgIGdyaWQ6IENhbGVuZGFyR3JpZCxcbiAgICBwYXJhbXM6IFJhbmdlRGVjb3JhdGlvblBhcmFtc1xuICApOiBEZWNvcmF0ZWRHcmlkIHtcbiAgICAvLyBCdWlsZCBjYWNoZSBrZXlcbiAgICBjb25zdCBjYWNoZUtleSA9IHRoaXMuYnVpbGRLZXkoZ3JpZCwgcGFyYW1zKTtcblxuICAgIC8vIENoZWNrIGNhY2hlIChmdW5jdGlvbiBwcmVkaWNhdGVzIGNhbid0IGJlIGNhY2hlZCByZWxpYWJseSlcbiAgICBjb25zdCBoYXNGdW5jdGlvbiA9IHR5cGVvZiBwYXJhbXMuZGlzYWJsZWREYXRlcyA9PT0gJ2Z1bmN0aW9uJztcbiAgICBpZiAoIWhhc0Z1bmN0aW9uICYmIHRoaXMuY2FjaGUuaGFzKGNhY2hlS2V5LmZ1bGwpKSB7XG4gICAgICAvLyBDYWNoZSBoaXQ6IFJldHVybiBleGlzdGluZyBncmlkXG4gICAgICBjb25zdCBjYWNoZWQgPSB0aGlzLmNhY2hlLmdldChjYWNoZUtleS5mdWxsKSE7XG4gICAgICBcbiAgICAgIC8vIExSVSB1cGRhdGU6IERlbGV0ZSBhbmQgcmUtaW5zZXJ0IChtb3ZlcyB0byBlbmQpXG4gICAgICB0aGlzLmNhY2hlLmRlbGV0ZShjYWNoZUtleS5mdWxsKTtcbiAgICAgIHRoaXMuY2FjaGUuc2V0KGNhY2hlS2V5LmZ1bGwsIGNhY2hlZCk7XG4gICAgICBcbiAgICAgIHJldHVybiBjYWNoZWQ7XG4gICAgfVxuXG4gICAgLy8gQ2FjaGUgbWlzczogQ29tcHV0ZSBkZWNvcmF0aW9uc1xuICAgIGNvbnN0IGRlY29yYXRlZCA9IHRoaXMuaGlnaGxpZ2h0ZXIuZGVjb3JhdGUoZ3JpZCwgcGFyYW1zKTtcblxuICAgIC8vIFN0b3JlIGluIGNhY2hlIChvbmx5IGlmIG5vdCB1c2luZyBmdW5jdGlvbiBwcmVkaWNhdGUpXG4gICAgaWYgKCFoYXNGdW5jdGlvbikge1xuICAgICAgdGhpcy5jYWNoZS5zZXQoY2FjaGVLZXkuZnVsbCwgZGVjb3JhdGVkKTtcblxuICAgICAgLy8gRXZpY3Qgb2xkZXN0IGlmIG92ZXIgbGltaXRcbiAgICAgIGlmICh0aGlzLmNhY2hlLnNpemUgPiB0aGlzLm1heFNpemUpIHtcbiAgICAgICAgY29uc3Qgb2xkZXN0S2V5ID0gdGhpcy5jYWNoZS5rZXlzKCkubmV4dCgpLnZhbHVlO1xuICAgICAgICB0aGlzLmNhY2hlLmRlbGV0ZShvbGRlc3RLZXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkZWNvcmF0ZWQ7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgY2FjaGUga2V5IGZyb20gZ3JpZCBhbmQgcGFyYW1zXG4gICAqIFxuICAgKiBLZXkgc3RydWN0dXJlOlxuICAgKiBgJHttb250aEtleX18JHtzdGFydElTT318JHtlbmRJU099fCR7bWluSVNPfXwke21heElTT318JHtob3ZlcklTT318JHtkaXNhYmxlZFNpZ31gXG4gICAqIFxuICAgKiBFeGFtcGxlOlxuICAgKiBcIjIwMjYtMS0wLXwyMDI2LTAxLTE1fDIwMjYtMDEtMjV8bnVsbHxudWxsfDIwMjYtMDEtMjB8MjAyNi0wMS0xMCwyMDI2LTAxLTExXCJcbiAgICogXG4gICAqIEBwYXJhbSBncmlkIEJhc2UgY2FsZW5kYXIgZ3JpZFxuICAgKiBAcGFyYW0gcGFyYW1zIERlY29yYXRpb24gcGFyYW1ldGVyc1xuICAgKiBAcmV0dXJucyBDYWNoZSBrZXkgY29tcG9uZW50c1xuICAgKi9cbiAgcHJpdmF0ZSBidWlsZEtleShcbiAgICBncmlkOiBDYWxlbmRhckdyaWQsXG4gICAgcGFyYW1zOiBSYW5nZURlY29yYXRpb25QYXJhbXNcbiAgKTogRGVjb3JhdGVkR3JpZENhY2hlS2V5IHtcbiAgICAvLyBNb250aCBrZXkgKGZyb20gYmFzZSBncmlkKVxuICAgIGNvbnN0IG1vbnRoS2V5ID0gYCR7Z3JpZC5tb250aC55ZWFyfS0ke2dyaWQubW9udGgubW9udGh9LSR7Z3JpZC53ZWVrU3RhcnR9LSR7Z3JpZC5sb2NhbGUgfHwgJyd9YDtcblxuICAgIC8vIERhdGUgSVNPcyAobnVsbCBpZiBub3QgcHJvdmlkZWQpXG4gICAgY29uc3Qgc3RhcnRJU08gPSBwYXJhbXMuc3RhcnQgPyB0aGlzLmFkYXB0ZXIudG9JU09EYXRlKHBhcmFtcy5zdGFydCkgOiAnbnVsbCc7XG4gICAgY29uc3QgZW5kSVNPID0gcGFyYW1zLmVuZCA/IHRoaXMuYWRhcHRlci50b0lTT0RhdGUocGFyYW1zLmVuZCkgOiAnbnVsbCc7XG4gICAgY29uc3QgbWluSVNPID0gcGFyYW1zLm1pbkRhdGUgPyB0aGlzLmFkYXB0ZXIudG9JU09EYXRlKHBhcmFtcy5taW5EYXRlKSA6ICdudWxsJztcbiAgICBjb25zdCBtYXhJU08gPSBwYXJhbXMubWF4RGF0ZSA/IHRoaXMuYWRhcHRlci50b0lTT0RhdGUocGFyYW1zLm1heERhdGUpIDogJ251bGwnO1xuICAgIGNvbnN0IGhvdmVySVNPID0gcGFyYW1zLmhvdmVyRGF0ZSB8fCAnbnVsbCc7XG5cbiAgICAvLyBEaXNhYmxlZCBkYXRlcyBzaWduYXR1cmVcbiAgICBjb25zdCBkaXNhYmxlZFNpZ25hdHVyZSA9IHRoaXMuYnVpbGREaXNhYmxlZFNpZ25hdHVyZShwYXJhbXMuZGlzYWJsZWREYXRlcyk7XG5cbiAgICAvLyBNdWx0aS1yYW5nZSBmbGFnIChhZmZlY3RzIGhvdmVyIGJlaGF2aW9yKVxuICAgIGNvbnN0IG11bHRpUmFuZ2VGbGFnID0gcGFyYW1zLm11bHRpUmFuZ2UgPyAnMScgOiAnMCc7XG4gICAgY29uc3Qgc2VsZWN0aW5nU3RhcnRGbGFnID0gcGFyYW1zLnNlbGVjdGluZ1N0YXJ0RGF0ZSA/ICcxJyA6ICcwJztcblxuICAgIC8vIEZ1bGwga2V5IChwaXBlLXNlcGFyYXRlZCBmb3IgcmVhZGFiaWxpdHkpXG4gICAgY29uc3QgZnVsbCA9IGAke21vbnRoS2V5fXwke3N0YXJ0SVNPfXwke2VuZElTT318JHttaW5JU099fCR7bWF4SVNPfXwke2hvdmVySVNPfXwke2Rpc2FibGVkU2lnbmF0dXJlfXwke211bHRpUmFuZ2VGbGFnfXwke3NlbGVjdGluZ1N0YXJ0RmxhZ31gO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1vbnRoS2V5LFxuICAgICAgc3RhcnRJU08sXG4gICAgICBlbmRJU08sXG4gICAgICBtaW5JU08sXG4gICAgICBtYXhJU08sXG4gICAgICBob3ZlcklTTyxcbiAgICAgIGRpc2FibGVkU2lnbmF0dXJlLFxuICAgICAgZnVsbFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgc2lnbmF0dXJlIGZvciBkaXNhYmxlZCBkYXRlc1xuICAgKiBcbiAgICogU3RyYXRlZ2llczpcbiAgICogLSBudWxsL3VuZGVmaW5lZDogJ25vbmUnXG4gICAqIC0gRnVuY3Rpb246ICdmdW5jdGlvbicgKG5vdCBjYWNoZWFibGUpXG4gICAqIC0gQXJyYXk6IFNvcnRlZCBJU08gZGF0ZXMgam9pbmVkIHdpdGggY29tbWFzXG4gICAqIFxuICAgKiBAcGFyYW0gZGlzYWJsZWREYXRlcyBEaXNhYmxlZCBkYXRlcyBzcGVjaWZpY2F0aW9uXG4gICAqIEByZXR1cm5zIFNpZ25hdHVyZSBzdHJpbmcgZm9yIGNhY2hlIGtleVxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZERpc2FibGVkU2lnbmF0dXJlKFxuICAgIGRpc2FibGVkRGF0ZXM/OiBEYXRlW10gfCAoKGRhdGU6IERhdGUpID0+IGJvb2xlYW4pIHwgbnVsbFxuICApOiBzdHJpbmcge1xuICAgIGlmICghZGlzYWJsZWREYXRlcykgcmV0dXJuICdub25lJztcblxuICAgIGlmICh0eXBlb2YgZGlzYWJsZWREYXRlcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuICdmdW5jdGlvbic7XG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZGlzYWJsZWREYXRlcykpIHtcbiAgICAgIGlmIChkaXNhYmxlZERhdGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuICdub25lJztcblxuICAgICAgLy8gQ29udmVydCB0byBJU08gZGF0ZXMsIHNvcnQsIGpvaW5cbiAgICAgIGNvbnN0IGlzb0FycmF5ID0gZGlzYWJsZWREYXRlc1xuICAgICAgICAubWFwKGRhdGUgPT4gdGhpcy5hZGFwdGVyLnRvSVNPRGF0ZShkYXRlKSlcbiAgICAgICAgLnNvcnQoKTtcblxuICAgICAgcmV0dXJuIGlzb0FycmF5LmpvaW4oJywnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gJ25vbmUnO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGFsbCBjYWNoZWQgZ3JpZHNcbiAgICovXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMuY2FjaGUuY2xlYXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY3VycmVudCBjYWNoZSBzaXplXG4gICAqL1xuICBzaXplKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuc2l6ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBrZXkgaXMgY2FjaGVkXG4gICAqIFxuICAgKiBAcGFyYW0gZ3JpZCBCYXNlIGNhbGVuZGFyIGdyaWRcbiAgICogQHBhcmFtIHBhcmFtcyBEZWNvcmF0aW9uIHBhcmFtZXRlcnNcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGlzIGdyaWQrcGFyYW1zIGlzIGNhY2hlZFxuICAgKi9cbiAgaGFzKGdyaWQ6IENhbGVuZGFyR3JpZCwgcGFyYW1zOiBSYW5nZURlY29yYXRpb25QYXJhbXMpOiBib29sZWFuIHtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmJ1aWxkS2V5KGdyaWQsIHBhcmFtcyk7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuaGFzKGtleS5mdWxsKTtcbiAgfVxufVxuIl19
|