@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.
- package/README.md +51 -3
- package/core/built-in-presets.d.ts +98 -0
- package/core/date-adapter.d.ts +298 -0
- package/core/date-clock.d.ts +82 -0
- package/core/dual-date-range.store.d.ts +9 -0
- package/core/index.d.ts +15 -0
- package/core/native-date-adapter.d.ts +152 -0
- package/core/preset-providers.d.ts +176 -0
- package/core/preset-registry.d.ts +181 -0
- package/core/preset.engine.d.ts +79 -9
- package/core/range-preset.plugin.d.ts +188 -0
- package/core/system-clock.d.ts +13 -0
- package/dual-datepicker.component.d.ts +17 -11
- package/esm2022/core/built-in-presets.mjs +289 -0
- package/esm2022/core/date-adapter.mjs +77 -0
- package/esm2022/core/date-clock.mjs +65 -0
- package/esm2022/core/dual-date-range.store.mjs +51 -15
- package/esm2022/core/index.mjs +17 -1
- package/esm2022/core/native-date-adapter.mjs +286 -0
- package/esm2022/core/preset-providers.mjs +243 -0
- package/esm2022/core/preset-registry.mjs +277 -0
- package/esm2022/core/preset.engine.mjs +139 -169
- package/esm2022/core/range-preset.plugin.mjs +70 -0
- package/esm2022/core/system-clock.mjs +34 -0
- package/esm2022/dual-datepicker.component.mjs +264 -196
- package/fesm2022/oneluiz-dual-datepicker.mjs +3219 -1822
- package/fesm2022/oneluiz-dual-datepicker.mjs.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Range Preset Plugin System
|
|
3
|
+
*
|
|
4
|
+
* Version: 3.6.0
|
|
5
|
+
*
|
|
6
|
+
* Plugin-based architecture for date range presets following Open/Closed Principle.
|
|
7
|
+
*
|
|
8
|
+
* WHY THIS EXISTS:
|
|
9
|
+
* - Enterprise apps need industry-specific presets (fiscal, hotel, logistics)
|
|
10
|
+
* - Presets should be distributable as external packages
|
|
11
|
+
* - Core should NOT know about all possible presets
|
|
12
|
+
* - Users should extend presets without modifying library code
|
|
13
|
+
*
|
|
14
|
+
* ARCHITECTURE:
|
|
15
|
+
* ```
|
|
16
|
+
* RangePresetPlugin (interface) - Contract for all presets
|
|
17
|
+
* ↓
|
|
18
|
+
* PresetRegistry (service) - Manages plugin registration
|
|
19
|
+
* ↓
|
|
20
|
+
* PresetEngine (refactored) - Resolves presets via registry
|
|
21
|
+
* ↓
|
|
22
|
+
* DualDateRangeStore - No changes, backward compatible
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* USAGE:
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Built-in presets work automatically
|
|
28
|
+
* store.applyPreset('LAST_7_DAYS'); // ✅ Works
|
|
29
|
+
*
|
|
30
|
+
* // Register custom preset
|
|
31
|
+
* const registry = inject(PresetRegistry);
|
|
32
|
+
* registry.register({
|
|
33
|
+
* key: 'THIS_FISCAL_QUARTER',
|
|
34
|
+
* resolve: (clock, adapter) => {
|
|
35
|
+
* const now = clock.now();
|
|
36
|
+
* const fiscalStart = adapter.startOfMonth(now);
|
|
37
|
+
* const fiscalEnd = adapter.endOfMonth(now);
|
|
38
|
+
* return { start: fiscalStart, end: fiscalEnd };
|
|
39
|
+
* }
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // Use custom preset
|
|
43
|
+
* store.applyPreset('THIS_FISCAL_QUARTER'); // ✅ Works
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* EXTERNAL PACKAGES:
|
|
47
|
+
* ```typescript
|
|
48
|
+
* // @acme/fiscal-presets package
|
|
49
|
+
* export const FISCAL_PRESETS: RangePresetPlugin[] = [
|
|
50
|
+
* { key: 'FISCAL_Q1', resolve: ... },
|
|
51
|
+
* { key: 'FISCAL_Q2', resolve: ... }
|
|
52
|
+
* ];
|
|
53
|
+
*
|
|
54
|
+
* // In app
|
|
55
|
+
* FISCAL_PRESETS.forEach(p => registry.register(p));
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
import { DateClock } from './date-clock';
|
|
59
|
+
import { DateAdapter } from './date-adapter';
|
|
60
|
+
/**
|
|
61
|
+
* Date range returned by preset plugins
|
|
62
|
+
*/
|
|
63
|
+
export interface DateRange {
|
|
64
|
+
/**
|
|
65
|
+
* Start date of the range (inclusive)
|
|
66
|
+
*/
|
|
67
|
+
start: Date;
|
|
68
|
+
/**
|
|
69
|
+
* End date of the range (inclusive)
|
|
70
|
+
*/
|
|
71
|
+
end: Date;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Range Preset Plugin Interface
|
|
75
|
+
*
|
|
76
|
+
* All date range presets (built-in or external) implement this interface.
|
|
77
|
+
*
|
|
78
|
+
* DESIGN PRINCIPLES:
|
|
79
|
+
* - **Deterministic**: Given the same clock.now(), always returns same range
|
|
80
|
+
* - **Timezone-safe**: Uses DateAdapter for all date operations
|
|
81
|
+
* - **SSR-compatible**: Uses DateClock injection, no global Date()
|
|
82
|
+
* - **Testable**: Pure function, no side effects
|
|
83
|
+
*
|
|
84
|
+
* EXAMPLE - Built-in preset:
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const todayPreset: RangePresetPlugin = {
|
|
87
|
+
* key: 'TODAY',
|
|
88
|
+
* resolve: (clock, adapter) => {
|
|
89
|
+
* const now = clock.now();
|
|
90
|
+
* const normalized = adapter.normalize(now);
|
|
91
|
+
* return { start: normalized, end: normalized };
|
|
92
|
+
* }
|
|
93
|
+
* };
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* EXAMPLE - Custom fiscal preset:
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const fiscalQuarterPreset: RangePresetPlugin = {
|
|
99
|
+
* key: 'THIS_FISCAL_QUARTER',
|
|
100
|
+
* resolve: (clock, adapter) => {
|
|
101
|
+
* const now = clock.now();
|
|
102
|
+
* const month = adapter.getMonth(now); // 0-11
|
|
103
|
+
*
|
|
104
|
+
* // Fiscal year starts in April (month 3)
|
|
105
|
+
* const fiscalMonth = (month + 9) % 12; // Offset to fiscal calendar
|
|
106
|
+
* const quarterStartMonth = Math.floor(fiscalMonth / 3) * 3;
|
|
107
|
+
* const adjustedMonth = (quarterStartMonth - 9 + 12) % 12;
|
|
108
|
+
*
|
|
109
|
+
* const yearOffset = month < 3 ? -1 : 0;
|
|
110
|
+
* const year = adapter.getYear(now) + yearOffset;
|
|
111
|
+
*
|
|
112
|
+
* const start = new Date(year, adjustedMonth, 1);
|
|
113
|
+
* const end = new Date(year, adjustedMonth + 3, 0);
|
|
114
|
+
*
|
|
115
|
+
* return {
|
|
116
|
+
* start: adapter.normalize(start),
|
|
117
|
+
* end: adapter.normalize(end)
|
|
118
|
+
* };
|
|
119
|
+
* }
|
|
120
|
+
* };
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* EXAMPLE - Hotel industry preset:
|
|
124
|
+
* ```typescript
|
|
125
|
+
* const checkInWeekPreset: RangePresetPlugin = {
|
|
126
|
+
* key: 'CHECK_IN_WEEK',
|
|
127
|
+
* resolve: (clock, adapter) => {
|
|
128
|
+
* const now = clock.now();
|
|
129
|
+
* // Hotel check-ins are Friday to Friday
|
|
130
|
+
* const dayOfWeek = adapter.getDayOfWeek(now);
|
|
131
|
+
* const daysToFriday = dayOfWeek <= 5 ? 5 - dayOfWeek : 7 - dayOfWeek + 5;
|
|
132
|
+
*
|
|
133
|
+
* const nextFriday = adapter.addDays(now, daysToFriday);
|
|
134
|
+
* const followingFriday = adapter.addDays(nextFriday, 7);
|
|
135
|
+
*
|
|
136
|
+
* return { start: nextFriday, end: followingFriday };
|
|
137
|
+
* }
|
|
138
|
+
* };
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export interface RangePresetPlugin {
|
|
142
|
+
/**
|
|
143
|
+
* Unique identifier for the preset
|
|
144
|
+
*
|
|
145
|
+
* Convention: SCREAMING_SNAKE_CASE
|
|
146
|
+
*
|
|
147
|
+
* Examples:
|
|
148
|
+
* - Built-in: 'TODAY', 'LAST_7_DAYS', 'THIS_MONTH'
|
|
149
|
+
* - Fiscal: 'FISCAL_Q1', 'FISCAL_YEAR_TO_DATE'
|
|
150
|
+
* - Hotel: 'CHECK_IN_WEEK', 'NEXT_30_NIGHTS'
|
|
151
|
+
* - Logistics: 'SHIPPING_WEEK', 'DELIVERY_WINDOW'
|
|
152
|
+
*/
|
|
153
|
+
key: string;
|
|
154
|
+
/**
|
|
155
|
+
* Resolve the date range for this preset
|
|
156
|
+
*
|
|
157
|
+
* MUST use:
|
|
158
|
+
* - `clock.now()` for current time (SSR-safe, deterministic)
|
|
159
|
+
* - `adapter.*` for all date operations (timezone-safe)
|
|
160
|
+
*
|
|
161
|
+
* MUST NOT use:
|
|
162
|
+
* - `new Date()` directly (breaks SSR determinism)
|
|
163
|
+
* - `date.toISOString()` (timezone bugs)
|
|
164
|
+
* - `date.setDate()` (mutates, use adapter.addDays() instead)
|
|
165
|
+
*
|
|
166
|
+
* @param clock - Injected DateClock for SSR-safe time access
|
|
167
|
+
* @param adapter - Injected DateAdapter for timezone-safe operations
|
|
168
|
+
* @returns Date range with start and end dates (both inclusive)
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* resolve: (clock, adapter) => {
|
|
173
|
+
* const now = clock.now();
|
|
174
|
+
* const start = adapter.addDays(now, -7);
|
|
175
|
+
* const end = adapter.normalize(now);
|
|
176
|
+
* return { start, end };
|
|
177
|
+
* }
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
resolve(clock: DateClock, adapter: DateAdapter): DateRange;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Type guard to check if object is a valid RangePresetPlugin
|
|
184
|
+
*
|
|
185
|
+
* @param obj - Object to check
|
|
186
|
+
* @returns true if object implements RangePresetPlugin interface
|
|
187
|
+
*/
|
|
188
|
+
export declare function isRangePresetPlugin(obj: any): obj is RangePresetPlugin;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DateClock } from './date-clock';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class SystemClock implements DateClock {
|
|
4
|
+
/**
|
|
5
|
+
* Returns current system time
|
|
6
|
+
*
|
|
7
|
+
* This is the standard behavior for client-side applications.
|
|
8
|
+
* For SSR, override DATE_CLOCK token with a fixed Date.
|
|
9
|
+
*/
|
|
10
|
+
now(): Date;
|
|
11
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SystemClock, never>;
|
|
12
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<SystemClock>;
|
|
13
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EventEmitter, OnInit, OnChanges, SimpleChanges, ElementRef } from '@angular/core';
|
|
2
2
|
import { ControlValueAccessor } from '@angular/forms';
|
|
3
|
+
import { DualDateRangeStore } from './core/dual-date-range.store';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
export interface DateRange {
|
|
5
6
|
startDate: string;
|
|
@@ -30,8 +31,10 @@ export type ThemeType = 'default' | 'bootstrap' | 'bulma' | 'foundation' | 'tail
|
|
|
30
31
|
export declare class DualDatepickerComponent implements OnInit, OnChanges, ControlValueAccessor {
|
|
31
32
|
private elementRef;
|
|
32
33
|
placeholder: string;
|
|
33
|
-
startDate: string;
|
|
34
|
-
|
|
34
|
+
set startDate(value: string);
|
|
35
|
+
get startDate(): string;
|
|
36
|
+
set endDate(value: string);
|
|
37
|
+
get endDate(): string;
|
|
35
38
|
showPresets: boolean;
|
|
36
39
|
showClearButton: boolean;
|
|
37
40
|
multiRange: boolean;
|
|
@@ -61,24 +64,22 @@ export declare class DualDatepickerComponent implements OnInit, OnChanges, Contr
|
|
|
61
64
|
multiDateRangeChange: EventEmitter<MultiDateRange>;
|
|
62
65
|
multiDateRangeSelected: EventEmitter<MultiDateRange>;
|
|
63
66
|
private dateAdapter;
|
|
67
|
+
protected readonly rangeStore: DualDateRangeStore;
|
|
64
68
|
showDatePicker: import("@angular/core").WritableSignal<boolean>;
|
|
65
|
-
dateRangeText: import("@angular/core").WritableSignal<string>;
|
|
66
|
-
selectingStartDate: import("@angular/core").WritableSignal<boolean>;
|
|
67
69
|
currentMonth: import("@angular/core").WritableSignal<any>;
|
|
68
70
|
previousMonth: import("@angular/core").WritableSignal<any>;
|
|
69
71
|
currentMonthDays: import("@angular/core").WritableSignal<any[]>;
|
|
70
72
|
previousMonthDays: import("@angular/core").WritableSignal<any[]>;
|
|
71
73
|
isDisabled: import("@angular/core").WritableSignal<boolean>;
|
|
72
|
-
pendingStartDate: string;
|
|
73
|
-
pendingEndDate: string;
|
|
74
|
-
hasPendingChanges: import("@angular/core").WritableSignal<boolean>;
|
|
75
|
-
startHour: number;
|
|
76
|
-
startMinute: number;
|
|
77
|
-
endHour: number;
|
|
78
|
-
endMinute: number;
|
|
79
74
|
showStartTimePicker: import("@angular/core").WritableSignal<boolean>;
|
|
80
75
|
showEndTimePicker: import("@angular/core").WritableSignal<boolean>;
|
|
81
76
|
hoverDate: import("@angular/core").WritableSignal<string>;
|
|
77
|
+
get startHour(): number;
|
|
78
|
+
get startMinute(): number;
|
|
79
|
+
get endHour(): number;
|
|
80
|
+
get endMinute(): number;
|
|
81
|
+
private setStartHourMinute;
|
|
82
|
+
private setEndHourMinute;
|
|
82
83
|
selectedRanges: import("@angular/core").WritableSignal<DateRange[]>;
|
|
83
84
|
currentRangeIndex: import("@angular/core").WritableSignal<number>;
|
|
84
85
|
focusedDay: import("@angular/core").WritableSignal<{
|
|
@@ -88,6 +89,11 @@ export declare class DualDatepickerComponent implements OnInit, OnChanges, Contr
|
|
|
88
89
|
currentMonthName: import("@angular/core").Signal<string>;
|
|
89
90
|
previousMonthName: import("@angular/core").Signal<string>;
|
|
90
91
|
weekDayNames: import("@angular/core").Signal<string[]>;
|
|
92
|
+
dateRangeText: import("@angular/core").Signal<string>;
|
|
93
|
+
selectingStartDate: import("@angular/core").Signal<boolean>;
|
|
94
|
+
hasPendingChanges: import("@angular/core").Signal<boolean>;
|
|
95
|
+
get pendingStartDate(): string;
|
|
96
|
+
get pendingEndDate(): string;
|
|
91
97
|
private readonly defaultMonthNames;
|
|
92
98
|
private readonly defaultMonthNamesShort;
|
|
93
99
|
private readonly defaultDayNames;
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Date Range Preset Plugins
|
|
3
|
+
*
|
|
4
|
+
* Version: 3.6.0
|
|
5
|
+
*
|
|
6
|
+
* Standard presets provided by the library.
|
|
7
|
+
* All presets use DateClock and DateAdapter for SSR-safety and timezone-safety.
|
|
8
|
+
*
|
|
9
|
+
* PRESETS INCLUDED:
|
|
10
|
+
* - TODAY, YESTERDAY
|
|
11
|
+
* - LAST_7_DAYS, LAST_14_DAYS, LAST_30_DAYS, LAST_60_DAYS, LAST_90_DAYS
|
|
12
|
+
* - THIS_WEEK, LAST_WEEK
|
|
13
|
+
* - THIS_MONTH, LAST_MONTH, MONTH_TO_DATE
|
|
14
|
+
* - THIS_QUARTER, LAST_QUARTER, QUARTER_TO_DATE
|
|
15
|
+
* - THIS_YEAR, LAST_YEAR, YEAR_TO_DATE
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* TODAY - Current day
|
|
19
|
+
*/
|
|
20
|
+
export const TODAY_PRESET = {
|
|
21
|
+
key: 'TODAY',
|
|
22
|
+
resolve: (clock, adapter) => {
|
|
23
|
+
const now = clock.now();
|
|
24
|
+
const normalized = adapter.normalize(now);
|
|
25
|
+
return { start: normalized, end: normalized };
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* YESTERDAY - Previous day
|
|
30
|
+
*/
|
|
31
|
+
export const YESTERDAY_PRESET = {
|
|
32
|
+
key: 'YESTERDAY',
|
|
33
|
+
resolve: (clock, adapter) => {
|
|
34
|
+
const now = clock.now();
|
|
35
|
+
const date = adapter.addDays(now, -1);
|
|
36
|
+
return { start: date, end: date };
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* LAST_7_DAYS - Last 7 days including today
|
|
41
|
+
*/
|
|
42
|
+
export const LAST_7_DAYS_PRESET = {
|
|
43
|
+
key: 'LAST_7_DAYS',
|
|
44
|
+
resolve: (clock, adapter) => {
|
|
45
|
+
const now = clock.now();
|
|
46
|
+
const end = adapter.normalize(now);
|
|
47
|
+
const start = adapter.addDays(now, -6);
|
|
48
|
+
return { start, end };
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* LAST_14_DAYS - Last 14 days including today
|
|
53
|
+
*/
|
|
54
|
+
export const LAST_14_DAYS_PRESET = {
|
|
55
|
+
key: 'LAST_14_DAYS',
|
|
56
|
+
resolve: (clock, adapter) => {
|
|
57
|
+
const now = clock.now();
|
|
58
|
+
const end = adapter.normalize(now);
|
|
59
|
+
const start = adapter.addDays(now, -13);
|
|
60
|
+
return { start, end };
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* LAST_30_DAYS - Last 30 days including today
|
|
65
|
+
*/
|
|
66
|
+
export const LAST_30_DAYS_PRESET = {
|
|
67
|
+
key: 'LAST_30_DAYS',
|
|
68
|
+
resolve: (clock, adapter) => {
|
|
69
|
+
const now = clock.now();
|
|
70
|
+
const end = adapter.normalize(now);
|
|
71
|
+
const start = adapter.addDays(now, -29);
|
|
72
|
+
return { start, end };
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* LAST_60_DAYS - Last 60 days including today
|
|
77
|
+
*/
|
|
78
|
+
export const LAST_60_DAYS_PRESET = {
|
|
79
|
+
key: 'LAST_60_DAYS',
|
|
80
|
+
resolve: (clock, adapter) => {
|
|
81
|
+
const now = clock.now();
|
|
82
|
+
const end = adapter.normalize(now);
|
|
83
|
+
const start = adapter.addDays(now, -59);
|
|
84
|
+
return { start, end };
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* LAST_90_DAYS - Last 90 days including today
|
|
89
|
+
*/
|
|
90
|
+
export const LAST_90_DAYS_PRESET = {
|
|
91
|
+
key: 'LAST_90_DAYS',
|
|
92
|
+
resolve: (clock, adapter) => {
|
|
93
|
+
const now = clock.now();
|
|
94
|
+
const end = adapter.normalize(now);
|
|
95
|
+
const start = adapter.addDays(now, -89);
|
|
96
|
+
return { start, end };
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* THIS_WEEK - Current week (Monday to Sunday)
|
|
101
|
+
*/
|
|
102
|
+
export const THIS_WEEK_PRESET = {
|
|
103
|
+
key: 'THIS_WEEK',
|
|
104
|
+
resolve: (clock, adapter) => {
|
|
105
|
+
const now = clock.now();
|
|
106
|
+
const dayOfWeek = adapter.getDay(now);
|
|
107
|
+
const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
|
|
108
|
+
const start = adapter.addDays(now, -daysToMonday);
|
|
109
|
+
const end = adapter.addDays(start, 6);
|
|
110
|
+
return { start, end };
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* LAST_WEEK - Previous week (Monday to Sunday)
|
|
115
|
+
*/
|
|
116
|
+
export const LAST_WEEK_PRESET = {
|
|
117
|
+
key: 'LAST_WEEK',
|
|
118
|
+
resolve: (clock, adapter) => {
|
|
119
|
+
const now = clock.now();
|
|
120
|
+
const dayOfWeek = adapter.getDay(now);
|
|
121
|
+
const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
|
|
122
|
+
const lastMonday = adapter.addDays(now, -daysToMonday - 7);
|
|
123
|
+
const lastSunday = adapter.addDays(lastMonday, 6);
|
|
124
|
+
return { start: lastMonday, end: lastSunday };
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* THIS_MONTH - Current calendar month (1st to last day)
|
|
129
|
+
*/
|
|
130
|
+
export const THIS_MONTH_PRESET = {
|
|
131
|
+
key: 'THIS_MONTH',
|
|
132
|
+
resolve: (clock, adapter) => {
|
|
133
|
+
const now = clock.now();
|
|
134
|
+
const start = adapter.startOfMonth(now);
|
|
135
|
+
const end = adapter.endOfMonth(now);
|
|
136
|
+
return { start, end };
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* LAST_MONTH - Previous calendar month
|
|
141
|
+
*/
|
|
142
|
+
export const LAST_MONTH_PRESET = {
|
|
143
|
+
key: 'LAST_MONTH',
|
|
144
|
+
resolve: (clock, adapter) => {
|
|
145
|
+
const now = clock.now();
|
|
146
|
+
const lastMonth = adapter.addMonths(now, -1);
|
|
147
|
+
const start = adapter.startOfMonth(lastMonth);
|
|
148
|
+
const end = adapter.endOfMonth(lastMonth);
|
|
149
|
+
return { start, end };
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* MONTH_TO_DATE - From start of current month to today
|
|
154
|
+
*/
|
|
155
|
+
export const MONTH_TO_DATE_PRESET = {
|
|
156
|
+
key: 'MONTH_TO_DATE',
|
|
157
|
+
resolve: (clock, adapter) => {
|
|
158
|
+
const now = clock.now();
|
|
159
|
+
const start = adapter.startOfMonth(now);
|
|
160
|
+
const end = adapter.normalize(now);
|
|
161
|
+
return { start, end };
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* THIS_QUARTER - Current quarter (Q1: Jan-Mar, Q2: Apr-Jun, Q3: Jul-Sep, Q4: Oct-Dec)
|
|
166
|
+
*/
|
|
167
|
+
export const THIS_QUARTER_PRESET = {
|
|
168
|
+
key: 'THIS_QUARTER',
|
|
169
|
+
resolve: (clock, adapter) => {
|
|
170
|
+
const now = clock.now();
|
|
171
|
+
const currentMonth = adapter.getMonth(now);
|
|
172
|
+
const quarterStartMonth = Math.floor(currentMonth / 3) * 3;
|
|
173
|
+
const year = adapter.getYear(now);
|
|
174
|
+
const start = new Date(year, quarterStartMonth, 1);
|
|
175
|
+
const normalizedStart = adapter.normalize(start);
|
|
176
|
+
const end = new Date(year, quarterStartMonth + 3, 0);
|
|
177
|
+
const normalizedEnd = adapter.normalize(end);
|
|
178
|
+
return { start: normalizedStart, end: normalizedEnd };
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* LAST_QUARTER - Previous quarter
|
|
183
|
+
*/
|
|
184
|
+
export const LAST_QUARTER_PRESET = {
|
|
185
|
+
key: 'LAST_QUARTER',
|
|
186
|
+
resolve: (clock, adapter) => {
|
|
187
|
+
const now = clock.now();
|
|
188
|
+
const currentMonth = adapter.getMonth(now);
|
|
189
|
+
const lastQuarterStartMonth = Math.floor(currentMonth / 3) * 3 - 3;
|
|
190
|
+
const year = adapter.getYear(now);
|
|
191
|
+
const adjustedYear = lastQuarterStartMonth < 0 ? year - 1 : year;
|
|
192
|
+
const adjustedMonth = lastQuarterStartMonth < 0 ? 9 : lastQuarterStartMonth;
|
|
193
|
+
const start = new Date(adjustedYear, adjustedMonth, 1);
|
|
194
|
+
const normalizedStart = adapter.normalize(start);
|
|
195
|
+
const end = new Date(adjustedYear, adjustedMonth + 3, 0);
|
|
196
|
+
const normalizedEnd = adapter.normalize(end);
|
|
197
|
+
return { start: normalizedStart, end: normalizedEnd };
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* QUARTER_TO_DATE - From start of current quarter to today
|
|
202
|
+
*/
|
|
203
|
+
export const QUARTER_TO_DATE_PRESET = {
|
|
204
|
+
key: 'QUARTER_TO_DATE',
|
|
205
|
+
resolve: (clock, adapter) => {
|
|
206
|
+
const now = clock.now();
|
|
207
|
+
const currentMonth = adapter.getMonth(now);
|
|
208
|
+
const quarterStartMonth = Math.floor(currentMonth / 3) * 3;
|
|
209
|
+
const year = adapter.getYear(now);
|
|
210
|
+
const start = new Date(year, quarterStartMonth, 1);
|
|
211
|
+
const normalizedStart = adapter.normalize(start);
|
|
212
|
+
const end = adapter.normalize(now);
|
|
213
|
+
return { start: normalizedStart, end };
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* THIS_YEAR - Current calendar year (Jan 1 to Dec 31)
|
|
218
|
+
*/
|
|
219
|
+
export const THIS_YEAR_PRESET = {
|
|
220
|
+
key: 'THIS_YEAR',
|
|
221
|
+
resolve: (clock, adapter) => {
|
|
222
|
+
const now = clock.now();
|
|
223
|
+
const year = adapter.getYear(now);
|
|
224
|
+
const start = new Date(year, 0, 1);
|
|
225
|
+
const end = new Date(year, 11, 31);
|
|
226
|
+
return {
|
|
227
|
+
start: adapter.normalize(start),
|
|
228
|
+
end: adapter.normalize(end)
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
/**
|
|
233
|
+
* LAST_YEAR - Previous calendar year
|
|
234
|
+
*/
|
|
235
|
+
export const LAST_YEAR_PRESET = {
|
|
236
|
+
key: 'LAST_YEAR',
|
|
237
|
+
resolve: (clock, adapter) => {
|
|
238
|
+
const now = clock.now();
|
|
239
|
+
const year = adapter.getYear(now);
|
|
240
|
+
const start = new Date(year - 1, 0, 1);
|
|
241
|
+
const end = new Date(year - 1, 11, 31);
|
|
242
|
+
return {
|
|
243
|
+
start: adapter.normalize(start),
|
|
244
|
+
end: adapter.normalize(end)
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* YEAR_TO_DATE - From start of current year to today
|
|
250
|
+
*/
|
|
251
|
+
export const YEAR_TO_DATE_PRESET = {
|
|
252
|
+
key: 'YEAR_TO_DATE',
|
|
253
|
+
resolve: (clock, adapter) => {
|
|
254
|
+
const now = clock.now();
|
|
255
|
+
const year = adapter.getYear(now);
|
|
256
|
+
const start = new Date(year, 0, 1);
|
|
257
|
+
const end = adapter.normalize(now);
|
|
258
|
+
return { start: adapter.normalize(start), end };
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* All built-in presets as an array
|
|
263
|
+
*
|
|
264
|
+
* Use this to register all built-in presets at once:
|
|
265
|
+
* ```typescript
|
|
266
|
+
* BUILT_IN_PRESETS.forEach(preset => registry.register(preset));
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
export const BUILT_IN_PRESETS = [
|
|
270
|
+
TODAY_PRESET,
|
|
271
|
+
YESTERDAY_PRESET,
|
|
272
|
+
LAST_7_DAYS_PRESET,
|
|
273
|
+
LAST_14_DAYS_PRESET,
|
|
274
|
+
LAST_30_DAYS_PRESET,
|
|
275
|
+
LAST_60_DAYS_PRESET,
|
|
276
|
+
LAST_90_DAYS_PRESET,
|
|
277
|
+
THIS_WEEK_PRESET,
|
|
278
|
+
LAST_WEEK_PRESET,
|
|
279
|
+
THIS_MONTH_PRESET,
|
|
280
|
+
LAST_MONTH_PRESET,
|
|
281
|
+
MONTH_TO_DATE_PRESET,
|
|
282
|
+
THIS_QUARTER_PRESET,
|
|
283
|
+
LAST_QUARTER_PRESET,
|
|
284
|
+
QUARTER_TO_DATE_PRESET,
|
|
285
|
+
THIS_YEAR_PRESET,
|
|
286
|
+
LAST_YEAR_PRESET,
|
|
287
|
+
YEAR_TO_DATE_PRESET
|
|
288
|
+
];
|
|
289
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbHQtaW4tcHJlc2V0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb3JlL2J1aWx0LWluLXByZXNldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBSUg7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQXNCO0lBQzdDLEdBQUcsRUFBRSxPQUFPO0lBQ1osT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1FBQzFCLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN4QixNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUNoRCxDQUFDO0NBQ0YsQ0FBQztBQUVGOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQXNCO0lBQ2pELEdBQUcsRUFBRSxXQUFXO0lBQ2hCLE9BQU8sRUFBRSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtRQUMxQixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDeEIsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDcEMsQ0FBQztDQUNGLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFzQjtJQUNuRCxHQUFHLEVBQUUsYUFBYTtJQUNsQixPQUFPLEVBQUUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDMUIsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFD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QUFDLENBQUM7UUFDbkMsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ2xELENBQUM7Q0FDRixDQUFDO0FBRUY7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUF3QjtJQUNuRCxZQUFZO0lBQ1osZ0JBQWdCO0lBQ2hCLGtCQUFrQjtJQUNsQixtQkFBbUI7SUFDbkIsbUJBQW1CO0lBQ25CLG1CQUFtQjtJQUNuQixtQkFBbUI7SUFDbkIsZ0JBQWdCO0lBQ2hCLGdCQUFnQjtJQUNoQixpQkFBaUI7SUFDakIsaUJBQWlCO0lBQ2pCLG9CQUFvQjtJQUNwQixtQkFBbUI7SUFDbkIsbUJBQW1CO0lBQ25CLHNCQUFzQjtJQUN0QixnQkFBZ0I7SUFDaEIsZ0JBQWdCO0lBQ2hCLG1CQUFtQjtDQUNwQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCdWlsdC1pbiBEYXRlIFJhbmdlIFByZXNldCBQbHVnaW5zXG4gKiBcbiAqIFZlcnNpb246IDMuNi4wXG4gKiBcbiAqIFN0YW5kYXJkIHByZXNldHMgcHJvdmlkZWQgYnkgdGhlIGxpYnJhcnkuXG4gKiBBbGwgcHJlc2V0cyB1c2UgRGF0ZUNsb2NrIGFuZCBEYXRlQWRhcHRlciBmb3IgU1NSLXNhZmV0eSBhbmQgdGltZXpvbmUtc2FmZXR5LlxuICogXG4gKiBQUkVTRVRTIElOQ0xVREVEOlxuICogLSBUT0RBWSwgWUVTVEVSREFZXG4gKiAtIExBU1RfN19EQVlTLCBMQVNUXzE0X0RBWVMsIExBU1RfMzBfREFZUywgTEFTVF82MF9EQVlTLCBMQVNUXzkwX0RBWVNcbiAqIC0gVEhJU19XRUVLLCBMQVNUX1dFRUtcbiAqIC0gVEhJU19NT05USCwgTEFTVF9NT05USCwgTU9OVEhfVE9fREFURVxuICogLSBUSElTX1FVQVJURVIsIExBU1RfUVVBUlRFUiwgUVVBUlRFUl9UT19EQVRFXG4gKiAtIFRISVNfWUVBUiwgTEFTVF9ZRUFSLCBZRUFSX1RPX0RBVEVcbiAqL1xuXG5pbXBvcnQgeyBSYW5nZVByZXNldFBsdWdpbiB9IGZyb20gJy4vcmFuZ2UtcHJlc2V0LnBsdWdpbic7XG5cbi8qKlxuICogVE9EQVkgLSBDdXJyZW50IGRheVxuICovXG5leHBvcnQgY29uc3QgVE9EQVlfUFJFU0VUOiBSYW5nZVByZXNldFBsdWdpbiA9IHtcbiAga2V5OiAnVE9EQVknLFxuICByZXNvbHZlOiAoY2xvY2ssIGFkYXB0ZXIpID0+IHtcbiAgICBjb25zdCBub3cgPSBjbG9jay5ub3coKTtcbiAgICBjb25zdCBub3JtYWxpemVkID0gYWRhcHRlci5ub3JtYWxpemUobm93KTtcbiAgICByZXR1cm4geyBzdGFydDogbm9ybWFsaXplZCwgZW5kOiBub3JtYWxpemVkIH07XG4gIH1cbn07XG5cbi8qKlxuICogWUVTVEVSREFZIC0gUHJldmlvdXMgZGF5XG4gKi9cbmV4cG9ydCBjb25zdCBZRVNURVJEQVlfUFJFU0VUOiBSYW5nZVByZXNldFBsdWdpbiA9IHtcbiAga2V5OiAnWUVTVEVSREFZJyxcbiAgcmVzb2x2ZTogKGNsb2NrLCBhZGFwdGVyKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gY2xvY2subm93KCk7XG4gICAgY29uc3QgZGF0ZSA9IGFkYXB0ZXIuYWRkRGF5cyhub3csIC0xKTtcbiAgICByZXR1cm4geyBzdGFydDogZGF0ZSwgZW5kOiBkYXRlIH07XG4gIH1cbn07XG5cbi8qKlxuICogTEFTVF83X0RBWVMgLSBMYXN0IDcgZGF5cyBpbmNsdWRpbmcgdG9kYXlcbiAqL1xuZXhwb3J0IGNvbnN0IExBU1RfN19EQVlTX1BSRVNFVDogUmFuZ2VQcmVzZXRQbHVnaW4gPSB7XG4gIGtleTogJ0xBU1RfN19EQVlTJyxcbiAgcmVzb2x2ZTogKGNsb2NrLCBhZGFwdGVyKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gY2xvY2subm93KCk7XG4gICAgY29uc3QgZW5kID0gYWRhcHRlci5ub3JtYWxpemUobm93KTtcbiAgICBjb25zdCBzdGFydCA9IGFkYXB0ZXIuYWRkRGF5cyhub3csIC02KTtcbiAgICByZXR1cm4geyBzdGFydCwgZW5kIH07XG4gIH1cbn07XG5cbi8qKlxuICogTEFTVF8xNF9EQVlTIC0gTGFzdCAxNCBkYXlzIGluY2x1ZGluZyB0b2RheVxuICovXG5leHBvcnQgY29uc3QgTEFTVF8xNF9EQVlTX1BSRVNFVDogUmFuZ2VQcmVzZXRQbHVnaW4gPSB7XG4gIGtleTogJ0xBU1RfMTRfREFZUycsXG4gIHJlc29sdmU6IChjbG9jaywgYWRhcHRlcikgPT4ge1xuICAgIGNvbnN0IG5vdyA9IGNsb2NrLm5vdygpO1xuICAgIGNvbnN0IGVuZCA9IGFkYXB0ZXIubm9ybWFsaXplKG5vdyk7XG4gICAgY29uc3Qgc3RhcnQgPSBhZGFwdGVyLmFkZERheXMobm93LCAtMTMpO1xuICAgIHJldHVybiB7IHN0YXJ0LCBlbmQgfTtcbiAgfVxufTtcblxuLyoqXG4gKiBMQVNUXzMwX0RBWVMgLSBMYXN0IDMwIGRheXMgaW5jbHVkaW5nIHRvZGF5XG4gKi9cbmV4cG9ydCBjb25zdCBMQVNUXzMwX0RBWVNfUFJFU0VUOiBSYW5nZVByZXNldFBsdWdpbiA9IHtcbiAga2V5OiAnTEFTVF8zMF9EQVlTJyxcbiAgcmVzb2x2ZTogKGNsb2NrLCBhZGFwdGVyKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gY2xvY2subm93KCk7XG4gICAgY29uc3QgZW5kID0gYWRhcHRlci5ub3JtYWxpemUobm93KTtcbiAgICBjb25zdCBzdGFydCA9IGFkYXB0ZXIuYWRkRGF5cyhub3csIC0yOSk7XG4gICAgcmV0dXJuIHsgc3RhcnQsIGVuZCB9O1xuICB9XG59O1xuXG4vKipcbiAqIExBU1RfNjBfREFZUyAtIExhc3QgNjAgZGF5cyBpbmNsdWRpbmcgdG9kYXlcbiAqL1xuZXhwb3J0IGNvbnN0IExBU1RfNjBfREFZU19QUkVTRVQ6IFJhbmdlUHJlc2V0UGx1Z2luID0ge1xuICBrZXk6ICdMQVNUXzYwX0RBWVMnLFxuICByZXNvbHZlOiAoY2xvY2ssIGFkYXB0ZXIpID0+IHtcbiAgICBjb25zdCBub3cgPSBjbG9jay5ub3coKTtcbiAgICBjb25zdCBlbmQgPSBhZGFwdGVyLm5vcm1hbGl6ZShub3cpO1xuICAgIGNvbnN0IHN0YXJ0ID0gYWRhcHRlci5hZGREYXlzKG5vdywgLTU5KTtcbiAgICByZXR1cm4geyBzdGFydCwgZW5kIH07XG4gIH1cbn07XG5cbi8qKlxuICogTEFTVF85MF9EQVlTIC0gTGFzdCA5MCBkYXlzIGluY2x1ZGluZyB0b2RheVxuICovXG5leHBvcnQgY29uc3QgTEFTVF85MF9EQVlTX1BSRVNFVDogUmFuZ2VQcmVzZXRQbHVnaW4gPSB7XG4gIGtleTogJ0xBU1RfOTBfREFZUycsXG4gIHJlc29sdmU6IChjbG9jaywgYWRhcHRlcikgPT4ge1xuICAgIGNvbnN0IG5vdyA9IGNsb2NrLm5vdygpO1xuICAgIGNvbnN0IGVuZCA9IGFkYXB0ZXIubm9ybWFsaXplKG5vdyk7XG4gICAgY29uc3Qgc3RhcnQgPSBhZGFwdGVyLmFkZERheXMobm93LCAtODkpO1xuICAgIHJldHVybiB7IHN0YXJ0LCBlbmQgfTtcbiAgfVxufTtcblxuLyoqXG4gKiBUSElTX1dFRUsgLSBDdXJyZW50IHdlZWsgKE1vbmRheSB0byBTdW5kYXkpXG4gKi9cbmV4cG9ydCBjb25zdCBUSElTX1dFRUtfUFJFU0VUOiBSYW5nZVByZXNldFBsdWdpbiA9IHtcbiAga2V5OiAnVEhJU19XRUVLJyxcbiAgcmVzb2x2ZTogKGNsb2NrLCBhZGFwdGVyKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gY2xvY2subm93KCk7XG4gICAgY29uc3QgZGF5T2ZXZWVrID0gYWRhcHRlci5nZXREYXkobm93KTtcbiAgICBjb25zdCBkYXlzVG9Nb25kYXkgPSBkYXlPZldlZWsgPT09IDAgPyA2IDogZGF5T2ZXZWVrIC0gMTtcbiAgICBjb25zdCBzdGFydCA9IGFkYXB0ZXIuYWRkRGF5cyhub3csIC1kYXlzVG9Nb25kYXkpO1xuICAgIGNvbnN0IGVuZCA9IGFkYXB0ZXIuYWRkRGF5cyhzdGFydCwgNik7XG4gICAgcmV0dXJuIHsgc3RhcnQsIGVuZCB9O1xuICB9XG59O1xuXG4vKipcbiAqIExBU1RfV0VFSyAtIFByZXZpb3VzIHdlZWsgKE1vbmRheSB0byBTdW5kYXkpXG4gKi9cbmV4cG9ydCBjb25zdCBMQVNUX1dFRUtfUFJFU0VUOiBSYW5nZVByZXNldFBsdWdpbiA9IHtcbiAga2V5OiAnTEFTVF9XRUVLJyxcbiAgcmVzb2x2ZTogKGNsb2NrLCBhZGFwdGVyKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gY2xvY2subm93KCk7XG4gICAgY29uc3QgZGF5T2ZXZWVrID0gYWRhcHRlci5nZXREYXkobm93KTtcbiAgICBjb25zdCBkYXlzVG9Nb25kYXkgPSBkYXlPZldlZWsgPT09IDAgPyA2IDogZGF5T2ZXZWVrIC0gMTtcbiAgICBjb25zdCBsYXN0TW9uZGF5ID0gYWRhcHRlci5hZGREYXlzKG5vdywgLWRheXNUb01vbmRheSAtIDcpO1xuICAgIGNvbnN0IGxhc3RTdW5kYXkgPSBhZGFwdGVyLmFkZERheXMobGFzdE1vbmRheSwgNik7XG4gICAgcmV0dXJuIHsgc3RhcnQ6IGxhc3RNb25kYXksIGVuZDogbGFzdFN1bmRheSB9O1xuICB9XG59O1xuXG4vKipcbiAqIFRISVNfTU9OVEggLSBDdXJyZW50IGNhbGVuZGFyIG1vbnRoICgxc3QgdG8gbGFzdCBkYXkpXG4gKi9cbmV4cG9ydCBjb25zdCBUSElTX01PTlRIX1BSRVNFVDogUmFuZ2VQcmVzZXRQbHVnaW4gPSB7XG4gIGtleTogJ1RISVNfTU9OVEgnLFxuICByZXNvbHZlOiAoY2xvY2ssIGFkYXB0ZXIpID0+IHtcbiAgICBjb25zdCBub3cgPSBjbG9jay5ub3coKTtcbiAgICBjb25zdCBzdGFydCA9IGFkYXB0ZXIuc3RhcnRPZk1vbnRoKG5vdyk7XG4gICAgY29uc3QgZW5kID0gYWRhcHRlci5lbmRPZk1vbnRoKG5vdyk7XG4gICAgcmV0dXJuIHsgc3RhcnQsIGVuZCB9O1xuICB9XG59O1xuXG4vKipcbiAqIExBU1RfTU9OVEggLSBQcmV2aW91cyBjYWxlbmRhciBtb250aFxuICovXG5leHBvcnQgY29uc3QgTEFTVF9NT05USF9QUkVTRVQ6IFJhbmdlUHJlc2V0UGx1Z2luID0ge1xuICBrZXk6ICdMQVNUX01PTlRIJyxcbiAgcmVzb2x2ZTogKGNsb2NrLCBhZGFwdGVyKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gY2xvY2subm93KCk7XG4gICAgY29uc3QgbGFzdE1vbnRoID0gYWRhcHRlci5hZGRNb250aHMobm93LCAtMSk7XG4gICAgY29uc3Qgc3RhcnQgPSBhZGFwdGVyLnN0YXJ0T2ZNb250aChsYXN0TW9udGgpO1xuICAgIGNvbnN0IGVuZCA9IGFkYXB0ZXIuZW5kT2ZNb250aChsYXN0TW9udGgpO1xuICAgIHJldHVybiB7IHN0YXJ0LCBlbmQgfTtcbiAgfVxufTtcblxuLyoqXG4gKiBNT05USF9UT19EQVRFIC0gRnJvbSBzdGFydCBvZiBjdXJyZW50IG1vbnRoIHRvIHRvZGF5XG4gKi9cbmV4cG9ydCBjb25zdCBNT05USF9UT19EQVRFX1BSRVNFVDogUmFuZ2VQcmVzZXRQbHVnaW4gPSB7XG4gIGtleTogJ01PTlRIX1RPX0RBVEUnLFxuICByZXNvbHZlOiAoY2xvY2ssIGFkYXB0ZXIpID0+IHtcbiAgICBjb25zdCBub3cgPSBjbG9jay5ub3coKTtcbiAgICBjb25zdCBzdGFydCA9IGFkYXB0ZXIuc3RhcnRPZk1vbnRoKG5vdyk7XG4gICAgY29uc3QgZW5kID0gYWRhcHRlci5ub3JtYWxpemUobm93KTtcbiAgICByZXR1cm4geyBzdGFydCwgZW5kIH07XG4gIH1cbn07XG5cbi8qKlxuICogVEhJU19RVUFSVEVSIC0gQ3VycmVudCBxdWFydGVyIChRMTogSmFuLU1hciwgUTI6IEFwci1KdW4sIFEzOiBKdWwtU2VwLCBRNDogT2N0LURlYylcbiAqL1xuZXhwb3J0IGNvbnN0IFRISVNfUVVBUlRFUl9QUkVTRVQ6IFJhbmdlUHJlc2V0UGx1Z2luID0ge1xuICBrZXk6ICdUSElTX1FVQVJURVInLFxuICByZXNvbHZlOiAoY2xvY2ssIGFkYXB0ZXIpID0+IHtcbiAgICBjb25zdCBub3cgPSBjbG9jay5ub3coKTtcbiAgICBjb25zdCBjdXJyZW50TW9udGggPSBhZGFwdGVyLmdldE1vbnRoKG5vdyk7XG4gICAgY29uc3QgcXVhcnRlclN0YXJ0TW9udGggPSBNYXRoLmZsb29yKGN1cnJlbnRNb250aCAvIDMpICogMztcbiAgICBjb25zdCB5ZWFyID0gYWRhcHRlci5nZXRZZWFyKG5vdyk7XG4gICAgXG4gICAgY29uc3Qgc3RhcnQgPSBuZXcgRGF0ZSh5ZWFyLCBxdWFydGVyU3RhcnRNb250aCwgMSk7XG4gICAgY29uc3Qgbm9ybWFsaXplZFN0YXJ0ID0gYWRhcHRlci5ub3JtYWxpemUoc3RhcnQpO1xuICAgIFxuICAgIGNvbnN0IGVuZCA9IG5ldyBEYXRlKHllYXIsIHF1YXJ0ZXJTdGFydE1vbnRoICsgMywgMCk7XG4gICAgY29uc3Qgbm9ybWFsaXplZEVuZCA9IGFkYXB0ZXIubm9ybWFsaXplKGVuZCk7XG4gICAgXG4gICAgcmV0dXJuIHsgc3RhcnQ6IG5vcm1hbGl6ZWRTdGFydCwgZW5kOiBub3JtYWxpemVkRW5kIH07XG4gIH1cbn07XG5cbi8qKlxuICogTEFTVF9RVUFSVEVSIC0gUHJldmlvdXMgcXVhcnRlclxuICovXG5leHBvcnQgY29uc3QgTEFTVF9RVUFSVEVSX1BSRVNFVDogUmFuZ2VQcmVzZXRQbHVnaW4gPSB7XG4gIGtleTogJ0xBU1RfUVVBUlRFUicsXG4gIHJlc29sdmU6IChjbG9jaywgYWRhcHRlcikgPT4ge1xuICAgIGNvbnN0IG5vdyA9IGNsb2NrLm5vdygpO1xuICAgIGNvbnN0IGN1cnJlbnRNb250aCA9IGFkYXB0ZXIuZ2V0TW9udGgobm93KTtcbiAgICBjb25zdCBsYXN0UXVhcnRlclN0YXJ0TW9udGggPSBNYXRoLmZsb29yKGN1cnJlbnRNb250aCAvIDMpICogMyAtIDM7XG4gICAgY29uc3QgeWVhciA9IGFkYXB0ZXIuZ2V0WWVhcihub3cpO1xuICAgIFxuICAgIGNvbnN0IGFkanVzdGVkWWVhciA9IGxhc3RRdWFydGVyU3RhcnRNb250aCA8IDAgPyB5ZWFyIC0gMSA6IHllYXI7XG4gICAgY29uc3QgYWRqdXN0ZWRNb250aCA9IGxhc3RRdWFydGVyU3RhcnRNb250aCA8IDAgPyA5IDogbGFzdFF1YXJ0ZXJTdGFydE1vbnRoO1xuICAgIFxuICAgIGNvbnN0IHN0YXJ0ID0gbmV3IERhdGUoYWRqdXN0ZWRZZWFyLCBhZGp1c3RlZE1vbnRoLCAxKTtcbiAgICBjb25zdCBub3JtYWxpemVkU3RhcnQgPSBhZGFwdGVyLm5vcm1hbGl6ZShzdGFydCk7XG4gICAgXG4gICAgY29uc3QgZW5kID0gbmV3IERhdGUoYWRqdXN0ZWRZZWFyLCBhZGp1c3RlZE1vbnRoICsgMywgMCk7XG4gICAgY29uc3Qgbm9ybWFsaXplZEVuZCA9IGFkYXB0ZXIubm9ybWFsaXplKGVuZCk7XG4gICAgXG4gICAgcmV0dXJuIHsgc3RhcnQ6IG5vcm1hbGl6ZWRTdGFydCwgZW5kOiBub3JtYWxpemVkRW5kIH07XG4gIH1cbn07XG5cbi8qKlxuICogUVVBUlRFUl9UT19EQVRFIC0gRnJvbSBzdGFydCBvZiBjdXJyZW50IHF1YXJ0ZXIgdG8gdG9kYXlcbiAqL1xuZXhwb3J0IGNvbnN0IFFVQVJURVJfVE9fREFURV9QUkVTRVQ6IFJhbmdlUHJlc2V0UGx1Z2luID0ge1xuICBrZXk6ICdRVUFSVEVSX1RPX0RBVEUnLFxuICByZXNvbHZlOiAoY2xvY2ssIGFkYXB0ZXIpID0+IHtcbiAgICBjb25zdCBub3cgPSBjbG9jay5ub3coKTtcbiAgICBjb25zdCBjdXJyZW50TW9udGggPSBhZGFwdGVyLmdldE1vbnRoKG5vdyk7XG4gICAgY29uc3QgcXVhcnRlclN0YXJ0TW9udGggPSBNYXRoLmZsb29yKGN1cnJlbnRNb250aCAvIDMpICogMztcbiAgICBjb25zdCB5ZWFyID0gYWRhcHRlci5nZXRZZWFyKG5vdyk7XG4gICAgXG4gICAgY29uc3Qgc3RhcnQgPSBuZXcgRGF0ZSh5ZWFyLCBxdWFydGVyU3RhcnRNb250aCwgMSk7XG4gICAgY29uc3Qgbm9ybWFsaXplZFN0YXJ0ID0gYWRhcHRlci5ub3JtYWxpemUoc3RhcnQpO1xuICAgIGNvbnN0IGVuZCA9IGFkYXB0ZXIubm9ybWFsaXplKG5vdyk7XG4gICAgXG4gICAgcmV0dXJuIHsgc3RhcnQ6IG5vcm1hbGl6ZWRTdGFydCwgZW5kIH07XG4gIH1cbn07XG5cbi8qKlxuICogVEhJU19ZRUFSIC0gQ3VycmVudCBjYWxlbmRhciB5ZWFyIChKYW4gMSB0byBEZWMgMzEpXG4gKi9cbmV4cG9ydCBjb25zdCBUSElTX1lFQVJfUFJFU0VUOiBSYW5nZVByZXNldFBsdWdpbiA9IHtcbiAga2V5OiAnVEhJU19ZRUFSJyxcbiAgcmVzb2x2ZTogKGNsb2NrLCBhZGFwdGVyKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gY2xvY2subm93KCk7XG4gICAgY29uc3QgeWVhciA9IGFkYXB0ZXIuZ2V0WWVhcihub3cpO1xuICAgIGNvbnN0IHN0YXJ0ID0gbmV3IERhdGUoeWVhciwgMCwgMSk7XG4gICAgY29uc3QgZW5kID0gbmV3IERhdGUoeWVhciwgMTEsIDMxKTtcbiAgICByZXR1cm4geyBcbiAgICAgIHN0YXJ0OiBhZGFwdGVyLm5vcm1hbGl6ZShzdGFydCksIFxuICAgICAgZW5kOiBhZGFwdGVyLm5vcm1hbGl6ZShlbmQpIFxuICAgIH07XG4gIH1cbn07XG5cbi8qKlxuICogTEFTVF9ZRUFSIC0gUHJldmlvdXMgY2FsZW5kYXIgeWVhclxuICovXG5leHBvcnQgY29uc3QgTEFTVF9ZRUFSX1BSRVNFVDogUmFuZ2VQcmVzZXRQbHVnaW4gPSB7XG4gIGtleTogJ0xBU1RfWUVBUicsXG4gIHJlc29sdmU6IChjbG9jaywgYWRhcHRlcikgPT4ge1xuICAgIGNvbnN0IG5vdyA9IGNsb2NrLm5vdygpO1xuICAgIGNvbnN0IHllYXIgPSBhZGFwdGVyLmdldFllYXIobm93KTtcbiAgICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKHllYXIgLSAxLCAwLCAxKTtcbiAgICBjb25zdCBlbmQgPSBuZXcgRGF0ZSh5ZWFyIC0gMSwgMTEsIDMxKTtcbiAgICByZXR1cm4geyBcbiAgICAgIHN0YXJ0OiBhZGFwdGVyLm5vcm1hbGl6ZShzdGFydCksIFxuICAgICAgZW5kOiBhZGFwdGVyLm5vcm1hbGl6ZShlbmQpIFxuICAgIH07XG4gIH1cbn07XG5cbi8qKlxuICogWUVBUl9UT19EQVRFIC0gRnJvbSBzdGFydCBvZiBjdXJyZW50IHllYXIgdG8gdG9kYXlcbiAqL1xuZXhwb3J0IGNvbnN0IFlFQVJfVE9fREFURV9QUkVTRVQ6IFJhbmdlUHJlc2V0UGx1Z2luID0ge1xuICBrZXk6ICdZRUFSX1RPX0RBVEUnLFxuICByZXNvbHZlOiAoY2xvY2ssIGFkYXB0ZXIpID0+IHtcbiAgICBjb25zdCBub3cgPSBjbG9jay5ub3coKTtcbiAgICBjb25zdCB5ZWFyID0gYWRhcHRlci5nZXRZZWFyKG5vdyk7XG4gICAgY29uc3Qgc3RhcnQgPSBuZXcgRGF0ZSh5ZWFyLCAwLCAxKTtcbiAgICBjb25zdCBlbmQgPSBhZGFwdGVyLm5vcm1hbGl6ZShub3cpO1xuICAgIHJldHVybiB7IHN0YXJ0OiBhZGFwdGVyLm5vcm1hbGl6ZShzdGFydCksIGVuZCB9O1xuICB9XG59O1xuXG4vKipcbiAqIEFsbCBidWlsdC1pbiBwcmVzZXRzIGFzIGFuIGFycmF5XG4gKiBcbiAqIFVzZSB0aGlzIHRvIHJlZ2lzdGVyIGFsbCBidWlsdC1pbiBwcmVzZXRzIGF0IG9uY2U6XG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBCVUlMVF9JTl9QUkVTRVRTLmZvckVhY2gocHJlc2V0ID0+IHJlZ2lzdHJ5LnJlZ2lzdGVyKHByZXNldCkpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBCVUlMVF9JTl9QUkVTRVRTOiBSYW5nZVByZXNldFBsdWdpbltdID0gW1xuICBUT0RBWV9QUkVTRVQsXG4gIFlFU1RFUkRBWV9QUkVTRVQsXG4gIExBU1RfN19EQVlTX1BSRVNFVCxcbiAgTEFTVF8xNF9EQVlTX1BSRVNFVCxcbiAgTEFTVF8zMF9EQVlTX1BSRVNFVCxcbiAgTEFTVF82MF9EQVlTX1BSRVNFVCxcbiAgTEFTVF85MF9EQVlTX1BSRVNFVCxcbiAgVEhJU19XRUVLX1BSRVNFVCxcbiAgTEFTVF9XRUVLX1BSRVNFVCxcbiAgVEhJU19NT05USF9QUkVTRVQsXG4gIExBU1RfTU9OVEhfUFJFU0VULFxuICBNT05USF9UT19EQVRFX1BSRVNFVCxcbiAgVEhJU19RVUFSVEVSX1BSRVNFVCxcbiAgTEFTVF9RVUFSVEVSX1BSRVNFVCxcbiAgUVVBUlRFUl9UT19EQVRFX1BSRVNFVCxcbiAgVEhJU19ZRUFSX1BSRVNFVCxcbiAgTEFTVF9ZRUFSX1BSRVNFVCxcbiAgWUVBUl9UT19EQVRFX1BSRVNFVFxuXTtcbiJdfQ==
|