;\n // Normalize each target\n Object.entries(result).forEach(([targetType, targetConfig]) => {\n let targetColor = rootColor;\n if (targetConfig === true || isString(targetConfig)) {\n targetColor = isString(targetConfig) ? targetConfig : targetColor;\n // @ts-ignore\n result[targetType] = { color: targetColor };\n } else if (isObject(targetConfig)) {\n if (hasAny(targetConfig, displayProps)) {\n // @ts-ignore\n result[targetType] = { ...targetConfig };\n } else {\n // @ts-ignore\n result[targetType] = {};\n }\n }\n // Set the theme color if it is missing\n // @ts-ignore\n defaultsDeep(result[targetType], { color: targetColor });\n });\n return result;\n}\n\nexport interface GlyphRenderer> {\n type: string;\n normalizeConfig(color: string, config: any): Profile
;\n prepareRender(glyphs: Record): void;\n render(attr: DateRangeCell, glyphs: Record): void;\n}\n\nexport class HighlightRenderer implements GlyphRenderer {\n type = 'highlight';\n\n normalizeConfig(color: string, config: any) {\n return normalizeConfig(color, config, {\n base: { fillMode: 'light' },\n start: { fillMode: 'solid' },\n end: { fillMode: 'solid' },\n }) as Profile;\n }\n\n prepareRender(glyphs: Record) {\n glyphs.highlights = [];\n if (!glyphs.content) glyphs.content = [];\n }\n\n render(\n { data, onStart, onEnd }: DateRangeCell,\n glyphs: Record,\n ) {\n const { key, highlight } = data;\n if (!highlight) return;\n const { highlights } = glyphs;\n const { base, start, end } = highlight;\n if (onStart && onEnd) {\n highlights.push({\n ...start,\n key,\n wrapperClass: `vc-day-layer vc-day-box-center-center vc-attr vc-${start.color}`,\n class: [`vc-highlight vc-highlight-bg-${start.fillMode}`, start.class],\n contentClass: [\n `vc-attr vc-highlight-content-${start.fillMode} vc-${start.color}`,\n start.contentClass,\n ],\n });\n } else if (onStart) {\n highlights.push({\n ...base,\n key: `${key}-base`,\n wrapperClass: `vc-day-layer vc-day-box-right-center vc-attr vc-${base.color}`,\n class: [\n `vc-highlight vc-highlight-base-start vc-highlight-bg-${base.fillMode}`,\n base.class,\n ],\n });\n highlights.push({\n ...start,\n key,\n wrapperClass: `vc-day-layer vc-day-box-center-center vc-attr vc-${start.color}`,\n class: [`vc-highlight vc-highlight-bg-${start.fillMode}`, start.class],\n contentClass: [\n `vc-attr vc-highlight-content-${start.fillMode} vc-${start.color}`,\n start.contentClass,\n ],\n });\n } else if (onEnd) {\n highlights.push({\n ...base,\n key: `${key}-base`,\n wrapperClass: `vc-day-layer vc-day-box-left-center vc-attr vc-${base.color}`,\n class: [\n `vc-highlight vc-highlight-base-end vc-highlight-bg-${base.fillMode}`,\n base.class,\n ],\n });\n highlights.push({\n ...end,\n key,\n wrapperClass: `vc-day-layer vc-day-box-center-center vc-attr vc-${end.color}`,\n class: [`vc-highlight vc-highlight-bg-${end.fillMode}`, end.class],\n contentClass: [\n `vc-attr vc-highlight-content-${end.fillMode} vc-${end.color}`,\n end.contentClass,\n ],\n });\n } else {\n highlights.push({\n ...base,\n key: `${key}-middle`,\n wrapperClass: `vc-day-layer vc-day-box-center-center vc-attr vc-${base.color}`,\n class: [\n `vc-highlight vc-highlight-base-middle vc-highlight-bg-${base.fillMode}`,\n base.class,\n ],\n contentClass: [\n `vc-attr vc-highlight-content-${base.fillMode} vc-${base.color}`,\n base.contentClass,\n ],\n });\n }\n }\n}\n\nexport class BaseRenderer>\n implements GlyphRenderer\n{\n type = '';\n collectionType = '';\n\n constructor(type: string, collectionType: string) {\n this.type = type;\n this.collectionType = collectionType;\n }\n\n normalizeConfig(color: string, config: any) {\n return normalizeConfig(color, config) as Profile;\n }\n\n prepareRender(glyphs: Record) {\n glyphs[this.collectionType] = [];\n }\n\n render(\n { data, onStart, onEnd }: DateRangeCell,\n glyphs: Record,\n ) {\n const { key } = data;\n const item = data[this.type as keyof Attribute];\n if (!key || !item) return;\n const collection = glyphs[this.collectionType];\n const { base, start, end } = item;\n if (onStart) {\n collection.push({\n ...start,\n key,\n class: [\n `vc-${this.type} vc-${this.type}-start vc-${start.color} vc-attr`,\n start.class,\n ],\n });\n } else if (onEnd) {\n collection.push({\n ...end,\n key,\n class: [\n `vc-${this.type} vc-${this.type}-end vc-${end.color} vc-attr`,\n end.class,\n ],\n });\n } else {\n collection.push({\n ...base,\n key,\n class: [\n `vc-${this.type} vc-${this.type}-base vc-${base.color} vc-attr`,\n base.class,\n ],\n });\n }\n }\n}\n\nexport class ContentRenderer extends BaseRenderer {\n constructor() {\n super('content', 'content');\n }\n\n normalizeConfig(_: string, config: any) {\n return normalizeConfig('base', config) as Profile;\n }\n}\n\nexport class DotRenderer extends BaseRenderer {\n constructor() {\n super('dot', 'dots');\n }\n}\n\nexport class BarRenderer extends BaseRenderer {\n constructor() {\n super('bar', 'bars');\n }\n}\n","import { Attribute } from './attribute';\nimport type { DateRangeCell } from '@/utils/date/range';\nimport {\n type Bar,\n type Content,\n type Dot,\n type GlyphRenderer,\n type Glyph,\n type Highlight,\n ContentRenderer,\n HighlightRenderer,\n DotRenderer,\n BarRenderer,\n} from './glyph';\n\nexport interface Glyphs {\n highlights: Highlight[];\n dots: Dot[];\n bars: Bar[];\n content: Content[];\n}\n\nexport class Theme {\n color: string;\n renderers: GlyphRenderer[] = [\n new ContentRenderer(),\n new HighlightRenderer(),\n new DotRenderer(),\n new BarRenderer(),\n ];\n\n constructor(color: string) {\n this.color = color;\n }\n\n normalizeGlyphs(attr: Attribute) {\n this.renderers.forEach(renderer => {\n const type = renderer.type as keyof Attribute;\n if (attr[type] != null) {\n // @ts-ignore\n attr[type] = renderer.normalizeConfig(this.color, attr[type]);\n }\n });\n }\n\n prepareRender(glyphs: Partial = {}) {\n this.renderers.forEach(renderer => {\n renderer.prepareRender(glyphs);\n });\n return glyphs;\n }\n\n render(cell: DateRangeCell, glyphs: Partial) {\n this.renderers.forEach(renderer => {\n renderer.render(cell, glyphs);\n });\n }\n}\n","interface LocaleConfig {\n dow: number;\n L: string;\n}\n\ninterface LocaleSetting {\n id: string;\n firstDayOfWeek: number;\n masks: {\n L: string;\n };\n}\n\nconst locales: Record = {\n // Arabic\n ar: { dow: 7, L: 'D/\\u200FM/\\u200FYYYY' },\n // Bulgarian\n bg: { dow: 2, L: 'D.MM.YYYY' },\n // Catalan\n ca: { dow: 2, L: 'DD/MM/YYYY' },\n // Chinese (China)\n 'zh-CN': { dow: 2, L: 'YYYY/MM/DD' },\n // Chinese (Taiwan)\n 'zh-TW': { dow: 1, L: 'YYYY/MM/DD' },\n // Croatian\n hr: { dow: 2, L: 'DD.MM.YYYY' },\n // Czech\n cs: { dow: 2, L: 'DD.MM.YYYY' },\n // Danish\n da: { dow: 2, L: 'DD.MM.YYYY' },\n // Dutch\n nl: { dow: 2, L: 'DD-MM-YYYY' },\n // English (US)\n 'en-US': { dow: 1, L: 'MM/DD/YYYY' },\n // English (Australia)\n 'en-AU': { dow: 2, L: 'DD/MM/YYYY' },\n // English (Canada)\n 'en-CA': { dow: 1, L: 'YYYY-MM-DD' },\n // English (Great Britain)\n 'en-GB': { dow: 2, L: 'DD/MM/YYYY' },\n // English (Ireland)\n 'en-IE': { dow: 2, L: 'DD-MM-YYYY' },\n // English (New Zealand)\n 'en-NZ': { dow: 2, L: 'DD/MM/YYYY' },\n // English (South Africa)\n 'en-ZA': { dow: 1, L: 'YYYY/MM/DD' },\n // Esperanto\n eo: { dow: 2, L: 'YYYY-MM-DD' },\n // Estonian\n et: { dow: 2, L: 'DD.MM.YYYY' },\n // Finnish\n fi: { dow: 2, L: 'DD.MM.YYYY' },\n // French\n fr: { dow: 2, L: 'DD/MM/YYYY' },\n // French (Canada)\n 'fr-CA': { dow: 1, L: 'YYYY-MM-DD' },\n // French (Switzerland)\n 'fr-CH': { dow: 2, L: 'DD.MM.YYYY' },\n // German\n de: { dow: 2, L: 'DD.MM.YYYY' },\n // Hebrew\n he: { dow: 1, L: 'DD.MM.YYYY' },\n // Indonesian\n id: { dow: 2, L: 'DD/MM/YYYY' },\n // Italian\n it: { dow: 2, L: 'DD/MM/YYYY' },\n // Japanese\n ja: { dow: 1, L: 'YYYY年M月D日' },\n // Korean\n ko: { dow: 1, L: 'YYYY.MM.DD' },\n // Latvian\n lv: { dow: 2, L: 'DD.MM.YYYY' },\n // Lithuanian\n lt: { dow: 2, L: 'DD.MM.YYYY' },\n // Macedonian\n mk: { dow: 2, L: 'D.MM.YYYY' },\n // Norwegian\n nb: { dow: 2, L: 'D. MMMM YYYY' },\n nn: { dow: 2, L: 'D. MMMM YYYY' },\n // Polish\n pl: { dow: 2, L: 'DD.MM.YYYY' },\n // Portuguese\n pt: { dow: 2, L: 'DD/MM/YYYY' },\n // Romanian\n ro: { dow: 2, L: 'DD.MM.YYYY' },\n // Russian\n ru: { dow: 2, L: 'DD.MM.YYYY' },\n // Slovak\n sk: { dow: 2, L: 'DD.MM.YYYY' },\n // Spanish (Spain)\n 'es-ES': { dow: 2, L: 'DD/MM/YYYY' },\n // Spanish (Mexico)\n 'es-MX': { dow: 2, L: 'DD/MM/YYYY' },\n // Swedish\n sv: { dow: 2, L: 'YYYY-MM-DD' },\n // Thai\n th: { dow: 1, L: 'DD/MM/YYYY' },\n // Turkish\n tr: { dow: 2, L: 'DD.MM.YYYY' },\n // Ukrainian\n uk: { dow: 2, L: 'DD.MM.YYYY' },\n // Vietnam\n vi: { dow: 2, L: 'DD/MM/YYYY' },\n};\nlocales.en = locales['en-US'];\nlocales.es = locales['es-ES'];\nlocales.no = locales.nb;\nlocales.zh = locales['zh-CN'];\n\n// Remap from abbr. to intuitive property names\nconst localeSettings = Object.entries(locales).reduce(\n (res, [id, { dow, L }]) => {\n res[id] = {\n id,\n firstDayOfWeek: dow,\n masks: { L },\n };\n return res;\n },\n {} as Record,\n);\n\nexport default localeSettings;\n","import { type App, reactive, computed } from 'vue';\nimport type { DarkModeConfig } from 'vue-screen-utils';\nimport { defaultsDeep, mapValues, get, has } from '../helpers';\nimport touch from './touch.json';\nimport masks from './masks.json';\nimport locales from './locales';\n\ndeclare const window: any;\n\ninterface DatePickerPopoverDefaults {\n visibility?: string;\n placement?: string;\n isInteractive?: boolean;\n}\n\ninterface DatePickerDefaults {\n updateOnInput?: boolean;\n inputDebounce?: number;\n popover?: DatePickerPopoverDefaults;\n}\n\nexport interface Defaults {\n componentPrefix?: string;\n color?: string;\n isDark?: DarkModeConfig;\n navVisibility?: string;\n titlePosition?: string;\n transition?: string;\n touch?: object;\n masks?: object;\n locales?: any;\n datePicker?: DatePickerDefaults;\n}\n\nconst defaultConfig: Defaults = {\n componentPrefix: 'V',\n color: 'blue',\n isDark: false,\n navVisibility: 'click',\n titlePosition: 'center',\n transition: 'slide-h',\n touch,\n masks,\n locales,\n datePicker: {\n updateOnInput: true,\n inputDebounce: 1000,\n popover: {\n visibility: 'hover-focus',\n placement: 'bottom-start',\n isInteractive: true,\n },\n },\n};\n\nconst state = reactive(defaultConfig);\n\nconst defaultLocales = computed(() => {\n return mapValues(state.locales, (l: any) => {\n l.masks = defaultsDeep(l.masks, state.masks);\n return l;\n });\n});\n\nexport { defaultLocales };\n\nexport const getDefault = (path: string) => {\n if (typeof window !== 'undefined' && has(window.__vcalendar__, path)) {\n return get(window.__vcalendar__, path);\n }\n return get(state, path);\n};\n\nexport const setupDefaults = (app: App, userDefaults: Defaults | undefined) => {\n app.config.globalProperties.$VCalendar = state;\n return Object.assign(state, defaultsDeep(userDefaults, state));\n};\n","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = toInteger;\n\nfunction toInteger(dirtyNumber) {\n if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {\n return NaN;\n }\n\n var number = Number(dirtyNumber);\n\n if (isNaN(number)) {\n return number;\n }\n\n return number < 0 ? Math.ceil(number) : Math.floor(number);\n}\n\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = getTimezoneOffsetInMilliseconds;\n\n/**\n * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.\n * They usually appear for dates that denote time before the timezones were introduced\n * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891\n * and GMT+01:00:00 after that date)\n *\n * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,\n * which would lead to incorrect calculations.\n *\n * This function returns the timezone offset in milliseconds that takes seconds in account.\n */\nfunction getTimezoneOffsetInMilliseconds(date) {\n var utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));\n utcDate.setUTCFullYear(date.getFullYear());\n return date.getTime() - utcDate.getTime();\n}\n\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = tzTokenizeDate;\n\n/**\n * Returns the [year, month, day, hour, minute, seconds] tokens of the provided\n * `date` as it will be rendered in the `timeZone`.\n */\nfunction tzTokenizeDate(date, timeZone) {\n var dtf = getDateTimeFormat(timeZone);\n return dtf.formatToParts ? partsOffset(dtf, date) : hackyOffset(dtf, date);\n}\n\nvar typeToPos = {\n year: 0,\n month: 1,\n day: 2,\n hour: 3,\n minute: 4,\n second: 5\n};\n\nfunction partsOffset(dtf, date) {\n try {\n var formatted = dtf.formatToParts(date);\n var filled = [];\n\n for (var i = 0; i < formatted.length; i++) {\n var pos = typeToPos[formatted[i].type];\n\n if (pos >= 0) {\n filled[pos] = parseInt(formatted[i].value, 10);\n }\n }\n\n return filled;\n } catch (error) {\n if (error instanceof RangeError) {\n return [NaN];\n }\n\n throw error;\n }\n}\n\nfunction hackyOffset(dtf, date) {\n var formatted = dtf.format(date).replace(/\\u200E/g, '');\n var parsed = /(\\d+)\\/(\\d+)\\/(\\d+),? (\\d+):(\\d+):(\\d+)/.exec(formatted); // var [, fMonth, fDay, fYear, fHour, fMinute, fSecond] = parsed\n // return [fYear, fMonth, fDay, fHour, fMinute, fSecond]\n\n return [parsed[3], parsed[1], parsed[2], parsed[4], parsed[5], parsed[6]];\n} // Get a cached Intl.DateTimeFormat instance for the IANA `timeZone`. This can be used\n// to get deterministic local date/time output according to the `en-US` locale which\n// can be used to extract local time parts as necessary.\n\n\nvar dtfCache = {};\n\nfunction getDateTimeFormat(timeZone) {\n if (!dtfCache[timeZone]) {\n // New browsers use `hourCycle`, IE and Chrome <73 does not support it and uses `hour12`\n var testDateFormatted = new Intl.DateTimeFormat('en-US', {\n hour12: false,\n timeZone: 'America/New_York',\n year: 'numeric',\n month: 'numeric',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit'\n }).format(new Date('2014-06-25T04:00:00.123Z'));\n var hourCycleSupported = testDateFormatted === '06/25/2014, 00:00:00' || testDateFormatted === '‎06‎/‎25‎/‎2014‎ ‎00‎:‎00‎:‎00';\n dtfCache[timeZone] = hourCycleSupported ? new Intl.DateTimeFormat('en-US', {\n hour12: false,\n timeZone: timeZone,\n year: 'numeric',\n month: 'numeric',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit'\n }) : new Intl.DateTimeFormat('en-US', {\n hourCycle: 'h23',\n timeZone: timeZone,\n year: 'numeric',\n month: 'numeric',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit'\n });\n }\n\n return dtfCache[timeZone];\n}\n\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = newDateUTC;\n\n/**\n * Use instead of `new Date(Date.UTC(...))` to support years below 100 which doesn't work\n * otherwise due to the nature of the\n * [`Date` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#interpretation_of_two-digit_years.\n *\n * For `Date.UTC(...)`, use `newDateUTC(...).getTime()`.\n */\nfunction newDateUTC(fullYear, month, day, hour, minute, second, millisecond) {\n var utcDate = new Date(0);\n utcDate.setUTCFullYear(fullYear, month, day);\n utcDate.setUTCHours(hour, minute, second, millisecond);\n return utcDate;\n}\n\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = tzParseTimezone;\n\nvar _index = _interopRequireDefault(require(\"../tzTokenizeDate/index.js\"));\n\nvar _index2 = _interopRequireDefault(require(\"../newDateUTC/index.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar MILLISECONDS_IN_HOUR = 3600000;\nvar MILLISECONDS_IN_MINUTE = 60000;\nvar patterns = {\n timezone: /([Z+-].*)$/,\n timezoneZ: /^(Z)$/,\n timezoneHH: /^([+-]\\d{2})$/,\n timezoneHHMM: /^([+-]\\d{2}):?(\\d{2})$/\n}; // Parse various time zone offset formats to an offset in milliseconds\n\nfunction tzParseTimezone(timezoneString, date, isUtcDate) {\n var token;\n var absoluteOffset; // Empty string\n\n if (!timezoneString) {\n return 0;\n } // Z\n\n\n token = patterns.timezoneZ.exec(timezoneString);\n\n if (token) {\n return 0;\n }\n\n var hours; // ±hh\n\n token = patterns.timezoneHH.exec(timezoneString);\n\n if (token) {\n hours = parseInt(token[1], 10);\n\n if (!validateTimezone(hours)) {\n return NaN;\n }\n\n return -(hours * MILLISECONDS_IN_HOUR);\n } // ±hh:mm or ±hhmm\n\n\n token = patterns.timezoneHHMM.exec(timezoneString);\n\n if (token) {\n hours = parseInt(token[1], 10);\n var minutes = parseInt(token[2], 10);\n\n if (!validateTimezone(hours, minutes)) {\n return NaN;\n }\n\n absoluteOffset = Math.abs(hours) * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE;\n return hours > 0 ? -absoluteOffset : absoluteOffset;\n } // IANA time zone\n\n\n if (isValidTimezoneIANAString(timezoneString)) {\n date = new Date(date || Date.now());\n var utcDate = isUtcDate ? date : toUtcDate(date);\n var offset = calcOffset(utcDate, timezoneString);\n var fixedOffset = isUtcDate ? offset : fixOffset(date, offset, timezoneString);\n return -fixedOffset;\n }\n\n return NaN;\n}\n\nfunction toUtcDate(date) {\n return (0, _index2.default)(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());\n}\n\nfunction calcOffset(date, timezoneString) {\n var tokens = (0, _index.default)(date, timezoneString); // ms dropped because it's not provided by tzTokenizeDate\n\n var asUTC = (0, _index2.default)(tokens[0], tokens[1] - 1, tokens[2], tokens[3] % 24, tokens[4], tokens[5], 0).getTime();\n var asTS = date.getTime();\n var over = asTS % 1000;\n asTS -= over >= 0 ? over : 1000 + over;\n return asUTC - asTS;\n}\n\nfunction fixOffset(date, offset, timezoneString) {\n var localTS = date.getTime(); // Our UTC time is just a guess because our offset is just a guess\n\n var utcGuess = localTS - offset; // Test whether the zone matches the offset for this ts\n\n var o2 = calcOffset(new Date(utcGuess), timezoneString); // If so, offset didn't change, and we're done\n\n if (offset === o2) {\n return offset;\n } // If not, change the ts by the difference in the offset\n\n\n utcGuess -= o2 - offset; // If that gives us the local time we want, we're done\n\n var o3 = calcOffset(new Date(utcGuess), timezoneString);\n\n if (o2 === o3) {\n return o2;\n } // If it's different, we're in a hole time. The offset has changed, but we don't adjust the time\n\n\n return Math.max(o2, o3);\n}\n\nfunction validateTimezone(hours, minutes) {\n return -23 <= hours && hours <= 23 && (minutes == null || 0 <= minutes && minutes <= 59);\n}\n\nvar validIANATimezoneCache = {};\n\nfunction isValidTimezoneIANAString(timeZoneString) {\n if (validIANATimezoneCache[timeZoneString]) return true;\n\n try {\n new Intl.DateTimeFormat(undefined, {\n timeZone: timeZoneString\n });\n validIANATimezoneCache[timeZoneString] = true;\n return true;\n } catch (error) {\n return false;\n }\n}\n\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n/** Regex to identify the presence of a time zone specifier in a date string */\nvar tzPattern = /(Z|[+-]\\d{2}(?::?\\d{2})?| UTC| [a-zA-Z]+\\/[a-zA-Z_]+(?:\\/[a-zA-Z_]+)?)$/;\nvar _default = tzPattern;\nexports.default = _default;\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = toDate;\n\nvar _index = _interopRequireDefault(require(\"date-fns/_lib/toInteger/index.js\"));\n\nvar _index2 = _interopRequireDefault(require(\"date-fns/_lib/getTimezoneOffsetInMilliseconds/index.js\"));\n\nvar _index3 = _interopRequireDefault(require(\"../_lib/tzParseTimezone/index.js\"));\n\nvar _index4 = _interopRequireDefault(require(\"../_lib/tzPattern/index.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar MILLISECONDS_IN_HOUR = 3600000;\nvar MILLISECONDS_IN_MINUTE = 60000;\nvar DEFAULT_ADDITIONAL_DIGITS = 2;\nvar patterns = {\n dateTimePattern: /^([0-9W+-]+)(T| )(.*)/,\n datePattern: /^([0-9W+-]+)(.*)/,\n plainTime: /:/,\n // year tokens\n YY: /^(\\d{2})$/,\n YYY: [/^([+-]\\d{2})$/, // 0 additional digits\n /^([+-]\\d{3})$/, // 1 additional digit\n /^([+-]\\d{4})$/ // 2 additional digits\n ],\n YYYY: /^(\\d{4})/,\n YYYYY: [/^([+-]\\d{4})/, // 0 additional digits\n /^([+-]\\d{5})/, // 1 additional digit\n /^([+-]\\d{6})/ // 2 additional digits\n ],\n // date tokens\n MM: /^-(\\d{2})$/,\n DDD: /^-?(\\d{3})$/,\n MMDD: /^-?(\\d{2})-?(\\d{2})$/,\n Www: /^-?W(\\d{2})$/,\n WwwD: /^-?W(\\d{2})-?(\\d{1})$/,\n HH: /^(\\d{2}([.,]\\d*)?)$/,\n HHMM: /^(\\d{2}):?(\\d{2}([.,]\\d*)?)$/,\n HHMMSS: /^(\\d{2}):?(\\d{2}):?(\\d{2}([.,]\\d*)?)$/,\n // time zone tokens (to identify the presence of a tz)\n timeZone: _index4.default\n};\n/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If an argument is a string, the function tries to parse it.\n * Function accepts complete ISO 8601 formats as well as partial implementations.\n * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601\n * If the function cannot parse the string or the values are invalid, it returns Invalid Date.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n * All *date-fns* functions will throw `RangeError` if `options.additionalDigits` is not 0, 1, 2 or undefined.\n *\n * @param {Date|String|Number} argument - the value to convert\n * @param {OptionsWithTZ} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options}\n * @param {0|1|2} [options.additionalDigits=2] - the additional number of digits in the extended year format\n * @param {String} [options.timeZone=''] - used to specify the IANA time zone offset of a date String.\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2\n *\n * @example\n * // Convert string '2014-02-11T11:30:30' to date:\n * var result = toDate('2014-02-11T11:30:30')\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert string '+02014101' to date,\n * // if the additional number of digits in the extended year format is 1:\n * var result = toDate('+02014101', {additionalDigits: 1})\n * //=> Fri Apr 11 2014 00:00:00\n */\n\nfunction toDate(argument, dirtyOptions) {\n if (arguments.length < 1) {\n throw new TypeError('1 argument required, but only ' + arguments.length + ' present');\n }\n\n if (argument === null) {\n return new Date(NaN);\n }\n\n var options = dirtyOptions || {};\n var additionalDigits = options.additionalDigits == null ? DEFAULT_ADDITIONAL_DIGITS : (0, _index.default)(options.additionalDigits);\n\n if (additionalDigits !== 2 && additionalDigits !== 1 && additionalDigits !== 0) {\n throw new RangeError('additionalDigits must be 0, 1 or 2');\n } // Clone the date\n\n\n if (argument instanceof Date || typeof argument === 'object' && Object.prototype.toString.call(argument) === '[object Date]') {\n // Prevent the date to lose the milliseconds when passed to new Date() in IE10\n return new Date(argument.getTime());\n } else if (typeof argument === 'number' || Object.prototype.toString.call(argument) === '[object Number]') {\n return new Date(argument);\n } else if (!(typeof argument === 'string' || Object.prototype.toString.call(argument) === '[object String]')) {\n return new Date(NaN);\n }\n\n var dateStrings = splitDateString(argument);\n var parseYearResult = parseYear(dateStrings.date, additionalDigits);\n var year = parseYearResult.year;\n var restDateString = parseYearResult.restDateString;\n var date = parseDate(restDateString, year);\n\n if (isNaN(date)) {\n return new Date(NaN);\n }\n\n if (date) {\n var timestamp = date.getTime();\n var time = 0;\n var offset;\n\n if (dateStrings.time) {\n time = parseTime(dateStrings.time);\n\n if (isNaN(time)) {\n return new Date(NaN);\n }\n }\n\n if (dateStrings.timeZone || options.timeZone) {\n offset = (0, _index3.default)(dateStrings.timeZone || options.timeZone, new Date(timestamp + time));\n\n if (isNaN(offset)) {\n return new Date(NaN);\n }\n } else {\n // get offset accurate to hour in time zones that change offset\n offset = (0, _index2.default)(new Date(timestamp + time));\n offset = (0, _index2.default)(new Date(timestamp + time + offset));\n }\n\n return new Date(timestamp + time + offset);\n } else {\n return new Date(NaN);\n }\n}\n\nfunction splitDateString(dateString) {\n var dateStrings = {};\n var parts = patterns.dateTimePattern.exec(dateString);\n var timeString;\n\n if (!parts) {\n parts = patterns.datePattern.exec(dateString);\n\n if (parts) {\n dateStrings.date = parts[1];\n timeString = parts[2];\n } else {\n dateStrings.date = null;\n timeString = dateString;\n }\n } else {\n dateStrings.date = parts[1];\n timeString = parts[3];\n }\n\n if (timeString) {\n var token = patterns.timeZone.exec(timeString);\n\n if (token) {\n dateStrings.time = timeString.replace(token[1], '');\n dateStrings.timeZone = token[1].trim();\n } else {\n dateStrings.time = timeString;\n }\n }\n\n return dateStrings;\n}\n\nfunction parseYear(dateString, additionalDigits) {\n var patternYYY = patterns.YYY[additionalDigits];\n var patternYYYYY = patterns.YYYYY[additionalDigits];\n var token; // YYYY or ±YYYYY\n\n token = patterns.YYYY.exec(dateString) || patternYYYYY.exec(dateString);\n\n if (token) {\n var yearString = token[1];\n return {\n year: parseInt(yearString, 10),\n restDateString: dateString.slice(yearString.length)\n };\n } // YY or ±YYY\n\n\n token = patterns.YY.exec(dateString) || patternYYY.exec(dateString);\n\n if (token) {\n var centuryString = token[1];\n return {\n year: parseInt(centuryString, 10) * 100,\n restDateString: dateString.slice(centuryString.length)\n };\n } // Invalid ISO-formatted year\n\n\n return {\n year: null\n };\n}\n\nfunction parseDate(dateString, year) {\n // Invalid ISO-formatted year\n if (year === null) {\n return null;\n }\n\n var token;\n var date;\n var month;\n var week; // YYYY\n\n if (dateString.length === 0) {\n date = new Date(0);\n date.setUTCFullYear(year);\n return date;\n } // YYYY-MM\n\n\n token = patterns.MM.exec(dateString);\n\n if (token) {\n date = new Date(0);\n month = parseInt(token[1], 10) - 1;\n\n if (!validateDate(year, month)) {\n return new Date(NaN);\n }\n\n date.setUTCFullYear(year, month);\n return date;\n } // YYYY-DDD or YYYYDDD\n\n\n token = patterns.DDD.exec(dateString);\n\n if (token) {\n date = new Date(0);\n var dayOfYear = parseInt(token[1], 10);\n\n if (!validateDayOfYearDate(year, dayOfYear)) {\n return new Date(NaN);\n }\n\n date.setUTCFullYear(year, 0, dayOfYear);\n return date;\n } // yyyy-MM-dd or YYYYMMDD\n\n\n token = patterns.MMDD.exec(dateString);\n\n if (token) {\n date = new Date(0);\n month = parseInt(token[1], 10) - 1;\n var day = parseInt(token[2], 10);\n\n if (!validateDate(year, month, day)) {\n return new Date(NaN);\n }\n\n date.setUTCFullYear(year, month, day);\n return date;\n } // YYYY-Www or YYYYWww\n\n\n token = patterns.Www.exec(dateString);\n\n if (token) {\n week = parseInt(token[1], 10) - 1;\n\n if (!validateWeekDate(year, week)) {\n return new Date(NaN);\n }\n\n return dayOfISOWeekYear(year, week);\n } // YYYY-Www-D or YYYYWwwD\n\n\n token = patterns.WwwD.exec(dateString);\n\n if (token) {\n week = parseInt(token[1], 10) - 1;\n var dayOfWeek = parseInt(token[2], 10) - 1;\n\n if (!validateWeekDate(year, week, dayOfWeek)) {\n return new Date(NaN);\n }\n\n return dayOfISOWeekYear(year, week, dayOfWeek);\n } // Invalid ISO-formatted date\n\n\n return null;\n}\n\nfunction parseTime(timeString) {\n var token;\n var hours;\n var minutes; // hh\n\n token = patterns.HH.exec(timeString);\n\n if (token) {\n hours = parseFloat(token[1].replace(',', '.'));\n\n if (!validateTime(hours)) {\n return NaN;\n }\n\n return hours % 24 * MILLISECONDS_IN_HOUR;\n } // hh:mm or hhmm\n\n\n token = patterns.HHMM.exec(timeString);\n\n if (token) {\n hours = parseInt(token[1], 10);\n minutes = parseFloat(token[2].replace(',', '.'));\n\n if (!validateTime(hours, minutes)) {\n return NaN;\n }\n\n return hours % 24 * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE;\n } // hh:mm:ss or hhmmss\n\n\n token = patterns.HHMMSS.exec(timeString);\n\n if (token) {\n hours = parseInt(token[1], 10);\n minutes = parseInt(token[2], 10);\n var seconds = parseFloat(token[3].replace(',', '.'));\n\n if (!validateTime(hours, minutes, seconds)) {\n return NaN;\n }\n\n return hours % 24 * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE + seconds * 1000;\n } // Invalid ISO-formatted time\n\n\n return null;\n}\n\nfunction dayOfISOWeekYear(isoWeekYear, week, day) {\n week = week || 0;\n day = day || 0;\n var date = new Date(0);\n date.setUTCFullYear(isoWeekYear, 0, 4);\n var fourthOfJanuaryDay = date.getUTCDay() || 7;\n var diff = week * 7 + day + 1 - fourthOfJanuaryDay;\n date.setUTCDate(date.getUTCDate() + diff);\n return date;\n} // Validation functions\n\n\nvar DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nvar DAYS_IN_MONTH_LEAP_YEAR = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nfunction isLeapYearIndex(year) {\n return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;\n}\n\nfunction validateDate(year, month, date) {\n if (month < 0 || month > 11) {\n return false;\n }\n\n if (date != null) {\n if (date < 1) {\n return false;\n }\n\n var isLeapYear = isLeapYearIndex(year);\n\n if (isLeapYear && date > DAYS_IN_MONTH_LEAP_YEAR[month]) {\n return false;\n }\n\n if (!isLeapYear && date > DAYS_IN_MONTH[month]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction validateDayOfYearDate(year, dayOfYear) {\n if (dayOfYear < 1) {\n return false;\n }\n\n var isLeapYear = isLeapYearIndex(year);\n\n if (isLeapYear && dayOfYear > 366) {\n return false;\n }\n\n if (!isLeapYear && dayOfYear > 365) {\n return false;\n }\n\n return true;\n}\n\nfunction validateWeekDate(year, week, day) {\n if (week < 0 || week > 52) {\n return false;\n }\n\n if (day != null && (day < 0 || day > 6)) {\n return false;\n }\n\n return true;\n}\n\nfunction validateTime(hours, minutes, seconds) {\n if (hours != null && (hours < 0 || hours >= 25)) {\n return false;\n }\n\n if (minutes != null && (minutes < 0 || minutes >= 60)) {\n return false;\n }\n\n if (seconds != null && (seconds < 0 || seconds >= 60)) {\n return false;\n }\n\n return true;\n}\n\nmodule.exports = exports.default;","export default function requiredArgs(required, args) {\n if (args.length < required) {\n throw new TypeError(required + ' argument' + (required > 1 ? 's' : '') + ' required, but only ' + args.length + ' present');\n }\n}","function _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @param {Date|Number} argument - the value to convert\n * @returns {Date} the parsed date in the local time zone\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\n\nexport default function toDate(argument) {\n requiredArgs(1, arguments);\n var argStr = Object.prototype.toString.call(argument); // Clone the date\n\n if (argument instanceof Date || _typeof(argument) === 'object' && argStr === '[object Date]') {\n // Prevent the date to lose the milliseconds when passed to new Date() in IE10\n return new Date(argument.getTime());\n } else if (typeof argument === 'number' || argStr === '[object Number]') {\n return new Date(argument);\n } else {\n if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') {\n // eslint-disable-next-line no-console\n console.warn(\"Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#string-arguments\"); // eslint-disable-next-line no-console\n\n console.warn(new Error().stack);\n }\n\n return new Date(NaN);\n }\n}","export default function toInteger(dirtyNumber) {\n if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {\n return NaN;\n }\n\n var number = Number(dirtyNumber);\n\n if (isNaN(number)) {\n return number;\n }\n\n return number < 0 ? Math.ceil(number) : Math.floor(number);\n}","var defaultOptions = {};\nexport function getDefaultOptions() {\n return defaultOptions;\n}\nexport function setDefaultOptions(newOptions) {\n defaultOptions = newOptions;\n}","import toDate from \"../toDate/index.js\";\nimport toInteger from \"../_lib/toInteger/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nimport { getDefaultOptions } from \"../_lib/defaultOptions/index.js\";\n/**\n * @name startOfWeek\n * @category Week Helpers\n * @summary Return the start of a week for the given date.\n *\n * @description\n * Return the start of a week for the given date.\n * The result will be in the local timezone.\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Date} the start of a week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // The start of a week for 2 September 2014 11:55:00:\n * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sun Aug 31 2014 00:00:00\n *\n * @example\n * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:\n * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function startOfWeek(dirtyDate, options) {\n var _ref, _ref2, _ref3, _options$weekStartsOn, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2;\n\n requiredArgs(1, arguments);\n var defaultOptions = getDefaultOptions();\n var weekStartsOn = toInteger((_ref = (_ref2 = (_ref3 = (_options$weekStartsOn = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.weekStartsOn) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.weekStartsOn) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.weekStartsOn) !== null && _ref !== void 0 ? _ref : 0); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN\n\n if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {\n throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');\n }\n\n var date = toDate(dirtyDate);\n var day = date.getDay();\n var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n date.setDate(date.getDate() - diff);\n date.setHours(0, 0, 0, 0);\n return date;\n}","/**\n * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.\n * They usually appear for dates that denote time before the timezones were introduced\n * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891\n * and GMT+01:00:00 after that date)\n *\n * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,\n * which would lead to incorrect calculations.\n *\n * This function returns the timezone offset in milliseconds that takes seconds in account.\n */\nexport default function getTimezoneOffsetInMilliseconds(date) {\n var utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));\n utcDate.setUTCFullYear(date.getFullYear());\n return date.getTime() - utcDate.getTime();\n}","import startOfWeek from \"../startOfWeek/index.js\";\nimport getTimezoneOffsetInMilliseconds from \"../_lib/getTimezoneOffsetInMilliseconds/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name differenceInCalendarWeeks\n * @category Week Helpers\n * @summary Get the number of calendar weeks between the given dates.\n *\n * @description\n * Get the number of calendar weeks between the given dates.\n *\n * @param {Date|Number} dateLeft - the later date\n * @param {Date|Number} dateRight - the earlier date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Number} the number of calendar weeks\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // How many calendar weeks are between 5 July 2014 and 20 July 2014?\n * const result = differenceInCalendarWeeks(\n * new Date(2014, 6, 20),\n * new Date(2014, 6, 5)\n * )\n * //=> 3\n *\n * @example\n * // If the week starts on Monday,\n * // how many calendar weeks are between 5 July 2014 and 20 July 2014?\n * const result = differenceInCalendarWeeks(\n * new Date(2014, 6, 20),\n * new Date(2014, 6, 5),\n * { weekStartsOn: 1 }\n * )\n * //=> 2\n */\n\nexport default function differenceInCalendarWeeks(dirtyDateLeft, dirtyDateRight, options) {\n requiredArgs(2, arguments);\n var startOfWeekLeft = startOfWeek(dirtyDateLeft, options);\n var startOfWeekRight = startOfWeek(dirtyDateRight, options);\n var timestampLeft = startOfWeekLeft.getTime() - getTimezoneOffsetInMilliseconds(startOfWeekLeft);\n var timestampRight = startOfWeekRight.getTime() - getTimezoneOffsetInMilliseconds(startOfWeekRight); // Round the number of days to the nearest integer\n // because the number of milliseconds in a week is not constant\n // (e.g. it's different in the week of the daylight saving time clock shift)\n\n return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_WEEK);\n}","import toDate from \"../toDate/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name lastDayOfMonth\n * @category Month Helpers\n * @summary Return the last day of a month for the given date.\n *\n * @description\n * Return the last day of a month for the given date.\n * The result will be in the local timezone.\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the last day of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The last day of a month for 2 September 2014 11:55:00:\n * const result = lastDayOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 00:00:00\n */\n\nexport default function lastDayOfMonth(dirtyDate) {\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n var month = date.getMonth();\n date.setFullYear(date.getFullYear(), month + 1, 0);\n date.setHours(0, 0, 0, 0);\n return date;\n}","import toDate from \"../toDate/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name startOfMonth\n * @category Month Helpers\n * @summary Return the start of a month for the given date.\n *\n * @description\n * Return the start of a month for the given date.\n * The result will be in the local timezone.\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a month\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a month for 2 September 2014 11:55:00:\n * const result = startOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function startOfMonth(dirtyDate) {\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n date.setDate(1);\n date.setHours(0, 0, 0, 0);\n return date;\n}","import differenceInCalendarWeeks from \"../differenceInCalendarWeeks/index.js\";\nimport lastDayOfMonth from \"../lastDayOfMonth/index.js\";\nimport startOfMonth from \"../startOfMonth/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n\n/**\n * @name getWeeksInMonth\n * @category Week Helpers\n * @summary Get the number of calendar weeks a month spans.\n *\n * @description\n * Get the number of calendar weeks the month in the given date spans.\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @returns {Number} the number of calendar weeks\n * @throws {TypeError} 2 arguments required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n *\n * @example\n * // How many calendar weeks does February 2015 span?\n * const result = getWeeksInMonth(new Date(2015, 1, 8))\n * //=> 4\n *\n * @example\n * // If the week starts on Monday,\n * // how many calendar weeks does July 2017 span?\n * const result = getWeeksInMonth(new Date(2017, 6, 5), { weekStartsOn: 1 })\n * //=> 6\n */\nexport default function getWeeksInMonth(date, options) {\n requiredArgs(1, arguments);\n return differenceInCalendarWeeks(lastDayOfMonth(date), startOfMonth(date), options) + 1;\n}","import startOfWeek from \"../startOfWeek/index.js\";\nimport toDate from \"../toDate/index.js\";\nimport toInteger from \"../_lib/toInteger/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nimport { getDefaultOptions } from \"../_lib/defaultOptions/index.js\";\n/**\n * @name getWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Get the local week-numbering year of the given date.\n *\n * @description\n * Get the local week-numbering year of the given date.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Number} the local week-numbering year\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Which week numbering year is 26 December 2004 with the default settings?\n * const result = getWeekYear(new Date(2004, 11, 26))\n * //=> 2005\n *\n * @example\n * // Which week numbering year is 26 December 2004 if week starts on Saturday?\n * const result = getWeekYear(new Date(2004, 11, 26), { weekStartsOn: 6 })\n * //=> 2004\n *\n * @example\n * // Which week numbering year is 26 December 2004 if the first week contains 4 January?\n * const result = getWeekYear(new Date(2004, 11, 26), { firstWeekContainsDate: 4 })\n * //=> 2004\n */\n\nexport default function getWeekYear(dirtyDate, options) {\n var _ref, _ref2, _ref3, _options$firstWeekCon, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2;\n\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n var year = date.getFullYear();\n var defaultOptions = getDefaultOptions();\n var firstWeekContainsDate = toInteger((_ref = (_ref2 = (_ref3 = (_options$firstWeekCon = options === null || options === void 0 ? void 0 : options.firstWeekContainsDate) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.firstWeekContainsDate) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref !== void 0 ? _ref : 1); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN\n\n if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {\n throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');\n }\n\n var firstWeekOfNextYear = new Date(0);\n firstWeekOfNextYear.setFullYear(year + 1, 0, firstWeekContainsDate);\n firstWeekOfNextYear.setHours(0, 0, 0, 0);\n var startOfNextYear = startOfWeek(firstWeekOfNextYear, options);\n var firstWeekOfThisYear = new Date(0);\n firstWeekOfThisYear.setFullYear(year, 0, firstWeekContainsDate);\n firstWeekOfThisYear.setHours(0, 0, 0, 0);\n var startOfThisYear = startOfWeek(firstWeekOfThisYear, options);\n\n if (date.getTime() >= startOfNextYear.getTime()) {\n return year + 1;\n } else if (date.getTime() >= startOfThisYear.getTime()) {\n return year;\n } else {\n return year - 1;\n }\n}","import getWeekYear from \"../getWeekYear/index.js\";\nimport startOfWeek from \"../startOfWeek/index.js\";\nimport toInteger from \"../_lib/toInteger/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nimport { getDefaultOptions } from \"../_lib/defaultOptions/index.js\";\n/**\n * @name startOfWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Return the start of a local week-numbering year for the given date.\n *\n * @description\n * Return the start of a local week-numbering year.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * @param {Date|Number} date - the original date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Date} the start of a week-numbering year\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // The start of an a week-numbering year for 2 July 2005 with default settings:\n * const result = startOfWeekYear(new Date(2005, 6, 2))\n * //=> Sun Dec 26 2004 00:00:00\n *\n * @example\n * // The start of a week-numbering year for 2 July 2005\n * // if Monday is the first day of week\n * // and 4 January is always in the first week of the year:\n * const result = startOfWeekYear(new Date(2005, 6, 2), {\n * weekStartsOn: 1,\n * firstWeekContainsDate: 4\n * })\n * //=> Mon Jan 03 2005 00:00:00\n */\n\nexport default function startOfWeekYear(dirtyDate, options) {\n var _ref, _ref2, _ref3, _options$firstWeekCon, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2;\n\n requiredArgs(1, arguments);\n var defaultOptions = getDefaultOptions();\n var firstWeekContainsDate = toInteger((_ref = (_ref2 = (_ref3 = (_options$firstWeekCon = options === null || options === void 0 ? void 0 : options.firstWeekContainsDate) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.firstWeekContainsDate) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref !== void 0 ? _ref : 1);\n var year = getWeekYear(dirtyDate, options);\n var firstWeek = new Date(0);\n firstWeek.setFullYear(year, 0, firstWeekContainsDate);\n firstWeek.setHours(0, 0, 0, 0);\n var date = startOfWeek(firstWeek, options);\n return date;\n}","import startOfWeek from \"../startOfWeek/index.js\";\nimport startOfWeekYear from \"../startOfWeekYear/index.js\";\nimport toDate from \"../toDate/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name getWeek\n * @category Week Helpers\n * @summary Get the local week index of the given date.\n *\n * @description\n * Get the local week index of the given date.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering\n *\n * @param {Date|Number} date - the given date\n * @param {Object} [options] - an object with options.\n * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}\n * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)\n * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year\n * @returns {Number} the week\n * @throws {TypeError} 1 argument required\n * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6\n * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7\n *\n * @example\n * // Which week of the local week numbering year is 2 January 2005 with default options?\n * const result = getWeek(new Date(2005, 0, 2))\n * //=> 2\n *\n * // Which week of the local week numbering year is 2 January 2005,\n * // if Monday is the first day of the week,\n * // and the first week of the year always contains 4 January?\n * const result = getWeek(new Date(2005, 0, 2), {\n * weekStartsOn: 1,\n * firstWeekContainsDate: 4\n * })\n * //=> 53\n */\n\nexport default function getWeek(dirtyDate, options) {\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n var diff = startOfWeek(date, options).getTime() - startOfWeekYear(date, options).getTime(); // Round the number of days to the nearest integer\n // because the number of milliseconds in a week is not constant\n // (e.g. it's different in the week of the daylight saving time clock shift)\n\n return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import startOfWeek from \"../startOfWeek/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name startOfISOWeek\n * @category ISO Week Helpers\n * @summary Return the start of an ISO week for the given date.\n *\n * @description\n * Return the start of an ISO week for the given date.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of an ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of an ISO week for 2 September 2014 11:55:00:\n * const result = startOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Mon Sep 01 2014 00:00:00\n */\n\nexport default function startOfISOWeek(dirtyDate) {\n requiredArgs(1, arguments);\n return startOfWeek(dirtyDate, {\n weekStartsOn: 1\n });\n}","import toDate from \"../toDate/index.js\";\nimport startOfISOWeek from \"../startOfISOWeek/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name getISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the ISO week-numbering year of the given date.\n *\n * @description\n * Get the ISO week-numbering year of the given date,\n * which always starts 3 days before the year's first Thursday.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which ISO-week numbering year is 2 January 2005?\n * const result = getISOWeekYear(new Date(2005, 0, 2))\n * //=> 2004\n */\n\nexport default function getISOWeekYear(dirtyDate) {\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n var year = date.getFullYear();\n var fourthOfJanuaryOfNextYear = new Date(0);\n fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4);\n fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0);\n var startOfNextYear = startOfISOWeek(fourthOfJanuaryOfNextYear);\n var fourthOfJanuaryOfThisYear = new Date(0);\n fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4);\n fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0);\n var startOfThisYear = startOfISOWeek(fourthOfJanuaryOfThisYear);\n\n if (date.getTime() >= startOfNextYear.getTime()) {\n return year + 1;\n } else if (date.getTime() >= startOfThisYear.getTime()) {\n return year;\n } else {\n return year - 1;\n }\n}","import getISOWeekYear from \"../getISOWeekYear/index.js\";\nimport startOfISOWeek from \"../startOfISOWeek/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name startOfISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Return the start of an ISO week-numbering year for the given date.\n *\n * @description\n * Return the start of an ISO week-numbering year,\n * which always starts 3 days before the year's first Thursday.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of an ISO week-numbering year\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of an ISO week-numbering year for 2 July 2005:\n * const result = startOfISOWeekYear(new Date(2005, 6, 2))\n * //=> Mon Jan 03 2005 00:00:00\n */\n\nexport default function startOfISOWeekYear(dirtyDate) {\n requiredArgs(1, arguments);\n var year = getISOWeekYear(dirtyDate);\n var fourthOfJanuary = new Date(0);\n fourthOfJanuary.setFullYear(year, 0, 4);\n fourthOfJanuary.setHours(0, 0, 0, 0);\n var date = startOfISOWeek(fourthOfJanuary);\n return date;\n}","import toDate from \"../toDate/index.js\";\nimport startOfISOWeek from \"../startOfISOWeek/index.js\";\nimport startOfISOWeekYear from \"../startOfISOWeekYear/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\nvar MILLISECONDS_IN_WEEK = 604800000;\n/**\n * @name getISOWeek\n * @category ISO Week Helpers\n * @summary Get the ISO week of the given date.\n *\n * @description\n * Get the ISO week of the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * @param {Date|Number} date - the given date\n * @returns {Number} the ISO week\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Which week of the ISO-week numbering year is 2 January 2005?\n * const result = getISOWeek(new Date(2005, 0, 2))\n * //=> 53\n */\n\nexport default function getISOWeek(dirtyDate) {\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n var diff = startOfISOWeek(date).getTime() - startOfISOWeekYear(date).getTime(); // Round the number of days to the nearest integer\n // because the number of milliseconds in a week is not constant\n // (e.g. it's different in the week of the daylight saving time clock shift)\n\n return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport toDate from \"../toDate/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name addDays\n * @category Day Helpers\n * @summary Add the specified number of days to the given date.\n *\n * @description\n * Add the specified number of days to the given date.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of days to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} - the new date with the days added\n * @throws {TypeError} - 2 arguments required\n *\n * @example\n * // Add 10 days to 1 September 2014:\n * const result = addDays(new Date(2014, 8, 1), 10)\n * //=> Thu Sep 11 2014 00:00:00\n */\n\nexport default function addDays(dirtyDate, dirtyAmount) {\n requiredArgs(2, arguments);\n var date = toDate(dirtyDate);\n var amount = toInteger(dirtyAmount);\n\n if (isNaN(amount)) {\n return new Date(NaN);\n }\n\n if (!amount) {\n // If 0 days, no-op to avoid changing times in the hour before end of DST\n return date;\n }\n\n date.setDate(date.getDate() + amount);\n return date;\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport toDate from \"../toDate/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name addMonths\n * @category Month Helpers\n * @summary Add the specified number of months to the given date.\n *\n * @description\n * Add the specified number of months to the given date.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of months to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the months added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 5 months to 1 September 2014:\n * const result = addMonths(new Date(2014, 8, 1), 5)\n * //=> Sun Feb 01 2015 00:00:00\n */\n\nexport default function addMonths(dirtyDate, dirtyAmount) {\n requiredArgs(2, arguments);\n var date = toDate(dirtyDate);\n var amount = toInteger(dirtyAmount);\n\n if (isNaN(amount)) {\n return new Date(NaN);\n }\n\n if (!amount) {\n // If 0 months, no-op to avoid changing times in the hour before end of DST\n return date;\n }\n\n var dayOfMonth = date.getDate(); // The JS Date object supports date math by accepting out-of-bounds values for\n // month, day, etc. For example, new Date(2020, 0, 0) returns 31 Dec 2019 and\n // new Date(2020, 13, 1) returns 1 Feb 2021. This is *almost* the behavior we\n // want except that dates will wrap around the end of a month, meaning that\n // new Date(2020, 13, 31) will return 3 Mar 2021 not 28 Feb 2021 as desired. So\n // we'll default to the end of the desired month by adding 1 to the desired\n // month and using a date of 0 to back up one day to the end of the desired\n // month.\n\n var endOfDesiredMonth = new Date(date.getTime());\n endOfDesiredMonth.setMonth(date.getMonth() + amount + 1, 0);\n var daysInMonth = endOfDesiredMonth.getDate();\n\n if (dayOfMonth >= daysInMonth) {\n // If we're already at the end of the month, then this is the correct date\n // and we're done.\n return endOfDesiredMonth;\n } else {\n // Otherwise, we now know that setting the original day-of-month value won't\n // cause an overflow, so set the desired day-of-month. Note that we can't\n // just set the date of `endOfDesiredMonth` because that object may have had\n // its time changed in the unusual case where where a DST transition was on\n // the last day of the month and its local time was in the hour skipped or\n // repeated next to a DST transition. So we use `date` instead which is\n // guaranteed to still have the original time.\n date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);\n return date;\n }\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport addMonths from \"../addMonths/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name addYears\n * @category Year Helpers\n * @summary Add the specified number of years to the given date.\n *\n * @description\n * Add the specified number of years to the given date.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of years to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the years added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 5 years to 1 September 2014:\n * const result = addYears(new Date(2014, 8, 1), 5)\n * //=> Sun Sep 01 2019 00:00:00\n */\n\nexport default function addYears(dirtyDate, dirtyAmount) {\n requiredArgs(2, arguments);\n var amount = toInteger(dirtyAmount);\n return addMonths(dirtyDate, amount * 12);\n}","import {\n type DayOfWeek,\n type OrdinalWeekInMonth,\n type DayParts,\n diffInDays,\n diffInWeeks,\n diffInMonths,\n diffInYears,\n isDayInMonth,\n isDayOfWeek,\n isWeekInMonth,\n isMonthInYear,\n isOrdinalWeekInMonth,\n} from './helpers';\nimport { isArray, isNumber, isFunction } from '../helpers';\n\nexport type SingleOrArray = T | T[];\n\nexport enum GroupRuleType {\n Any = 'any',\n All = 'all',\n}\n\nexport enum IntervalRuleType {\n Days = 'days',\n Weeks = 'weeks',\n Months = 'months',\n Years = 'years',\n}\n\nexport enum ComponentRuleType {\n Days = 'days',\n Weekdays = 'weekdays',\n Weeks = 'weeks',\n Months = 'months',\n Years = 'years',\n}\n\nexport enum OrdinalComponentRuleType {\n OrdinalWeekdays = 'ordinalWeekdays',\n}\n\nexport enum FunctionRuleType {\n Function = 'function',\n}\n\nexport type RuleType =\n | GroupRuleType\n | IntervalRuleType\n | ComponentRuleType\n | OrdinalComponentRuleType\n | FunctionRuleType;\n\nexport type OrdinalArrayConfig = SingleOrArray<\n [OrdinalWeekInMonth, ...DayOfWeek[]]\n>;\n\nexport interface Rule {\n type: T;\n passes(dayParts: DayParts): boolean;\n}\n\nexport class IntervalRule implements Rule {\n private validated = true;\n\n constructor(\n public type: IntervalRuleType,\n public interval: number,\n public from: DayParts,\n ) {\n // Start date needed for interval rules\n if (!this.from) {\n console.error(\n `A valid \"from\" date is required for date interval rule. This rule will be skipped.`,\n );\n this.validated = false;\n }\n }\n\n passes(dateParts: DayParts) {\n if (!this.validated) return true;\n\n const { date } = dateParts;\n switch (this.type) {\n case 'days': {\n return diffInDays(this.from.date, date) % this.interval === 0;\n }\n case 'weeks': {\n return diffInWeeks(this.from.date, date) % this.interval === 0;\n }\n case 'months': {\n return diffInMonths(this.from.date, date) % this.interval === 0;\n }\n case 'years': {\n return diffInYears(this.from.date, date) % this.interval === 0;\n }\n default: {\n return false;\n }\n }\n }\n}\n\nexport class ComponentRule implements Rule {\n components: number[] = [];\n\n static create(type: ComponentRuleType, config: unknown) {\n switch (type) {\n case ComponentRuleType.Days:\n return new DaysRule(config);\n case ComponentRuleType.Weekdays:\n return new WeekdaysRule(config);\n case ComponentRuleType.Weeks:\n return new WeeksRule(config);\n case ComponentRuleType.Months:\n return new MonthsRule(config);\n case ComponentRuleType.Years:\n return new YearsRule(config);\n }\n }\n\n constructor(\n public type: ComponentRuleType,\n components: unknown,\n public validator: (component: unknown) => component is number,\n public getter: (dayParts: DayParts) => number[],\n ) {\n this.components = this.normalizeComponents(components);\n }\n\n normalizeComponents(components: unknown) {\n if (this.validator(components)) return [components];\n if (!isArray(components)) return [];\n const result: number[] = [];\n components.forEach(component => {\n if (!this.validator(component)) {\n console.error(\n `Component value ${component} in invalid for \"${this.type}\" rule. This rule will be skipped.`,\n );\n return;\n }\n result.push(component);\n });\n return result;\n }\n\n passes(dayParts: DayParts) {\n const comps = this.getter(dayParts);\n const result = comps.some(comp => this.components.includes(comp));\n return result;\n }\n}\n\nexport class DaysRule extends ComponentRule {\n constructor(components: unknown) {\n super(\n ComponentRuleType.Days,\n components,\n isDayInMonth,\n ({ day, dayFromEnd }) => [day, -dayFromEnd],\n );\n }\n}\n\nexport class WeekdaysRule extends ComponentRule {\n constructor(components: unknown) {\n super(\n ComponentRuleType.Weekdays,\n components,\n isDayOfWeek,\n ({ weekday }) => [weekday],\n );\n }\n}\n\nexport class WeeksRule extends ComponentRule {\n constructor(components: unknown) {\n super(\n ComponentRuleType.Weeks,\n components,\n isWeekInMonth,\n ({ week, weekFromEnd }) => [week, -weekFromEnd],\n );\n }\n}\n\nexport class MonthsRule extends ComponentRule {\n constructor(components: unknown) {\n super(ComponentRuleType.Months, components, isMonthInYear, ({ month }) => [\n month,\n ]);\n }\n}\n\nexport class YearsRule extends ComponentRule {\n constructor(components: unknown) {\n super(ComponentRuleType.Years, components, isNumber, ({ year }) => [year]);\n }\n}\n\nexport class OrdinalComponentRule implements Rule {\n components: [OrdinalWeekInMonth, DayOfWeek][];\n\n constructor(\n public type: OrdinalComponentRuleType,\n components: OrdinalArrayConfig,\n ) {\n this.components = this.normalizeComponents(components);\n }\n\n normalizeArrayConfig(config: OrdinalArrayConfig) {\n const result: [OrdinalWeekInMonth, DayOfWeek][] = [];\n config.forEach((numOrArray, i) => {\n if (isNumber(numOrArray)) {\n if (i === 0) return;\n if (!isOrdinalWeekInMonth(config[0])) {\n console.error(\n `Ordinal range for \"${this.type}\" rule is from -5 to -1 or 1 to 5. This rule will be skipped.`,\n );\n return;\n }\n if (!isDayOfWeek(numOrArray)) {\n console.error(\n `Acceptable range for \"${this.type}\" rule is from 1 to 5. This rule will be skipped`,\n );\n return;\n }\n result.push([config[0], numOrArray]);\n } else if (isArray(numOrArray)) {\n result.push(...this.normalizeArrayConfig(numOrArray));\n }\n });\n return result;\n }\n\n normalizeComponents(config: OrdinalArrayConfig) {\n const result: [OrdinalWeekInMonth, DayOfWeek][] = [];\n config.forEach((numOrArray, i) => {\n if (isNumber(numOrArray)) {\n if (i === 0) return;\n if (!isOrdinalWeekInMonth(config[0])) {\n console.error(\n `Ordinal range for \"${this.type}\" rule is from -5 to -1 or 1 to 5. This rule will be skipped.`,\n );\n return;\n }\n if (!isDayOfWeek(numOrArray)) {\n console.error(\n `Acceptable range for \"${this.type}\" rule is from 1 to 5. This rule will be skipped`,\n );\n return;\n }\n result.push([config[0], numOrArray]);\n } else if (isArray(numOrArray)) {\n result.push(...this.normalizeArrayConfig(numOrArray));\n }\n });\n return result;\n }\n\n passes(dayParts: DayParts) {\n const { weekday, weekdayOrdinal, weekdayOrdinalFromEnd } = dayParts;\n return this.components.some(\n ([ordinalWeek, ordinalWeekday]) =>\n (ordinalWeek === weekdayOrdinal ||\n ordinalWeek === -weekdayOrdinalFromEnd) &&\n weekday === ordinalWeekday,\n );\n }\n}\n\nexport class FunctionRule implements Rule {\n type = FunctionRuleType.Function;\n private validated = true;\n\n constructor(public fn: Function) {\n if (!isFunction(fn)) {\n console.error(\n `The function rule requires a valid function. This rule will be skipped.`,\n );\n this.validated = false;\n }\n }\n\n passes(dayParts: DayParts) {\n if (!this.validated) return true;\n\n return this.fn(dayParts);\n }\n}\n","import { isArray, isObject, isString, isFunction } from '../helpers';\nimport Locale from '../locale';\nimport type {\n DayOfWeek,\n DayInMonth,\n WeekInMonth,\n MonthInYear,\n DayParts,\n DateParts,\n} from './helpers';\nimport {\n type Rule,\n type RuleType,\n type SingleOrArray,\n ComponentRule,\n ComponentRuleType,\n FunctionRule,\n GroupRuleType,\n IntervalRule,\n IntervalRuleType,\n OrdinalComponentRuleType,\n OrdinalComponentRule,\n} from './rules';\n\nexport type RepeatIntervalShort = 'day' | 'week' | 'month' | 'year';\n\nexport type RepeatInterval = 'days' | 'weeks' | 'months' | 'years';\nexport interface DateRepeatConfig {\n every: RepeatIntervalShort | [number, RepeatInterval];\n from: Date;\n until: Date;\n weekdays: SingleOrArray;\n days: SingleOrArray;\n weeks: SingleOrArray;\n months: SingleOrArray;\n years: SingleOrArray;\n ordinalWeekdays: SingleOrArray;\n on: SingleOrArray>;\n}\n\nexport type DateRepeatFn = (dayParts: DayParts) => boolean;\n\nexport interface DateRepeatOptions {\n locale: Locale;\n}\n\nexport class DateRepeat implements Rule {\n validated = true;\n\n config: Partial | DateRepeatFn;\n type = GroupRuleType.Any;\n from: DateParts | undefined;\n until: DateParts | undefined;\n rules: Rule[] = [];\n locale = new Locale();\n\n constructor(\n config: Partial | DateRepeatFn,\n options: Partial = {},\n private parent?: DateRepeat,\n ) {\n if (options.locale) this.locale = options.locale;\n\n this.config = config;\n if (isFunction(config)) {\n this.type = GroupRuleType.All;\n this.rules = [new FunctionRule(config)];\n } else if (isArray(config)) {\n this.type = GroupRuleType.Any;\n this.rules = config.map(c => new DateRepeat(c, options, this));\n } else if (isObject(config)) {\n this.type = GroupRuleType.All;\n // Assign bounding dates\n this.from = config.from\n ? this.locale.getDateParts(config.from)\n : parent?.from;\n this.until = config.until\n ? this.locale.getDateParts(config.until)\n : parent?.until;\n this.rules = this.getObjectRules(config);\n } else {\n console.error('Rule group configuration must be an object or an array.');\n this.validated = false;\n }\n }\n\n getObjectRules(config: any) {\n const rules: Rule[] = [];\n\n // Add interval rule\n if (config.every) {\n if (isString(config.every)) {\n config.every = [1, `${config.every}s`];\n }\n if (isArray(config.every)) {\n const [interval = 1, type = IntervalRuleType.Days] = config.every;\n rules.push(new IntervalRule(type, interval, this.from!));\n }\n }\n\n // Add component rules\n Object.values(ComponentRuleType).forEach(type => {\n if (!(type in config)) return;\n rules.push(ComponentRule.create(type, config[type]));\n });\n\n // Add ordinal component rules\n Object.values(OrdinalComponentRuleType).forEach(type => {\n if (!(type in config)) return;\n rules.push(new OrdinalComponentRule(type, config[type]));\n });\n\n // Add group rules\n if (config.on != null) {\n if (!isArray(config.on)) config.on = [config.on];\n rules.push(\n new DateRepeat(config.on, { locale: this.locale }, this.parent),\n );\n }\n\n return rules;\n }\n\n passes(dayParts: DayParts) {\n if (!this.validated) return true;\n\n if (this.from && dayParts.dayIndex <= this.from.dayIndex) return false;\n if (this.until && dayParts.dayIndex >= this.until.dayIndex) return false;\n\n if (this.type === GroupRuleType.Any) {\n return this.rules.some(r => r.passes(dayParts));\n }\n return this.rules.every(r => r.passes(dayParts));\n }\n}\n","import {\n pad,\n isNumber,\n isString,\n isDate,\n isArray,\n arrayHasItems,\n isFunction,\n isObject,\n} from '../helpers';\nimport toFnsDate from 'date-fns-tz/toDate';\nimport getWeeksInMonth from 'date-fns/getWeeksInMonth';\nimport getWeek from 'date-fns/getWeek';\nimport getISOWeek from 'date-fns/getISOWeek';\nimport addDays from 'date-fns/addDays';\nimport addMonths from 'date-fns/addMonths';\nimport addYears from 'date-fns/addYears';\nimport { type LocaleConfig, default as Locale } from '../locale';\n\nexport { addDays, addMonths, addYears };\nexport { DateRepeat } from './repeat';\n\n// #region Types\n\ntype DayNameLength = 'narrow' | 'short' | 'long';\ntype MonthNameLength = 'short' | 'long';\n\nexport type DayInMonth =\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n | 18\n | 18\n | 20\n | 21\n | 22\n | 23\n | 24\n | 25\n | 26\n | 27\n | 28\n | 29\n | 30\n | 31\n | -1\n | -2\n | -3\n | -4\n | -5\n | -6\n | -7\n | -8\n | -9\n | -10\n | -11\n | -12\n | -13\n | -14\n | -15\n | -16\n | -17\n | -18\n | -18\n | -20\n | -21\n | -22\n | -23\n | -24\n | -25\n | -26\n | -27\n | -28\n | -29\n | -30\n | -31;\nexport type DayOfWeek = 1 | 2 | 3 | 4 | 5 | 6 | 7;\nexport type WeekInMonth = 1 | 2 | 3 | 4 | 5 | 6;\nexport type WeekInMonthFromEnd = -6 | -5 | -4 | -3 | -2 | -1;\nexport type OrdinalWeekInMonth = -5 | -4 | -3 | -2 | -1 | 1 | 2 | 3 | 4 | 5;\nexport type MonthInYear = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;\nexport type StartOfWeek = 1 | 2 | 3 | 4 | 5 | 6 | 7;\n\nexport type WeekStartsOn = 0 | 1 | 2 | 3 | 4 | 5 | 6;\nexport type DateSource = Date | string | number;\nexport type TimeNames = Partial>;\n\n// #endregion Types\n\nexport function isDayInMonth(dayInMonth: unknown): dayInMonth is DayInMonth {\n if (!isNumber(dayInMonth)) return false;\n return dayInMonth >= 1 && dayInMonth <= 31;\n}\n\nexport function isDayOfWeek(dayOfWeek: unknown): dayOfWeek is DayOfWeek {\n if (!isNumber(dayOfWeek)) return false;\n return dayOfWeek >= 1 && dayOfWeek <= 7;\n}\n\nexport function isWeekInMonth(\n weekInMonth: unknown,\n): weekInMonth is WeekInMonth {\n if (!isNumber(weekInMonth)) return false;\n return (\n (weekInMonth >= -6 && weekInMonth <= -1) ||\n (weekInMonth >= 1 && weekInMonth <= 6)\n );\n}\n\nexport function isMonthInYear(\n monthInYear: unknown,\n): monthInYear is MonthInYear {\n if (!isNumber(monthInYear)) return false;\n return monthInYear >= 1 && monthInYear <= 12;\n}\n\nexport function isOrdinalWeekInMonth(\n weekInMonth: unknown,\n): weekInMonth is OrdinalWeekInMonth {\n if (!isNumber(weekInMonth)) return false;\n if (weekInMonth < -5 || weekInMonth > 5 || weekInMonth === 0) return false;\n return true;\n}\n\ninterface NumberRuleConfig {\n min?: number;\n max?: number;\n interval?: number;\n}\n\ntype DatePartsRuleFunction = (part: number, parts: TimeParts) => boolean;\n\ntype DatePartsRule =\n | number\n | Array\n | NumberRuleConfig\n | DatePartsRuleFunction;\n\nexport interface DatePartsRules {\n hours?: DatePartsRule;\n minutes?: DatePartsRule;\n seconds?: DatePartsRule;\n milliseconds?: DatePartsRule;\n}\n\nexport interface DatePartOption {\n value: number;\n label: string;\n disabled?: boolean;\n}\n\nexport interface FormatParseOptions {\n locale?: Locale | LocaleConfig | string;\n timezone?: string;\n}\n\nexport interface DateOptions {\n type: string;\n fillDate: DateSource;\n mask: string;\n patch: DatePatch;\n rules: DatePartsRules;\n}\n\nexport interface PageAddress {\n day?: number;\n week?: number;\n month: number;\n year: number;\n}\n\nexport interface TimeParts {\n hours: number;\n minutes: number;\n seconds: number;\n milliseconds: number;\n}\n\nexport interface SimpleDateParts {\n year: number;\n month: number;\n day: number;\n hours: number;\n minutes: number;\n seconds: number;\n milliseconds: number;\n}\n\nexport interface DayParts {\n dayIndex: number;\n day: number;\n dayFromEnd: number;\n weekday: number;\n weekdayOrdinal: number;\n weekdayOrdinalFromEnd: number;\n week: number;\n weekFromEnd: number;\n weeknumber: number;\n month: number;\n year: number;\n date: Date;\n}\n\nexport interface DateParts extends DayParts {\n milliseconds: number;\n seconds: number;\n minutes: number;\n hours: number;\n time: number;\n dateTime: number;\n isValid: boolean;\n timezoneOffset: number;\n isPm?: boolean;\n}\n\nexport interface MonthParts {\n firstDayOfWeek: DayOfWeek;\n firstDayOfMonth: Date;\n inLeapYear: boolean;\n firstWeekday: number;\n numDays: number;\n numWeeks: number;\n month: number;\n year: number;\n weeknumbers: number[];\n isoWeeknumbers: number[];\n}\n\nexport type DatePatch = 'dateTime' | 'date' | 'time';\n\nexport const DatePatchKeys: Record = {\n dateTime: [\n 'year',\n 'month',\n 'day',\n 'hours',\n 'minutes',\n 'seconds',\n 'milliseconds',\n ],\n date: ['year', 'month', 'day'],\n time: ['hours', 'minutes', 'seconds', 'milliseconds'],\n};\n\nexport const daysInWeek = 7;\nexport const weeksInMonth = 6;\nexport const MS_PER_SECOND = 1000;\nexport const MS_PER_MINUTE = MS_PER_SECOND * 60;\nexport const MS_PER_HOUR = MS_PER_MINUTE * 60;\nexport const MS_PER_DAY = MS_PER_HOUR * 24;\n\nconst daysInMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nconst maskMacros = ['L', 'iso'];\n\ntype DatePartsRange = Readonly<[number, number, number]>;\ntype TimePartsKey = 'milliseconds' | 'seconds' | 'minutes' | 'hours';\nconst DATE_PART_RANGES: Record = {\n milliseconds: [0, 999, 3],\n seconds: [0, 59, 2],\n minutes: [0, 59, 2],\n hours: [0, 23, 2],\n} as const;\n\n// #region Format constants\n\nconst token =\n /d{1,2}|W{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|Z{1,4}|([HhMsDm])\\1?|[aA]|\"[^\"]*\"|'[^']*'/g;\nconst literal = /\\[([^]*?)\\]/gm;\nconst formatFlags: any = {\n D(d: DateParts) {\n return d.day;\n },\n DD(d: DateParts) {\n return pad(d.day, 2);\n },\n // Do(d: DateParts, l: Locale) {\n // return l.DoFn(d.day);\n // },\n d(d: DateParts) {\n return d.weekday - 1;\n },\n dd(d: DateParts) {\n return pad(d.weekday - 1, 2);\n },\n W(d: DateParts, l: Locale) {\n return l.dayNamesNarrow[d.weekday - 1];\n },\n WW(d: DateParts, l: Locale) {\n return l.dayNamesShorter[d.weekday - 1];\n },\n WWW(d: DateParts, l: Locale) {\n return l.dayNamesShort[d.weekday - 1];\n },\n WWWW(d: DateParts, l: Locale) {\n return l.dayNames[d.weekday - 1];\n },\n M(d: DateParts) {\n return d.month;\n },\n MM(d: DateParts) {\n return pad(d.month, 2);\n },\n MMM(d: DateParts, l: Locale) {\n return l.monthNamesShort[d.month - 1];\n },\n MMMM(d: DateParts, l: Locale) {\n return l.monthNames[d.month - 1];\n },\n YY(d: DateParts) {\n return String(d.year).substr(2);\n },\n YYYY(d: DateParts) {\n return pad(d.year, 4);\n },\n h(d: DateParts) {\n return d.hours % 12 || 12;\n },\n hh(d: DateParts) {\n return pad(d.hours % 12 || 12, 2);\n },\n H(d: DateParts) {\n return d.hours;\n },\n HH(d: DateParts) {\n return pad(d.hours, 2);\n },\n m(d: DateParts) {\n return d.minutes;\n },\n mm(d: DateParts) {\n return pad(d.minutes, 2);\n },\n s(d: DateParts) {\n return d.seconds;\n },\n ss(d: DateParts) {\n return pad(d.seconds, 2);\n },\n S(d: DateParts) {\n return Math.round(d.milliseconds / 100);\n },\n SS(d: DateParts) {\n return pad(Math.round(d.milliseconds / 10), 2);\n },\n SSS(d: DateParts) {\n return pad(d.milliseconds, 3);\n },\n a(d: DateParts, l: Locale) {\n return d.hours < 12 ? l.amPm[0] : l.amPm[1];\n },\n A(d: DateParts, l: Locale) {\n return d.hours < 12 ? l.amPm[0].toUpperCase() : l.amPm[1].toUpperCase();\n },\n Z() {\n return 'Z';\n },\n ZZ(d: DateParts) {\n const o = d.timezoneOffset;\n return `${o > 0 ? '-' : '+'}${pad(Math.floor(Math.abs(o) / 60), 2)}`;\n },\n ZZZ(d: DateParts) {\n const o = d.timezoneOffset;\n return `${o > 0 ? '-' : '+'}${pad(\n Math.floor(Math.abs(o) / 60) * 100 + (Math.abs(o) % 60),\n 4,\n )}`;\n },\n ZZZZ(d: DateParts) {\n const o = d.timezoneOffset;\n return `${o > 0 ? '-' : '+'}${pad(Math.floor(Math.abs(o) / 60), 2)}:${pad(\n Math.abs(o) % 60,\n 2,\n )}`;\n },\n};\n\n// #endregion Format constants\n\n// #region Parse constants\n\nconst twoDigits = /\\d\\d?/;\nconst threeDigits = /\\d{3}/;\nconst fourDigits = /\\d{4}/;\nconst word =\n /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nconst noop = () => {};\nconst monthUpdate = (arrName: string) => (d: DateParts, v: string, l: any) => {\n const index = l[arrName].indexOf(\n v.charAt(0).toUpperCase() + v.substr(1).toLowerCase(),\n );\n if (~index) {\n d.month = index;\n }\n};\nconst parseFlags: any = {\n D: [\n twoDigits,\n (d: DateParts, v: number) => {\n d.day = v;\n },\n ],\n Do: [\n new RegExp(twoDigits.source + word.source),\n (d: DateParts, v: string) => {\n d.day = parseInt(v, 10);\n },\n ],\n d: [twoDigits, noop],\n W: [word, noop],\n M: [\n twoDigits,\n (d: DateParts, v: number) => {\n d.month = v - 1;\n },\n ],\n MMM: [word, monthUpdate('monthNamesShort')],\n MMMM: [word, monthUpdate('monthNames')],\n YY: [\n twoDigits,\n (d: DateParts, v: number) => {\n const da = new Date();\n const cent = +da.getFullYear().toString().substr(0, 2);\n d.year = +`${v > 68 ? cent - 1 : cent}${v}`;\n },\n ],\n YYYY: [\n fourDigits,\n (d: DateParts, v: number) => {\n d.year = v;\n },\n ],\n S: [\n /\\d/,\n (d: DateParts, v: number) => {\n d.milliseconds = v * 100;\n },\n ],\n SS: [\n /\\d{2}/,\n (d: DateParts, v: number) => {\n d.milliseconds = v * 10;\n },\n ],\n SSS: [\n threeDigits,\n (d: DateParts, v: number) => {\n d.milliseconds = v;\n },\n ],\n h: [\n twoDigits,\n (d: DateParts, v: number) => {\n d.hours = v;\n },\n ],\n m: [\n twoDigits,\n (d: DateParts, v: number) => {\n d.minutes = v;\n },\n ],\n s: [\n twoDigits,\n (d: DateParts, v: number) => {\n d.seconds = v;\n },\n ],\n a: [\n word,\n (d: DateParts, v: string, l: Locale) => {\n const val = v.toLowerCase();\n if (val === l.amPm[0]) {\n d.isPm = false;\n } else if (val === l.amPm[1]) {\n d.isPm = true;\n }\n },\n ],\n Z: [\n /[^\\s]*?[+-]\\d\\d:?\\d\\d|[^\\s]*?Z?/,\n (d: DateParts, v: string) => {\n if (v === 'Z') v = '+00:00';\n const parts = `${v}`.match(/([+-]|\\d\\d)/gi);\n if (parts) {\n const minutes = +parts[1] * 60 + parseInt(parts[2], 10);\n d.timezoneOffset = parts[0] === '+' ? minutes : -minutes;\n }\n },\n ],\n};\nparseFlags.DD = parseFlags.D;\nparseFlags.dd = parseFlags.d;\nparseFlags.WWWW = parseFlags.WWW = parseFlags.WW = parseFlags.W;\nparseFlags.MM = parseFlags.M;\nparseFlags.mm = parseFlags.m;\nparseFlags.hh = parseFlags.H = parseFlags.HH = parseFlags.h;\nparseFlags.ss = parseFlags.s;\nparseFlags.A = parseFlags.a;\nparseFlags.ZZZZ = parseFlags.ZZZ = parseFlags.ZZ = parseFlags.Z;\n\n// #endregion Parse constants\n\nfunction normalizeMasks(masks: string | string[], locale: Locale): string[] {\n return (\n ((arrayHasItems(masks) && masks) || [\n (isString(masks) && masks) || 'YYYY-MM-DD',\n ]) as string[]\n ).map(m =>\n maskMacros.reduce(\n (prev, curr) => prev.replace(curr, locale.masks[curr] || ''),\n m,\n ),\n );\n}\n\nexport function isDateParts(parts: unknown): parts is Partial {\n return (\n isObject(parts) && 'year' in parts && 'month' in parts && 'day' in parts\n );\n}\n\nexport function isDateSource(date: unknown): date is DateSource {\n if (date == null) return false;\n return isString(date) || isNumber(date) || isDate(date);\n}\n\nexport function roundDate(dateMs: number, snapMs = 0) {\n if (snapMs > 0) return new Date(Math.round(dateMs / snapMs) * snapMs);\n return new Date(dateMs);\n}\n\nexport function startOfWeek(date: Date, firstDayOfWeek: DayOfWeek = 1) {\n const day = date.getDay() + 1;\n const daysToAdd =\n day >= firstDayOfWeek\n ? firstDayOfWeek - day\n : -(7 - (firstDayOfWeek - day));\n return addDays(date, daysToAdd);\n}\n\nexport function getStartOfWeek(date: Date, firstDayOfWeek: DayOfWeek = 1) {\n const day = date.getDay() + 1;\n const daysToAdd =\n day >= firstDayOfWeek\n ? firstDayOfWeek - day\n : -(7 - (firstDayOfWeek - day));\n return addDays(date, daysToAdd);\n}\n\nexport function getDayIndex(year: number, month: number, day: number) {\n const utcDate = Date.UTC(year, month - 1, day);\n return diffInDays(new Date(0), new Date(utcDate));\n}\n\nexport function diffInDays(d1: Date, d2: Date) {\n return Math.round((d2.getTime() - d1.getTime()) / MS_PER_DAY);\n}\n\nexport function diffInWeeks(d1: Date, d2: Date) {\n return Math.ceil(diffInDays(startOfWeek(d1), startOfWeek(d2)) / 7);\n}\n\nexport function diffInYears(d1: Date, d2: Date) {\n return d2.getUTCFullYear() - d1.getUTCFullYear();\n}\n\nexport function diffInMonths(d1: Date, d2: Date) {\n return diffInYears(d1, d2) * 12 + (d2.getMonth() - d1.getMonth());\n}\n\nexport function getDateFromParts(\n parts: Partial,\n timezone = '',\n) {\n const d = new Date();\n const {\n year = d.getFullYear(),\n month = d.getMonth() + 1,\n day = d.getDate(),\n hours: hrs = 0,\n minutes: min = 0,\n seconds: sec = 0,\n milliseconds: ms = 0,\n } = parts;\n\n if (timezone) {\n const dateString = `${pad(year, 4)}-${pad(month, 2)}-${pad(day, 2)}T${pad(\n hrs,\n 2,\n )}:${pad(min, 2)}:${pad(sec, 2)}.${pad(ms, 3)}`;\n return toFnsDate(dateString, { timeZone: timezone });\n }\n return new Date(year, month - 1, day, hrs, min, sec, ms);\n}\n\nexport function getTimezoneOffset(\n parts: Partial,\n timezone = '',\n) {\n const {\n year: y = 0,\n month: m = 0,\n day: d = 0,\n hours: hrs = 0,\n minutes: min = 0,\n seconds: sec = 0,\n milliseconds: ms = 0,\n } = parts;\n let date;\n const utcDate = new Date(Date.UTC(y, m - 1, d, hrs, min, sec, ms));\n if (timezone) {\n const dateString = `${pad(y, 4)}-${pad(m, 2)}-${pad(d, 2)}T${pad(\n hrs,\n 2,\n )}:${pad(min, 2)}:${pad(sec, 2)}.${pad(ms, 3)}`;\n date = toFnsDate(dateString, { timeZone: timezone });\n } else {\n date = new Date(y, m - 1, d, hrs, min, sec, ms);\n }\n return (date.getTime() - utcDate.getTime()) / 60000;\n}\n\nexport function getDateParts(date: Date, locale: Locale): DateParts {\n let tzDate = new Date(date.getTime());\n if (locale.timezone) {\n tzDate = new Date(\n date.toLocaleString('en-US', { timeZone: locale.timezone }),\n );\n tzDate.setMilliseconds(date.getMilliseconds());\n }\n const milliseconds = tzDate.getMilliseconds();\n const seconds = tzDate.getSeconds();\n const minutes = tzDate.getMinutes();\n const hours = tzDate.getHours();\n const time =\n milliseconds +\n seconds * MS_PER_SECOND +\n minutes * MS_PER_MINUTE +\n hours * MS_PER_HOUR;\n const month = (tzDate.getMonth() + 1);\n const year = tzDate.getFullYear();\n const monthParts = locale.getMonthParts(month, year);\n const day = tzDate.getDate();\n const dayFromEnd = monthParts.numDays - day + 1;\n const weekday = tzDate.getDay() + 1;\n const weekdayOrdinal = Math.floor((day - 1) / 7 + 1);\n const weekdayOrdinalFromEnd = Math.floor((monthParts.numDays - day) / 7 + 1);\n const week = Math.ceil(\n (day + Math.abs(monthParts.firstWeekday - monthParts.firstDayOfWeek)) / 7,\n );\n const weekFromEnd = monthParts.numWeeks - week + 1;\n const weeknumber = monthParts.weeknumbers[week];\n const dayIndex = getDayIndex(year, month, day);\n const parts: DateParts = {\n milliseconds,\n seconds,\n minutes,\n hours,\n time,\n day,\n dayFromEnd,\n weekday,\n weekdayOrdinal,\n weekdayOrdinalFromEnd,\n week,\n weekFromEnd,\n weeknumber,\n month,\n year,\n date: tzDate,\n dateTime: tzDate.getTime(),\n dayIndex,\n timezoneOffset: 0,\n isValid: true,\n };\n return parts;\n}\n\nexport function getMonthPartsKey(\n month: number,\n year: number,\n firstDayOfWeek: DayOfWeek,\n) {\n return `${year}-${month}-${firstDayOfWeek}`;\n}\n\nexport function getMonthParts(\n month: number,\n year: number,\n firstDayOfWeek: DayOfWeek,\n) {\n const inLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n const firstDayOfMonth = new Date(year, month - 1, 1);\n const firstWeekday = firstDayOfMonth.getDay() + 1;\n const numDays = month === 2 && inLeapYear ? 29 : daysInMonths[month - 1];\n const weekStartsOn: WeekStartsOn = (firstDayOfWeek - 1) as WeekStartsOn;\n const numWeeks = getWeeksInMonth(firstDayOfMonth, {\n weekStartsOn,\n });\n const weeknumbers = [];\n const isoWeeknumbers = [];\n for (let i = 0; i < numWeeks; i++) {\n const date = addDays(firstDayOfMonth, i * 7);\n weeknumbers.push(getWeek(date, { weekStartsOn }));\n isoWeeknumbers.push(getISOWeek(date));\n }\n return {\n firstDayOfWeek,\n firstDayOfMonth,\n inLeapYear,\n firstWeekday,\n numDays,\n numWeeks,\n month,\n year,\n weeknumbers,\n isoWeeknumbers,\n };\n}\n\nexport function getWeekdayDates() {\n const dates = [];\n const year = 2020;\n const month = 1;\n const day = 5;\n for (let i = 0; i < daysInWeek; i++) {\n dates.push(\n getDateFromParts({\n year,\n month,\n day: day + i,\n hours: 12,\n }),\n );\n }\n return dates;\n}\n\nexport function getDayNames(\n length: DayNameLength,\n localeId: string | undefined = undefined,\n) {\n const dtf = new Intl.DateTimeFormat(localeId, {\n weekday: length,\n });\n return getWeekdayDates().map(d => dtf.format(d));\n}\n\nexport function getHourDates() {\n const dates = [];\n for (let i = 0; i <= 24; i++) {\n dates.push(new Date(2000, 0, 1, i));\n }\n return dates;\n}\n\nexport function getRelativeTimeNames(localeId = undefined): TimeNames {\n const units: Intl.RelativeTimeFormatUnit[] = [\n 'second',\n 'minute',\n 'hour',\n 'day',\n 'week',\n 'month',\n 'quarter',\n 'year',\n ];\n const rtf = new Intl.RelativeTimeFormat(localeId);\n return units.reduce((names, unit) => {\n const parts = rtf.formatToParts(100, unit);\n // @ts-ignore\n names[unit] = parts[1].unit;\n return names;\n }, {});\n}\n\nexport function getMonthDates() {\n const dates = [];\n for (let i = 0; i < 12; i++) {\n dates.push(new Date(2000, i, 15));\n }\n return dates;\n}\n\nexport function getMonthNames(length: MonthNameLength, localeId = undefined) {\n const dtf = new Intl.DateTimeFormat(localeId, {\n month: length,\n timeZone: 'UTC',\n });\n return getMonthDates().map(d => dtf.format(d));\n}\n\nexport function datePartIsValid(\n part: number,\n rule: DatePartsRule,\n parts: DateParts,\n): boolean {\n if (isNumber(rule)) return rule === part;\n if (isArray(rule)) return (rule as number[]).includes(part);\n if (isFunction(rule)) return rule(part, parts);\n if (rule.min != null && rule.min > part) return false;\n if (rule.max != null && rule.max < part) return false;\n if (rule.interval != null && part % rule.interval !== 0) return false;\n return true;\n}\n\nexport function getDatePartOptions(\n parts: DateParts,\n range: DatePartsRange,\n rule: DatePartsRule | undefined,\n) {\n const options: DatePartOption[] = [];\n const [min, max, padding] = range;\n for (let i = min; i <= max; i++) {\n if (rule == null || datePartIsValid(i, rule, parts)) {\n options.push({\n value: i,\n label: pad(i, padding),\n });\n }\n }\n return options;\n}\n\nexport function getDatePartsOptions(parts: DateParts, rules: DatePartsRules) {\n return {\n milliseconds: getDatePartOptions(\n parts,\n DATE_PART_RANGES.milliseconds,\n rules.milliseconds,\n ),\n seconds: getDatePartOptions(parts, DATE_PART_RANGES.seconds, rules.seconds),\n minutes: getDatePartOptions(parts, DATE_PART_RANGES.minutes, rules.minutes),\n hours: getDatePartOptions(parts, DATE_PART_RANGES.hours, rules.hours),\n };\n}\n\nexport function getNearestDatePart(\n parts: DateParts,\n range: DatePartsRange,\n value: number,\n rule: DatePartsRule,\n) {\n const options = getDatePartOptions(parts, range, rule);\n const result = options.reduce((prev, opt) => {\n if (opt.disabled) return prev;\n if (isNaN(prev)) return opt.value;\n const diffPrev = Math.abs(prev - value);\n const diffCurr = Math.abs(opt.value - value);\n return diffCurr < diffPrev ? opt.value : prev;\n }, NaN);\n return isNaN(result) ? value : result;\n}\n\nexport function applyRulesForDateParts(\n dateParts: DateParts,\n rules: DatePartsRules,\n) {\n const result = { ...dateParts };\n Object.entries(rules).forEach(([key, rule]) => {\n const range = DATE_PART_RANGES[key as TimePartsKey];\n const value = dateParts[key as TimePartsKey];\n result[key as TimePartsKey] = getNearestDatePart(\n dateParts,\n range,\n value,\n rule,\n );\n });\n return result;\n}\n\nexport function parseDate(\n dateString: string,\n mask: string | string[],\n locale: Locale,\n) {\n const masks = normalizeMasks(mask, locale);\n return (\n masks\n .map(m => {\n if (typeof m !== 'string') {\n throw new Error('Invalid mask');\n }\n // Reset string value\n let str = dateString;\n // Avoid regular expression denial of service, fail early for really long strings\n // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS\n if (str.length > 1000) {\n return false;\n }\n\n let isValid = true;\n const dp: Partial = {};\n m.replace(token, $0 => {\n if (parseFlags[$0]) {\n const info = parseFlags[$0];\n const index = str.search(info[0]);\n if (!~index) {\n isValid = false;\n } else {\n str.replace(info[0], result => {\n info[1](dp, result, locale);\n str = str.substr(index + result.length);\n return result;\n });\n }\n }\n\n return parseFlags[$0] ? '' : $0.slice(1, $0.length - 1);\n });\n\n if (!isValid) {\n return false;\n }\n\n const today = new Date();\n if (dp.hours != null) {\n if (dp.isPm === true && +dp.hours !== 12) {\n dp.hours = +dp.hours + 12;\n } else if (dp.isPm === false && +dp.hours === 12) {\n dp.hours = 0;\n }\n }\n\n let date;\n if (dp.timezoneOffset != null) {\n dp.minutes = +(dp.minutes || 0) - +dp.timezoneOffset;\n date = new Date(\n Date.UTC(\n dp.year || today.getFullYear(),\n dp.month || 0,\n dp.day || 1,\n dp.hours || 0,\n dp.minutes || 0,\n dp.seconds || 0,\n dp.milliseconds || 0,\n ),\n );\n } else {\n date = locale.getDateFromParts({\n year: dp.year || today.getFullYear(),\n month: (dp.month || 0) + 1,\n day: dp.day || 1,\n hours: dp.hours || 0,\n minutes: dp.minutes || 0,\n seconds: dp.seconds || 0,\n milliseconds: dp.milliseconds || 0,\n });\n }\n return date;\n })\n .find(d => d) || new Date(dateString)\n );\n}\n\nexport function formatDate(\n date: Date,\n masks: string | string[],\n locale: Locale,\n) {\n if (date == null) return '';\n let mask = normalizeMasks(masks, locale)[0];\n // Convert timezone to utc if needed\n if (/Z$/.test(mask)) locale.timezone = 'utc';\n const literals: string[] = [];\n // Make literals inactive by replacing them with ??\n mask = mask.replace(literal, ($0, $1: string) => {\n literals.push($1);\n return '??';\n });\n const dateParts = locale.getDateParts(date);\n // Apply formatting rules\n mask = mask.replace(token, $0 =>\n $0 in formatFlags\n ? formatFlags[$0](dateParts, locale)\n : $0.slice(1, $0.length - 1),\n );\n // Inline literal values back into the formatted value\n return mask.replace(/\\?\\?/g, () => literals.shift()!);\n}\n","import {\n DateSource,\n DayParts,\n DateParts,\n MonthParts,\n daysInWeek,\n weeksInMonth,\n addDays,\n addMonths,\n getDayIndex,\n} from './date/helpers';\nimport Locale from './locale';\nimport { pad, pick } from './helpers';\n\nexport interface CalendarDay extends DayParts {\n id: string;\n position: number;\n label: string;\n ariaLabel: string;\n weekdayPosition: number;\n weekdayPositionFromEnd: number;\n weekPosition: number;\n isoWeeknumber: number;\n startDate: Date;\n noonDate: Date;\n endDate: Date;\n isToday: boolean;\n isFirstDay: boolean;\n isLastDay: boolean;\n isDisabled: boolean;\n isFocusable: boolean;\n isFocused: boolean;\n inMonth: boolean;\n inPrevMonth: boolean;\n inNextMonth: boolean;\n onTop: boolean;\n onBottom: boolean;\n onLeft: boolean;\n onRight: boolean;\n classes: Array;\n locale: Locale;\n}\n\nexport interface CalendarWeek {\n id: string;\n week: number;\n weekPosition: number;\n weeknumber: number;\n isoWeeknumber: number;\n weeknumberDisplay?: number;\n days: CalendarDay[];\n title: string;\n}\n\nexport interface CalendarWeekday {\n weekday: number;\n label: string;\n}\n\nexport type PageView = 'daily' | 'weekly' | 'monthly';\n\nexport type TitlePosition = 'center' | 'left' | 'right';\n\nexport interface Page {\n id: string;\n day?: number;\n week?: number;\n month: number;\n year: number;\n view: PageView;\n trimWeeks: boolean;\n position: number;\n row: number;\n rowFromEnd: number;\n column: number;\n columnFromEnd: number;\n showWeeknumbers: boolean;\n showIsoWeeknumbers: boolean;\n weeknumberPosition: string;\n monthTitle: string;\n weekTitle?: string;\n dayTitle?: string;\n title: string;\n titlePosition: TitlePosition;\n shortMonthLabel: string;\n monthLabel: string;\n shortYearLabel: string;\n yearLabel: string;\n monthComps: MonthParts;\n prevMonthComps: MonthParts;\n nextMonthComps: MonthParts;\n days: CalendarDay[];\n weeks: CalendarWeek[];\n weekdays: CalendarWeekday[];\n viewDays: CalendarDay[];\n viewWeeks: CalendarWeek[];\n}\n\nexport type PageAddress = Pick;\n\nexport type PageConfig = Pick<\n Page,\n | 'day'\n | 'week'\n | 'month'\n | 'year'\n | 'view'\n | 'titlePosition'\n | 'trimWeeks'\n | 'position'\n | 'row'\n | 'rowFromEnd'\n | 'column'\n | 'columnFromEnd'\n | 'showWeeknumbers'\n | 'showIsoWeeknumbers'\n | 'weeknumberPosition'\n>;\n\nexport type CachedPage = Pick<\n Page,\n | 'id'\n | 'month'\n | 'year'\n | 'monthTitle'\n | 'shortMonthLabel'\n | 'monthLabel'\n | 'shortYearLabel'\n | 'yearLabel'\n | 'monthComps'\n | 'prevMonthComps'\n | 'nextMonthComps'\n | 'days'\n | 'weeks'\n | 'weekdays'\n>;\n\nconst viewAddressKeys: Record = {\n daily: ['year', 'month', 'day'],\n weekly: ['year', 'month', 'week'],\n monthly: ['year', 'month'],\n};\n\nfunction getDays(\n {\n monthComps,\n prevMonthComps,\n nextMonthComps,\n }: Pick,\n locale: Locale,\n): CalendarDay[] {\n const days: CalendarDay[] = [];\n const {\n firstDayOfWeek,\n firstWeekday,\n isoWeeknumbers,\n weeknumbers,\n numDays,\n numWeeks,\n } = monthComps;\n const prevMonthDaysToShow =\n firstWeekday +\n (firstWeekday < firstDayOfWeek ? daysInWeek : 0) -\n firstDayOfWeek;\n let prevMonth = true;\n let thisMonth = false;\n let nextMonth = false;\n let position = 0;\n // Formatter for aria labels\n const formatter = new Intl.DateTimeFormat(locale.id, {\n weekday: 'long',\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n // Init counters with previous month's data\n let day = prevMonthComps.numDays - prevMonthDaysToShow + 1;\n let dayFromEnd = prevMonthComps.numDays - day + 1;\n let weekdayOrdinal = Math.floor((day - 1) / daysInWeek + 1);\n let weekdayOrdinalFromEnd = 1;\n let week = prevMonthComps.numWeeks;\n let weekFromEnd = 1;\n let month = prevMonthComps.month;\n let year = prevMonthComps.year;\n // Store todays comps\n const today = new Date();\n const todayDay = today.getDate();\n const todayMonth = today.getMonth() + 1;\n const todayYear = today.getFullYear();\n // Cycle through max weeks in month\n for (let w = 1; w <= weeksInMonth; w++) {\n // Cycle through days in week\n for (\n let i = 1, weekday = firstDayOfWeek;\n i <= daysInWeek;\n i++, weekday += weekday === daysInWeek ? 1 - daysInWeek : 1\n ) {\n // We need to know when to start counting actual month days\n if (prevMonth && weekday === firstWeekday) {\n // Reset counters for current month\n day = 1;\n dayFromEnd = monthComps.numDays;\n weekdayOrdinal = Math.floor((day - 1) / daysInWeek + 1);\n weekdayOrdinalFromEnd = Math.floor((numDays - day) / daysInWeek + 1);\n week = 1;\n weekFromEnd = numWeeks;\n month = monthComps.month;\n year = monthComps.year;\n // ...and flag we're tracking actual month days\n prevMonth = false;\n thisMonth = true;\n }\n const startDate = locale.getDateFromParams(year, month, day, 0, 0, 0, 0);\n const noonDate = locale.getDateFromParams(year, month, day, 12, 0, 0, 0);\n const endDate = locale.getDateFromParams(\n year,\n month,\n day,\n 23,\n 59,\n 59,\n 999,\n );\n const date = startDate;\n const id = `${pad(year, 4)}-${pad(month, 2)}-${pad(day, 2)}`;\n const weekdayPosition = i;\n const weekdayPositionFromEnd = daysInWeek - i;\n const weeknumber = weeknumbers[w - 1];\n const isoWeeknumber = isoWeeknumbers[w - 1];\n const isToday =\n day === todayDay && month === todayMonth && year === todayYear;\n const isFirstDay = thisMonth && day === 1;\n const isLastDay = thisMonth && day === numDays;\n const onTop = w === 1;\n const onBottom = w === numWeeks;\n const onLeft = i === 1;\n const onRight = i === daysInWeek;\n const dayIndex = getDayIndex(year, month, day);\n days.push({\n locale,\n id,\n position: ++position,\n label: day.toString(),\n ariaLabel: formatter.format(new Date(year, month - 1, day)),\n day,\n dayFromEnd,\n weekday,\n weekdayPosition,\n weekdayPositionFromEnd,\n weekdayOrdinal,\n weekdayOrdinalFromEnd,\n week,\n weekFromEnd,\n weekPosition: w,\n weeknumber,\n isoWeeknumber,\n month,\n year,\n date,\n startDate,\n endDate,\n noonDate,\n dayIndex,\n isToday,\n isFirstDay,\n isLastDay,\n isDisabled: !thisMonth,\n isFocusable: !thisMonth,\n isFocused: false,\n inMonth: thisMonth,\n inPrevMonth: prevMonth,\n inNextMonth: nextMonth,\n onTop,\n onBottom,\n onLeft,\n onRight,\n classes: [\n `id-${id}`,\n `day-${day}`,\n `day-from-end-${dayFromEnd}`,\n `weekday-${weekday}`,\n `weekday-position-${weekdayPosition}`,\n `weekday-ordinal-${weekdayOrdinal}`,\n `weekday-ordinal-from-end-${weekdayOrdinalFromEnd}`,\n `week-${week}`,\n `week-from-end-${weekFromEnd}`,\n {\n 'is-today': isToday,\n 'is-first-day': isFirstDay,\n 'is-last-day': isLastDay,\n 'in-month': thisMonth,\n 'in-prev-month': prevMonth,\n 'in-next-month': nextMonth,\n 'on-top': onTop,\n 'on-bottom': onBottom,\n 'on-left': onLeft,\n 'on-right': onRight,\n },\n ],\n });\n // See if we've hit the last day of the month\n if (thisMonth && isLastDay) {\n thisMonth = false;\n nextMonth = true;\n // Reset counters to next month's data\n day = 1;\n dayFromEnd = numDays;\n weekdayOrdinal = 1;\n weekdayOrdinalFromEnd = Math.floor((numDays - day) / daysInWeek + 1);\n week = 1;\n weekFromEnd = nextMonthComps.numWeeks;\n month = nextMonthComps.month;\n year = nextMonthComps.year;\n // Still in the middle of the month (hasn't ended yet)\n } else {\n day++;\n dayFromEnd--;\n weekdayOrdinal = Math.floor((day - 1) / daysInWeek + 1);\n weekdayOrdinalFromEnd = Math.floor((numDays - day) / daysInWeek + 1);\n }\n }\n // Append week days\n week++;\n weekFromEnd--;\n }\n return days;\n}\n\nfunction getWeeks(\n days: CalendarDay[],\n showWeeknumbers: boolean,\n showIsoWeeknumbers: boolean,\n locale: Locale,\n): CalendarWeek[] {\n const result = days.reduce((result: CalendarWeek[], day: CalendarDay, i) => {\n const weekIndex = Math.floor(i / 7);\n let week = result[weekIndex];\n if (!week) {\n week = {\n id: `week-${weekIndex + 1}`,\n title: '',\n week: day.week,\n weekPosition: day.weekPosition,\n weeknumber: day.weeknumber,\n isoWeeknumber: day.isoWeeknumber,\n weeknumberDisplay: showWeeknumbers\n ? day.weeknumber\n : showIsoWeeknumbers\n ? day.isoWeeknumber\n : undefined,\n days: [],\n };\n result[weekIndex] = week;\n }\n week.days.push(day);\n return result;\n }, Array(days.length / daysInWeek));\n result.forEach(week => {\n const fromDay = week.days[0];\n const toDay = week.days[week.days.length - 1];\n if (fromDay.month === toDay.month) {\n week.title = `${locale.formatDate(fromDay.date, 'MMMM YYYY')}`;\n } else if (fromDay.year === toDay.year) {\n week.title = `${locale.formatDate(\n fromDay.date,\n 'MMM',\n )} - ${locale.formatDate(toDay.date, 'MMM YYYY')}`;\n } else {\n week.title = `${locale.formatDate(\n fromDay.date,\n 'MMM YYYY',\n )} - ${locale.formatDate(toDay.date, 'MMM YYYY')}`;\n }\n });\n return result;\n}\n\nfunction getWeekdays(week: CalendarWeek, locale: Locale): CalendarWeekday[] {\n return week.days.map(day => ({\n label: locale.formatDate(day.date, locale.masks.weekdays),\n weekday: day.weekday,\n }));\n}\n\nexport function getPageAddressForDate(\n date: DateSource,\n view: PageView,\n locale: Locale,\n) {\n return pick(\n locale.getDateParts(locale.toDate(date)),\n viewAddressKeys[view],\n ) as PageAddress;\n}\n\nexport function addPages(\n { day, week, month, year }: PageAddress,\n count: number,\n view: PageView,\n locale: Locale,\n): PageAddress {\n if (view === 'daily' && day) {\n const date = new Date(year, month - 1, day);\n const newDate = addDays(date, count);\n return {\n day: newDate.getDate(),\n month: newDate.getMonth() + 1,\n year: newDate.getFullYear(),\n };\n } else if (view === 'weekly' && week) {\n const comps = locale.getMonthParts(month, year);\n const date = comps.firstDayOfMonth;\n const newDate = addDays(date, (week - 1 + count) * 7);\n const parts = locale.getDateParts(newDate);\n return {\n week: parts.week,\n month: parts.month,\n year: parts.year,\n };\n } else {\n const date = new Date(year, month - 1, 1);\n const newDate = addMonths(date, count);\n return {\n month: newDate.getMonth() + 1,\n year: newDate.getFullYear(),\n };\n }\n}\n\nexport function pageIsValid(page: PageAddress | null | undefined) {\n return page != null && page.month != null && page.year != null;\n}\n\nexport function pageIsBeforePage(\n page: PageAddress | null | undefined,\n comparePage: PageAddress | null | undefined,\n) {\n if (!pageIsValid(page) || !pageIsValid(comparePage)) return false;\n page = page as PageAddress;\n comparePage = comparePage as PageAddress;\n if (page.year !== comparePage.year) return page.year < comparePage.year;\n if (page.month && comparePage.month && page.month !== comparePage.month)\n return page.month < comparePage.month;\n if (page.week && comparePage.week && page.week !== comparePage.week) {\n return page.week < comparePage.week;\n }\n if (page.day && comparePage.day && page.day !== comparePage.day) {\n return page.day < comparePage.day;\n }\n return false;\n}\n\nexport function pageIsAfterPage(\n page: PageAddress | null | undefined,\n comparePage: PageAddress | null | undefined,\n) {\n if (!pageIsValid(page) || !pageIsValid(comparePage)) return false;\n page = page as PageAddress;\n comparePage = comparePage as PageAddress;\n if (page.year !== comparePage.year) {\n return page.year > comparePage.year;\n }\n if (page.month && comparePage.month && page.month !== comparePage.month) {\n return page.month > comparePage.month;\n }\n if (page.week && comparePage.week && page.week !== comparePage.week) {\n return page.week > comparePage.week;\n }\n if (page.day && comparePage.day && page.day !== comparePage.day) {\n return page.day > comparePage.day;\n }\n return false;\n}\n\nexport function pageIsBetweenPages(\n page: PageAddress | null | undefined,\n fromPage: PageAddress | null | undefined,\n toPage: PageAddress | null | undefined,\n) {\n return (\n (page || false) &&\n !pageIsBeforePage(page, fromPage) &&\n !pageIsAfterPage(page, toPage)\n );\n}\n\nexport function pageIsEqualToPage(\n aPage: PageAddress | null | undefined,\n bPage: PageAddress | null | undefined,\n) {\n if (!aPage && bPage) return false;\n if (aPage && !bPage) return false;\n if (!aPage && !bPage) return true;\n aPage = aPage as PageAddress;\n bPage = bPage as PageAddress;\n return (\n aPage.year === bPage.year &&\n aPage.month === bPage.month &&\n aPage.week === bPage.week &&\n aPage.day === bPage.day\n );\n}\n\nexport function pageRangeToArray(\n from: PageAddress,\n to: PageAddress,\n view: PageView,\n locale: Locale,\n) {\n if (!pageIsValid(from) || !pageIsValid(to)) return [];\n const result = [];\n while (!pageIsAfterPage(from, to)) {\n result.push(from);\n from = addPages(from, 1, view, locale);\n }\n return result;\n}\n\nexport function getPageKey(config: PageConfig) {\n const { day, week, month, year } = config;\n let id = `${year}-${pad(month, 2)}`;\n if (week) id = `${id}-w${week}`;\n if (day) id = `${id}-${pad(day, 2)}`;\n return id;\n}\n\nexport function getCachedPage(config: PageConfig, locale: Locale): CachedPage {\n const { month, year, showWeeknumbers, showIsoWeeknumbers } = config;\n const date = new Date(year, month - 1, 15);\n const monthComps = locale.getMonthParts(month, year);\n const prevMonthComps = locale.getPrevMonthParts(month, year);\n const nextMonthComps = locale.getNextMonthParts(month, year);\n const days = getDays({ monthComps, prevMonthComps, nextMonthComps }, locale);\n const weeks = getWeeks(days, showWeeknumbers, showIsoWeeknumbers, locale);\n const weekdays = getWeekdays(weeks[0], locale);\n return {\n id: getPageKey(config),\n month,\n year,\n monthTitle: locale.formatDate(date, locale.masks.title),\n shortMonthLabel: locale.formatDate(date, 'MMM'),\n monthLabel: locale.formatDate(date, 'MMMM'),\n shortYearLabel: year.toString().substring(2),\n yearLabel: year.toString(),\n monthComps,\n prevMonthComps,\n nextMonthComps,\n days,\n weeks,\n weekdays,\n };\n}\n\nexport function getPage(config: PageConfig, cachedPage: CachedPage) {\n const { day, week, view, trimWeeks } = config;\n const page: Page = {\n ...cachedPage,\n ...config,\n title: '',\n viewDays: [],\n viewWeeks: [],\n };\n switch (view) {\n case 'daily': {\n let dayObj = page.days.find(d => d.inMonth)!;\n if (day) {\n dayObj = page.days.find(d => d.day === day && d.inMonth) || dayObj;\n } else if (week) {\n dayObj = page.days.find(d => d.week === week && d.inMonth)!;\n }\n const weekObj = page.weeks[dayObj.week - 1];\n page.viewWeeks = [weekObj];\n page.viewDays = [dayObj];\n page.week = dayObj.week;\n page.weekTitle = weekObj.title;\n page.day = dayObj.day;\n page.dayTitle = dayObj.ariaLabel;\n page.title = page.dayTitle;\n break;\n }\n case 'weekly': {\n page.week = week || 1;\n const weekObj = page.weeks[page.week - 1];\n page.viewWeeks = [weekObj];\n page.viewDays = weekObj.days;\n page.weekTitle = weekObj.title;\n page.title = page.weekTitle;\n break;\n }\n default: {\n page.title = page.monthTitle;\n page.viewWeeks = page.weeks.slice(\n 0,\n trimWeeks ? page.monthComps.numWeeks : undefined,\n );\n page.viewDays = page.days;\n break;\n }\n }\n return page;\n}\n","export default class Cache {\n keys: string[] = [];\n store: Record = {};\n\n constructor(\n public size: number,\n public createKey: (...args: any[]) => string,\n public createItem: (...args: any[]) => T,\n ) {}\n\n get(...args: any[]) {\n const key = this.createKey(...args);\n return this.store[key];\n }\n\n getOrSet(...args: any[]): T {\n const key = this.createKey(...args);\n if (this.store[key]) return this.store[key];\n const item = this.createItem(...args);\n if (this.keys.length >= this.size) {\n const removeKey = this.keys.shift();\n if (removeKey != null) {\n delete this.store[removeKey];\n }\n }\n this.keys.push(key);\n this.store[key] = item;\n return item;\n }\n}\n","import { type DateRepeatConfig, DateRepeat } from './repeat';\nimport { type DateParts, type DayParts, addDays, MS_PER_DAY } from './helpers';\nimport { isDate, isArray, isObject } from '../helpers';\nimport type { CalendarDay } from '../page';\nimport Locale from '../locale';\n\ntype DateRangeDate = Date | string | number | null;\n\ninterface DateRangeConfig {\n start: DateRangeDate;\n end: DateRangeDate;\n span: number;\n order: number;\n repeat: Partial;\n}\n\nexport type DateRangeSource =\n | DateRange\n | DateRangeDate\n | [DateRangeDate, DateRangeDate]\n | Partial;\n\nexport interface SimpleDateRange {\n start: Date;\n end: Date;\n}\n\nexport class DateRange {\n order: number;\n locale: Locale;\n start: DateParts | null = null;\n end: DateParts | null = null;\n repeat: DateRepeat | null = null;\n\n static fromMany(ranges: DateRangeSource | DateRangeSource[], locale: Locale) {\n // Assign dates\n return (isArray(ranges) ? ranges : [ranges])\n .filter(d => d)\n .map(d => DateRange.from(d, locale));\n }\n\n static from(source: DateRangeSource, locale: Locale) {\n if (source instanceof DateRange) return source;\n const config: Partial = {\n start: null,\n end: null,\n };\n if (source != null) {\n if (isArray(source)) {\n config.start = source[0] ?? null;\n config.end = source[1] ?? null;\n } else if (isObject(source)) {\n Object.assign(config, source);\n } else {\n config.start = source;\n config.end = source;\n }\n }\n if (config.start != null) config.start = new Date(config.start);\n if (config.end != null) config.end = new Date(config.end);\n return new DateRange(config, locale);\n }\n\n private constructor(config: Partial, locale = new Locale()) {\n this.locale = locale;\n const { start, end, span, order, repeat } = config;\n\n if (isDate(start)) {\n this.start = locale.getDateParts(start);\n }\n\n if (isDate(end)) {\n this.end = locale.getDateParts(end);\n } else if (this.start != null && span) {\n this.end = locale.getDateParts(addDays(this.start.date, span - 1));\n }\n\n this.order = order ?? 0;\n\n if (repeat) {\n this.repeat = new DateRepeat(\n {\n from: this.start?.date,\n ...repeat,\n },\n {\n locale: this.locale,\n },\n );\n }\n }\n\n get opts() {\n const { order, locale } = this;\n return { order, locale };\n }\n\n get hasRepeat() {\n return !!this.repeat;\n }\n\n get isSingleDay() {\n const { start, end } = this;\n return (\n start &&\n end &&\n start.year === end.year &&\n start.month === end.month &&\n start.day === end.day\n );\n }\n\n get isMultiDay() {\n return !this.isSingleDay;\n }\n\n get daySpan() {\n if (this.start == null || this.end == null) {\n if (this.hasRepeat) return 1;\n return Infinity;\n }\n return this.end.dayIndex - this.start.dayIndex;\n }\n\n startsOnDay(dayParts: DayParts) {\n return (\n this.start?.dayIndex === dayParts.dayIndex ||\n !!this.repeat?.passes(dayParts)\n );\n }\n\n intersectsDay(dayIndex: number) {\n return this.intersectsDayRange(dayIndex, dayIndex);\n }\n\n intersectsRange(range: DateRange) {\n return this.intersectsDayRange(\n range.start?.dayIndex ?? -Infinity,\n range.end?.dayIndex ?? Infinity,\n );\n }\n\n intersectsDayRange(startDayIndex: number, endDayIndex: number) {\n if (this.start && this.start.dayIndex > endDayIndex) return false;\n if (this.end && this.end.dayIndex < startDayIndex) return false;\n return true;\n }\n}\n\ninterface DataRange {\n startDay: number;\n startTime: number;\n endDay: number;\n endTime: number;\n}\n\nexport interface RangeData {\n key: string | number;\n order?: number;\n}\n\ninterface DataRanges {\n ranges: DataRange[];\n data: RangeData;\n}\n\nexport interface DateRangeCell extends DataRange {\n data: T;\n onStart: boolean;\n onEnd: boolean;\n startTime: number;\n startDate: Date;\n endTime: number;\n endDate: Date;\n allDay: boolean;\n order: number;\n}\n\nexport class DateRangeContext {\n private records: Record = {};\n\n render(data: RangeData, range: DateRange, days: DayParts[]) {\n let result = null;\n const startDayIndex = days[0].dayIndex;\n const endDayIndex = days[days.length - 1].dayIndex;\n if (range.hasRepeat) {\n days.forEach(day => {\n if (range.startsOnDay(day)) {\n const span = range.daySpan < Infinity ? range.daySpan : 1;\n result = {\n startDay: day.dayIndex,\n startTime: range.start?.time ?? 0,\n endDay: day.dayIndex + span - 1,\n endTime: range.end?.time ?? MS_PER_DAY,\n };\n this.getRangeRecords(data).push(result);\n }\n });\n } else if (range.intersectsDayRange(startDayIndex, endDayIndex)) {\n result = {\n startDay: range.start?.dayIndex ?? -Infinity,\n startTime: range.start?.time ?? -Infinity,\n endDay: range.end?.dayIndex ?? Infinity,\n endTime: range.end?.time ?? Infinity,\n };\n this.getRangeRecords(data).push(result);\n }\n return result;\n }\n\n private getRangeRecords(data: RangeData) {\n let record = this.records[data.key];\n if (!record) {\n record = {\n ranges: [],\n data,\n };\n this.records[data.key] = record;\n }\n return record.ranges;\n }\n\n getCell(key: string | number, day: CalendarDay) {\n const cells = this.getCells(day);\n const result = cells.find(cell => cell.data.key === key);\n return result;\n }\n\n cellExists(key: string | number, dayIndex: number) {\n const records = this.records[key];\n if (records == null) return false;\n return records.ranges.some(\n r => r.startDay <= dayIndex && r.endDay >= dayIndex,\n );\n }\n\n getCells(day: CalendarDay) {\n const records = Object.values(this.records);\n const result: DateRangeCell[] = [];\n const { dayIndex } = day;\n records.forEach(({ data, ranges }) => {\n ranges\n .filter(r => r.startDay <= dayIndex && r.endDay >= dayIndex)\n .forEach(range => {\n const onStart = dayIndex === range.startDay;\n const onEnd = dayIndex === range.endDay;\n const startTime = onStart ? range.startTime : 0;\n const startDate = new Date(day.startDate.getTime() + startTime);\n const endTime = onEnd ? range.endTime : MS_PER_DAY;\n const endDate = new Date(day.endDate.getTime() + endTime);\n const allDay = startTime === 0 && endTime === MS_PER_DAY;\n const order = data.order || 0;\n result.push({\n ...range,\n data,\n onStart,\n onEnd,\n startTime,\n startDate,\n endTime,\n endDate,\n allDay,\n order,\n });\n });\n });\n result.sort((a, b) => a.order - b.order);\n return result;\n }\n}\n","import {\n type PageConfig,\n type CachedPage,\n getPageKey,\n getCachedPage,\n getPage,\n} from './page';\nimport {\n type DateSource,\n type DateOptions,\n type DayOfWeek,\n type MonthParts,\n type MonthInYear,\n type SimpleDateParts,\n type TimeNames,\n DatePatchKeys,\n applyRulesForDateParts,\n daysInWeek,\n formatDate,\n parseDate,\n getDateParts,\n getDateFromParts,\n getDayNames,\n getMonthNames,\n getMonthParts,\n getMonthPartsKey,\n getHourDates,\n getRelativeTimeNames,\n isDateParts,\n} from './date/helpers';\nimport Cache from './cache';\nimport { type DateRangeSource, DateRange } from './date/range';\nimport { defaultLocales } from './defaults';\nimport {\n isString,\n isNumber,\n isDate,\n isObject,\n has,\n pick,\n clamp,\n defaultsDeep,\n} from './helpers';\n\nexport interface LocaleConfig {\n id: string;\n firstDayOfWeek: number;\n masks: any;\n monthCacheSize: number;\n pageCacheSize: number;\n}\n\nconst DEFAULT_MONTH_CACHE_SIZE = 12;\nconst DEFAULT_PAGE_CACHE_SIZE = 5;\n\nexport function resolveConfig(\n config: string | Partial | undefined,\n locales: any,\n) {\n // Get the detected locale string\n const detLocale = new Intl.DateTimeFormat().resolvedOptions().locale;\n // Resolve the locale id\n let id;\n if (isString(config)) {\n id = config;\n } else if (has(config, 'id')) {\n id = config!.id;\n }\n id = (id || detLocale).toLowerCase();\n const localeKeys = Object.keys(locales);\n const validKey = (k: string) => localeKeys.find(lk => lk.toLowerCase() === k);\n id = validKey(id) || validKey(id.substring(0, 2)) || detLocale;\n // Add fallback and spread default locale to prevent repetitive update loops\n const defLocale: LocaleConfig = {\n ...locales['en-IE'],\n ...locales[id],\n id,\n monthCacheSize: DEFAULT_MONTH_CACHE_SIZE,\n pageCacheSize: DEFAULT_PAGE_CACHE_SIZE,\n };\n // Assign or merge defaults with provided config\n const result: LocaleConfig = isObject(config)\n ? defaultsDeep(config, defLocale)\n : defLocale;\n // Return resolved config\n return result;\n}\n\nexport default class Locale {\n id: any;\n daysInWeek: number;\n firstDayOfWeek: DayOfWeek;\n masks: any;\n timezone: string | undefined;\n hourLabels: string[];\n dayNames: string[];\n dayNamesShort: string[];\n dayNamesShorter: string[];\n dayNamesNarrow: string[];\n monthNames: string[];\n monthNamesShort: string[];\n relativeTimeNames: TimeNames;\n amPm: [string, string] = ['am', 'pm'];\n monthCache: Cache;\n pageCache: Cache;\n\n constructor(\n config: Partial | string | undefined = undefined,\n timezone?: string,\n ) {\n const { id, firstDayOfWeek, masks, monthCacheSize, pageCacheSize } =\n resolveConfig(config, defaultLocales.value);\n this.monthCache = new Cache(\n monthCacheSize,\n getMonthPartsKey,\n getMonthParts,\n );\n this.pageCache = new Cache(pageCacheSize, getPageKey, getCachedPage);\n this.id = id;\n this.daysInWeek = daysInWeek;\n this.firstDayOfWeek = clamp(firstDayOfWeek, 1, daysInWeek) as DayOfWeek;\n this.masks = masks;\n this.timezone = timezone || undefined;\n this.hourLabels = this.getHourLabels();\n this.dayNames = getDayNames('long', this.id);\n this.dayNamesShort = getDayNames('short', this.id);\n this.dayNamesShorter = this.dayNamesShort.map(s => s.substring(0, 2));\n this.dayNamesNarrow = getDayNames('narrow', this.id);\n this.monthNames = getMonthNames('long', this.id);\n this.monthNamesShort = getMonthNames('short', this.id);\n this.relativeTimeNames = getRelativeTimeNames(this.id);\n }\n\n formatDate(date: Date, masks: string | string[]) {\n return formatDate(date, masks, this);\n }\n\n parseDate(dateString: string, mask: string | string[]) {\n return parseDate(dateString, mask, this);\n }\n\n toDate(\n d: DateSource | Partial,\n opts: Partial = {},\n ): Date {\n const nullDate = new Date(NaN);\n let result = nullDate;\n const { fillDate, mask, patch, rules } = opts;\n if (isNumber(d)) {\n opts.type = 'number';\n result = new Date(+d);\n } else if (isString(d)) {\n opts.type = 'string';\n result = d ? parseDate(d, mask || 'iso', this) : nullDate;\n } else if (isDate(d)) {\n opts.type = 'date';\n result = new Date(d.getTime());\n } else if (isDateParts(d)) {\n opts.type = 'object';\n result = this.getDateFromParts(d);\n }\n // Patch parts or apply rules if needed\n if (result && (patch || rules)) {\n let parts = this.getDateParts(result);\n // Patch date parts\n if (patch && fillDate != null) {\n const fillParts = this.getDateParts(this.toDate(fillDate));\n parts = this.getDateParts(\n this.toDate({ ...fillParts, ...pick(parts, DatePatchKeys[patch]) }),\n );\n }\n // Apply date part rules\n if (rules) {\n parts = applyRulesForDateParts(parts, rules);\n }\n result = this.getDateFromParts(parts);\n }\n return result || nullDate;\n }\n\n toDateOrNull(\n d: DateSource | Partial,\n opts: Partial = {},\n ): Date | null {\n const dte = this.toDate(d, opts);\n return isNaN(dte.getTime()) ? null : dte;\n }\n\n fromDate(date: Date, { type, mask }: Partial = {}) {\n switch (type) {\n case 'number':\n return date ? date.getTime() : NaN;\n case 'string':\n return date ? this.formatDate(date, mask || 'iso') : '';\n case 'object':\n return date ? this.getDateParts(date) : null;\n default:\n return date ? new Date(date) : null;\n }\n }\n\n range(source: DateRangeSource) {\n return DateRange.from(source, this);\n }\n\n ranges(ranges: DateRangeSource | DateRangeSource[]) {\n return DateRange.fromMany(ranges, this);\n }\n\n getDateParts(date: Date) {\n return getDateParts(date, this);\n }\n\n getDateFromParts(parts: Partial) {\n return getDateFromParts(parts, this.timezone);\n }\n\n getDateFromParams(\n year: number,\n month: number,\n day: number,\n hours: number,\n minutes: number,\n seconds: number,\n milliseconds: number,\n ) {\n return this.getDateFromParts({\n year,\n month,\n day,\n hours,\n minutes,\n seconds,\n milliseconds,\n });\n }\n\n getPage(config: PageConfig) {\n const cachedPage = this.pageCache.getOrSet(config, this);\n return getPage(config, cachedPage);\n }\n\n getMonthParts(month: number, year: number) {\n const { firstDayOfWeek } = this;\n return this.monthCache.getOrSet(month, year, firstDayOfWeek);\n }\n\n getThisMonthParts() {\n const date = new Date();\n return this.getMonthParts(\n (date.getMonth() + 1),\n date.getFullYear(),\n );\n }\n\n getPrevMonthParts(month: number, year: number) {\n if (month === 1) return this.getMonthParts(12, year - 1);\n return this.getMonthParts(month - 1, year);\n }\n\n getNextMonthParts(month: number, year: number) {\n if (month === 12) return this.getMonthParts(1, year + 1);\n return this.getMonthParts(month + 1, year);\n }\n\n getHourLabels() {\n return getHourDates().map(d => {\n return this.formatDate(d, this.masks.hours);\n });\n }\n\n getDayId(date: Date) {\n return this.formatDate(date, 'YYYY-MM-DD');\n }\n}\n","import type { Placement } from '@popperjs/core';\nimport { type DateRangeSource, DateRange } from './date/range';\nimport { arrayHasItems, createGuid } from './helpers';\nimport { addDays } from './date/helpers';\nimport type { PopoverVisibility } from './popovers';\nimport { Theme } from './theme';\nimport Locale from './locale';\n\nimport {\n ContentConfig,\n HighlightConfig,\n DotConfig,\n BarConfig,\n Profile,\n Content,\n Highlight,\n Dot,\n Bar,\n} from './glyph';\n\nexport type PopoverConfig = Partial<{\n label: string;\n visibility: PopoverVisibility;\n placement: Placement;\n hideIndicator: boolean;\n isInteractive: boolean;\n}>;\n\nexport type EventConfig = Partial<{\n label: string;\n}>;\n\nexport interface AttributeConfig {\n key: string | number;\n hashcode: string;\n content: ContentConfig;\n highlight: HighlightConfig;\n dot: DotConfig;\n bar: BarConfig;\n popover: PopoverConfig;\n event: EventConfig;\n dates: DateRangeSource[];\n customData: any;\n order: number;\n pinPage: boolean;\n}\n\nexport class Attribute {\n key: string | number = '';\n hashcode = '';\n highlight: Profile | null = null;\n content: Profile | null = null;\n dot: Profile | null = null;\n bar: Profile | null = null;\n event: EventConfig | null = null;\n popover: PopoverConfig | null = null;\n customData: any = null;\n ranges: DateRange[];\n hasRanges = false;\n order = 0;\n pinPage = false;\n maxRepeatSpan = 0;\n locale: Locale;\n\n constructor(config: Partial, theme: Theme, locale: Locale) {\n const { dates } = Object.assign(\n this,\n { hashcode: '', order: 0, pinPage: false },\n config,\n );\n if (!this.key) this.key = createGuid();\n this.locale = locale;\n // Normalize attribute\n theme.normalizeGlyphs(this);\n // Assign dates\n this.ranges = locale.ranges(dates ?? []);\n this.hasRanges = !!arrayHasItems(this.ranges);\n this.maxRepeatSpan = this.ranges\n .filter(r => r.hasRepeat)\n .map(r => r.daySpan)\n .reduce((res, curr) => Math.max(res, curr), 0);\n }\n\n intersectsRange({ start, end }: DateRange) {\n if (start == null || end == null) return false;\n const simpleRanges = this.ranges.filter(r => !r.hasRepeat);\n for (const range of simpleRanges) {\n if (range.intersectsDayRange(start.dayIndex, end.dayIndex)) {\n return true;\n }\n }\n const repeatRanges = this.ranges.filter(r => r.hasRepeat);\n if (!repeatRanges.length) return false;\n let day = start;\n if (this.maxRepeatSpan > 1) {\n day = this.locale.getDateParts(addDays(day.date, -this.maxRepeatSpan));\n }\n while (day.dayIndex <= end.dayIndex) {\n for (const range of repeatRanges) {\n if (range.startsOnDay(day)) return true;\n }\n day = this.locale.getDateParts(addDays(day.date, 1));\n }\n return false;\n }\n}\n","import {\n type PropType,\n type ExtractPropTypes,\n computed,\n provide,\n inject,\n} from 'vue';\nimport { type DarkModeClassConfig, useDarkMode } from 'vue-screen-utils';\nimport { Theme } from '../utils/theme';\nimport { getDefault } from '../utils/defaults';\nimport { type LocaleConfig, default as Locale } from '../utils/locale';\nimport { Attribute } from '../utils/attribute';\nimport { isObject } from '../utils/helpers';\nimport { type DayOfWeek, addDays } from '../utils/date/helpers';\n\nconst contextKey = '__vc_base_context__';\n\nexport const propsDef = {\n color: {\n type: String,\n default: () => getDefault('color'),\n },\n isDark: {\n type: [Boolean, String, Object] as PropType<\n boolean | 'system' | DarkModeClassConfig\n >,\n default: () => getDefault('isDark'),\n },\n firstDayOfWeek: Number as PropType,\n masks: Object,\n locale: [String, Object] as PropType | Locale>,\n timezone: String,\n minDate: null,\n maxDate: null,\n disabledDates: null,\n};\n\nexport type BaseProps = Readonly>;\n\nexport type BaseContext = ReturnType;\n\nexport function createBase(props: BaseProps) {\n // #region Computed\n\n const color = computed(() => props.color ?? '');\n const isDark = computed(() => props.isDark ?? false);\n const { displayMode } = useDarkMode(isDark);\n const theme = computed(() => new Theme(color.value));\n\n const locale = computed(() => {\n // Return the locale prop if it is an instance of the Locale class\n if (props.locale instanceof Locale) return props.locale;\n // Build up a base config from component props\n const config = (\n isObject(props.locale)\n ? props.locale\n : {\n id: props.locale,\n firstDayOfWeek: props.firstDayOfWeek,\n masks: props.masks,\n }\n ) as Partial;\n // Return new locale\n return new Locale(config, props.timezone);\n });\n\n const masks = computed(() => locale.value.masks);\n\n const disabledDates = computed(() => {\n const dates: any[] = props.disabledDates ?? [];\n // Add disabled range for min date\n if (props.minDate != null) {\n dates.push({\n start: null,\n end: addDays(locale.value.toDate(props.minDate), -1),\n });\n }\n // Add disabled range for max date\n if (props.maxDate != null) {\n dates.push({\n start: addDays(locale.value.toDate(props.maxDate), 1),\n end: null,\n });\n }\n return locale.value.ranges(dates);\n });\n\n const disabledAttribute = computed(() => {\n return new Attribute(\n {\n key: 'disabled',\n dates: disabledDates.value,\n order: 100,\n },\n theme.value,\n locale.value,\n );\n });\n\n // #endregion Computed\n\n const context = {\n color,\n isDark,\n displayMode,\n theme,\n locale,\n masks,\n disabledDates,\n disabledAttribute,\n };\n provide(contextKey, context);\n return context;\n}\n\nexport function useBase() {\n const context = inject(contextKey);\n if (context) return context;\n throw new Error(\n 'Base context missing. Please verify this component is nested within a valid context provider.',\n );\n}\n\nexport function useOrCreateBase(props: BaseProps) {\n return inject(contextKey, createBase(props));\n}\n","import { on, off, isFunction } from './helpers';\nimport type { CustomElement } from './helpers';\n\ninterface SwipeHandlerOptions {\n maxSwipeTime: number;\n minHorizontalSwipeDistance: number;\n maxVerticalSwipeDistance: number;\n}\n\nexport const addHorizontalSwipeHandler = (\n element: CustomElement,\n handler: Function,\n {\n maxSwipeTime,\n minHorizontalSwipeDistance,\n maxVerticalSwipeDistance,\n }: SwipeHandlerOptions,\n) => {\n if (!element || !element.addEventListener || !isFunction(handler)) {\n return null;\n }\n // State variables\n let startX = 0;\n let startY = 0;\n let startTime: number | null = null;\n let isSwiping = false;\n // Touch start handler\n function touchStart(e: TouchEvent) {\n const t = e.changedTouches[0];\n startX = t.screenX;\n startY = t.screenY;\n startTime = new Date().getTime();\n isSwiping = true;\n }\n // Touch end handler\n function touchEnd(e: TouchEvent) {\n if (!isSwiping || !startTime) return;\n isSwiping = false;\n const t = e.changedTouches[0];\n const deltaX = t.screenX - startX;\n const deltaY = t.screenY - startY;\n const deltaTime = new Date().getTime() - startTime;\n if (deltaTime < maxSwipeTime) {\n if (\n Math.abs(deltaX) >= minHorizontalSwipeDistance &&\n Math.abs(deltaY) <= maxVerticalSwipeDistance\n ) {\n const arg = { toLeft: false, toRight: false };\n if (deltaX < 0) {\n // Swipe to the left\n arg.toLeft = true;\n } else {\n // Swipe to the right\n arg.toRight = true;\n }\n handler(arg);\n }\n }\n }\n // Add event handlers\n on(element, 'touchstart', touchStart, { passive: true });\n // on(element, 'touchmove', touchmove);\n on(element, 'touchend', touchEnd, { passive: true });\n // Return function that removes event handlers\n return () => {\n off(element, 'touchstart', touchStart);\n // off(element, 'touchmove', touchmove);\n off(element, 'touchend', touchEnd);\n };\n};\n","const watchSkippers: Partial> = {};\n\nexport const skipWatcher = (watcher: string, durationMs = 10) => {\n watchSkippers[watcher] = Date.now() + durationMs;\n};\n\nexport const unskipWatcher = (watcher: string) => {\n delete watchSkippers[watcher];\n};\n\nexport const handleWatcher = (watcher: string, handler: Function) => {\n if (watcher in watchSkippers) {\n const dateTime = watchSkippers[watcher] as number;\n if (Date.now() < dateTime) return;\n delete watchSkippers[watcher];\n }\n handler();\n};\n","import {\n type PropType,\n type ExtractPropTypes,\n computed,\n ref,\n provide,\n onMounted,\n onUnmounted,\n watch,\n inject,\n watchEffect,\n} from 'vue';\nimport { propsDef as basePropsDef, useOrCreateBase } from './base';\nimport Popover from '../Popover/Popover.vue';\nimport { type AttributeConfig, Attribute } from '../utils/attribute';\nimport {\n type DateSource,\n addDays,\n addMonths,\n addYears,\n} from '../utils/date/helpers';\nimport { type DateRangeCell, DateRangeContext } from '../utils/date/range';\nimport { getDefault } from '../utils/defaults';\nimport {\n type CustomElement,\n createGuid,\n isBoolean,\n has,\n head,\n last,\n arrayHasItems,\n} from '../utils/helpers';\nimport {\n type CalendarDay,\n type CalendarWeek,\n type Page,\n type PageAddress,\n type TitlePosition,\n pageRangeToArray,\n pageIsValid,\n pageIsEqualToPage,\n pageIsBeforePage,\n pageIsAfterPage,\n pageIsBetweenPages,\n getPageAddressForDate,\n addPages as _addPages,\n} from '../utils/page';\nimport type { PopoverVisibility } from '../utils/popovers';\nimport { addHorizontalSwipeHandler } from '../utils/touch';\nimport { skipWatcher, handleWatcher } from '../utils/watchers';\n\nexport type CalendarView = 'daily' | 'weekly' | 'monthly';\n\nexport type MoveTarget = DateSource | PageAddress;\n\nexport type MoveTransition = 'none' | 'fade' | 'slide-v' | 'slide-h';\n\nexport interface MoveOptions {\n position: number;\n view: CalendarView;\n transition: MoveTransition;\n force: boolean;\n fromPage: PageAddress;\n toPage: PageAddress;\n}\n\nexport interface RefreshOptions {\n page: PageAddress;\n position: number;\n force: boolean;\n transition: MoveTransition;\n}\n\nexport type DayCells = Record<\n number,\n { day: CalendarDay; cells: DateRangeCell[] }\n>;\n\nexport type CalendarProps = Readonly>;\n\ntype IContainer = Pick & CustomElement;\n\nexport type CalendarContext = ReturnType;\n\nexport const propsDef = {\n ...basePropsDef,\n view: {\n type: String as PropType,\n default: 'monthly',\n validator(value: string) {\n return ['daily', 'weekly', 'monthly'].includes(value);\n },\n },\n rows: {\n type: Number,\n default: 1,\n },\n columns: {\n type: Number,\n default: 1,\n },\n step: Number,\n titlePosition: {\n type: String as PropType,\n default: () => getDefault('titlePosition') as TitlePosition,\n },\n navVisibility: {\n type: String as PropType,\n default: () => getDefault('navVisibility') as PopoverVisibility,\n },\n showWeeknumbers: [Boolean, String],\n showIsoWeeknumbers: [Boolean, String],\n expanded: Boolean,\n borderless: Boolean,\n transparent: Boolean,\n initialPage: Object as PropType,\n initialPagePosition: { type: Number, default: 1 },\n minPage: Object as PropType,\n maxPage: Object as PropType,\n transition: String as PropType,\n attributes: Array as PropType>,\n trimWeeks: Boolean,\n disablePageSwipe: Boolean,\n};\n\nexport const emitsDef = [\n 'dayclick',\n 'daymouseenter',\n 'daymouseleave',\n 'dayfocusin',\n 'dayfocusout',\n 'daykeydown',\n 'weeknumberclick',\n 'transition-start',\n 'transition-end',\n 'did-move',\n 'update:view',\n 'update:pages',\n];\n\nconst contextKey = '__vc_calendar_context__';\n\nexport function createCalendar(props: CalendarProps, { emit, slots }: any) {\n // Reactive refs\n const containerRef = ref(null);\n const navPopoverRef = ref(null);\n const focusedDay = ref(null);\n const focusableDay = ref(new Date().getDate());\n const inTransition = ref(false);\n const navPopoverId = ref(createGuid());\n const dayPopoverId = ref(createGuid());\n const _view = ref(props.view);\n const _pages = ref([]);\n const transitionName = ref('');\n\n // Non-reactive util vars\n let transitionPromise: any = null;\n let removeHandlers: any = null;\n\n // #region Computed\n\n const {\n theme,\n color,\n displayMode,\n locale,\n masks,\n disabledAttribute,\n disabledDates,\n } = useOrCreateBase(props);\n\n const count = computed(() => props.rows * props.columns);\n\n const step = computed(() => props.step || count.value);\n\n const firstPage = computed(() => head(_pages.value) ?? null);\n\n const lastPage = computed(() => last(_pages.value) ?? null);\n\n const minPage = computed(\n () =>\n props.minPage || (props.minDate ? getDateAddress(props.minDate) : null),\n );\n\n const maxPage = computed(\n () =>\n props.maxPage || (props.maxDate ? getDateAddress(props.maxDate) : null),\n );\n\n const navVisibility = computed(() => props.navVisibility);\n\n const showWeeknumbers = computed(() => !!props.showWeeknumbers);\n\n const showIsoWeeknumbers = computed(() => !!props.showIsoWeeknumbers);\n\n const isMonthly = computed(() => _view.value === 'monthly');\n const isWeekly = computed(() => _view.value === 'weekly');\n const isDaily = computed(() => _view.value === 'daily');\n\n // #endregion Computed\n\n // #region Methods\n\n const onTransitionBeforeEnter = () => {\n inTransition.value = true;\n emit('transition-start');\n };\n\n const onTransitionAfterEnter = () => {\n inTransition.value = false;\n emit('transition-end');\n if (transitionPromise) {\n transitionPromise.resolve(true);\n transitionPromise = null;\n }\n };\n\n const addPages = (\n address: PageAddress,\n count: number,\n view = _view.value,\n ) => {\n return _addPages(address, count, view, locale.value);\n };\n\n const getDateAddress = (date: DateSource) => {\n return getPageAddressForDate(date, _view.value, locale.value);\n };\n\n const refreshDisabled = (day: CalendarDay) => {\n if (!disabledAttribute.value || !attributeContext.value) return;\n day.isDisabled = attributeContext.value.cellExists(\n disabledAttribute.value.key,\n day.dayIndex,\n );\n };\n\n const refreshFocusable = (day: CalendarDay) => {\n day.isFocusable = day.inMonth && day.day === focusableDay.value;\n };\n\n const forDays = (pages: Page[], fn: (day: CalendarDay) => boolean | void) => {\n for (const page of pages) {\n for (const day of page.days) {\n if (fn(day) === false) return;\n }\n }\n };\n\n const days = computed(() =>\n _pages.value.reduce((result: CalendarDay[], page: Page) => {\n result.push(...page.viewDays);\n return result;\n }, []),\n );\n\n const attributes = computed(() => {\n const result: Attribute[] = [];\n (props.attributes || []).forEach((attr, i) => {\n if (!attr || !attr.dates) return;\n const key = has(attr, 'key') ? attr.key : i;\n const order = attr.order || 0;\n result.push(\n new Attribute(\n {\n ...attr,\n key,\n order,\n },\n theme.value,\n locale.value,\n ),\n );\n });\n if (disabledAttribute.value) {\n result.push(disabledAttribute.value);\n }\n return result;\n });\n\n const hasAttributes = computed(() => arrayHasItems(attributes.value));\n\n const attributeContext = computed(() => {\n const ctx = new DateRangeContext();\n attributes.value.forEach(attr => {\n attr.ranges.forEach(range => {\n ctx.render(attr, range, days.value);\n });\n });\n return ctx;\n });\n\n const dayCells = computed(() => {\n return days.value.reduce((result, day) => {\n result[day.dayIndex] = { day, cells: [] };\n result[day.dayIndex].cells.push(...attributeContext.value.getCells(day));\n return result;\n }, {} as DayCells);\n });\n\n const getWeeknumberPosition = (column: number, columnFromEnd: number) => {\n const showWeeknumbers = props.showWeeknumbers || props.showIsoWeeknumbers;\n if (showWeeknumbers == null) return '';\n if (isBoolean(showWeeknumbers)) {\n return showWeeknumbers ? 'left' : '';\n }\n if (showWeeknumbers.startsWith('right')) {\n return columnFromEnd > 1 ? 'right' : showWeeknumbers;\n }\n return column > 1 ? 'left' : showWeeknumbers;\n };\n\n const getPageForAttributes = () => {\n if (!hasAttributes.value) return null;\n const attr =\n attributes.value.find(attr => attr.pinPage) || attributes.value[0];\n if (!attr || !attr.hasRanges) return null;\n const [range] = attr.ranges;\n const date = range.start?.date || range.end?.date;\n return date ? getDateAddress(date) : null;\n };\n\n const getDefaultInitialPage = () => {\n // 1. Try existing first page\n if (pageIsValid(firstPage.value)) return firstPage.value as PageAddress;\n // 2. Try the first attribute\n const page = getPageForAttributes();\n if (pageIsValid(page)) return page as PageAddress;\n // 3. Use today's page\n return getDateAddress(new Date());\n };\n\n const getTargetPageRange = (\n page: PageAddress,\n opts: Partial = {},\n ) => {\n const { view = _view.value, position = 1, force } = opts;\n const pagesToAdd = position > 0 ? 1 - position : -(count.value + position);\n let fromPage = addPages(page, pagesToAdd, view);\n let toPage = addPages(fromPage!, count.value - 1, view);\n\n // Adjust range for min/max if not forced\n if (!force) {\n if (pageIsBeforePage(fromPage, minPage.value)) {\n fromPage = minPage.value!;\n } else if (pageIsAfterPage(toPage, maxPage.value)) {\n fromPage = addPages(maxPage.value!, 1 - count.value);\n }\n toPage = addPages(fromPage!, count.value - 1);\n }\n return { fromPage, toPage };\n };\n\n const getPageTransition = (\n oldPage: Page,\n newPage: Page,\n defaultTransition = '',\n ) => {\n if (defaultTransition === 'none' || defaultTransition === 'fade')\n return defaultTransition;\n // Moving to a different view\n if (oldPage?.view !== newPage?.view) return 'fade';\n // Moving to a previous page\n const moveNext = pageIsAfterPage(newPage, oldPage);\n const movePrev = pageIsBeforePage(newPage, oldPage);\n if (!moveNext && !movePrev) {\n return 'fade';\n }\n // Vertical slide\n if (defaultTransition === 'slide-v') {\n return movePrev ? 'slide-down' : 'slide-up';\n }\n // Horizontal slide\n return movePrev ? 'slide-right' : 'slide-left';\n };\n\n const refreshPages = (opts: Partial = {}) => {\n return new Promise((resolve, reject) => {\n const { position = 1, force = false, transition } = opts;\n const page = pageIsValid(opts.page)\n ? opts.page!\n : getDefaultInitialPage();\n const { fromPage } = getTargetPageRange(page, {\n position,\n force,\n });\n // Create the new pages\n const pages: Page[] = [];\n for (let i = 0; i < count.value; i++) {\n const newPage = addPages(fromPage!, i);\n const position = i + 1;\n const row = Math.ceil(position / props.columns);\n const rowFromEnd = props.rows - row + 1;\n const column = position % props.columns || props.columns;\n const columnFromEnd = props.columns - column + 1;\n const weeknumberPosition = getWeeknumberPosition(column, columnFromEnd);\n pages.push(\n locale.value.getPage({\n ...newPage,\n view: _view.value,\n titlePosition: props.titlePosition,\n trimWeeks: props.trimWeeks,\n position,\n row,\n rowFromEnd,\n column,\n columnFromEnd,\n showWeeknumbers: showWeeknumbers.value,\n showIsoWeeknumbers: showIsoWeeknumbers.value,\n weeknumberPosition,\n }),\n );\n }\n // Assign the transition\n transitionName.value = getPageTransition(\n _pages.value[0],\n pages[0],\n transition,\n );\n // Assign the new pages\n _pages.value = pages;\n // Cache or resolve transition promise\n if (transitionName.value && transitionName.value !== 'none') {\n transitionPromise = {\n resolve,\n reject,\n };\n } else {\n resolve(true);\n }\n });\n };\n\n const targetBy = (pages: number) => {\n const fromPage = firstPage.value ?? getDateAddress(new Date());\n return addPages(fromPage, pages);\n };\n\n const canMove = (target: MoveTarget, opts: Partial = {}) => {\n const page = pageIsValid(target as PageAddress)\n ? (target as Page)\n : getDateAddress(target as DateSource);\n // Calculate new page range without adjusting to min/max\n Object.assign(\n opts,\n getTargetPageRange(page, {\n ...opts,\n force: true,\n }),\n );\n // Verify we can move to any pages in the target range\n const pagesInRange = pageRangeToArray(\n opts.fromPage!,\n opts.toPage!,\n _view.value,\n locale.value,\n ).map(p => pageIsBetweenPages(p, minPage.value, maxPage.value));\n return pagesInRange.every(val => val);\n };\n\n const canMoveBy = (pages: number, opts: Partial = {}) => {\n return canMove(targetBy(pages), opts);\n };\n\n const canMovePrev = computed(() => canMoveBy(-step.value));\n\n const canMoveNext = computed(() => canMoveBy(step.value));\n\n const move = async (target: MoveTarget, opts: Partial = {}) => {\n // Return if we can't move to this page\n if (!opts.force && !canMove(target, opts)) return false;\n // Move to new `fromPage` if it's different from the current one\n if (opts.fromPage && !pageIsEqualToPage(opts.fromPage, firstPage.value)) {\n // Hide nav popover for good measure\n if (navPopoverRef.value) {\n navPopoverRef.value.hide({ hideDelay: 0 });\n }\n // Quietly change view if needed\n if (opts.view) {\n skipWatcher('view', 10);\n _view.value = opts.view;\n }\n await refreshPages({\n ...opts,\n page: opts.fromPage,\n position: 1,\n force: true,\n });\n emit('did-move', _pages.value);\n }\n return true;\n };\n\n const moveBy = (pages: number, opts: Partial = {}) => {\n return move(targetBy(pages), opts);\n };\n\n const movePrev = () => {\n return moveBy(-step.value);\n };\n\n const moveNext = () => {\n return moveBy(step.value);\n };\n\n const tryFocusDate = (date: Date) => {\n const inMonth = isMonthly.value ? '.in-month' : '';\n const daySelector = `.id-${locale.value.getDayId(date)}${inMonth}`;\n const selector = `${daySelector}.vc-focusable, ${daySelector} .vc-focusable`;\n const el = containerRef.value;\n if (el) {\n const focusableEl = el.querySelector(selector) as HTMLElement;\n if (focusableEl) {\n focusableEl.focus();\n return true;\n }\n }\n return false;\n };\n\n const focusDate = async (date: Date, opts: Partial = {}) => {\n if (tryFocusDate(date)) return true;\n // Move to the given date\n await move(date, opts);\n return tryFocusDate(date);\n };\n\n const onDayClick = (day: CalendarDay, event: MouseEvent) => {\n focusableDay.value = day.day;\n emit('dayclick', day, event);\n };\n\n const onDayMouseenter = (day: CalendarDay, event: MouseEvent) => {\n emit('daymouseenter', day, event);\n };\n\n const onDayMouseleave = (day: CalendarDay, event: MouseEvent) => {\n emit('daymouseleave', day, event);\n };\n\n const onDayFocusin = (day: CalendarDay, event: FocusEvent | null) => {\n focusableDay.value = day.day;\n focusedDay.value = day;\n day.isFocused = true;\n emit('dayfocusin', day, event);\n };\n\n const onDayFocusout = (day: CalendarDay, event: FocusEvent) => {\n focusedDay.value = null;\n day.isFocused = false;\n emit('dayfocusout', day, event);\n };\n\n const onDayKeydown = (day: CalendarDay, event: KeyboardEvent) => {\n emit('daykeydown', day, event);\n const date = day.noonDate;\n let newDate = null;\n switch (event.key) {\n case 'ArrowLeft': {\n // Move to previous day\n newDate = addDays(date, -1);\n break;\n }\n case 'ArrowRight': {\n // Move to next day\n newDate = addDays(date, 1);\n break;\n }\n case 'ArrowUp': {\n // Move to previous week\n newDate = addDays(date, -7);\n break;\n }\n case 'ArrowDown': {\n // Move to next week\n newDate = addDays(date, 7);\n break;\n }\n case 'Home': {\n // Move to first weekday position\n newDate = addDays(date, -day.weekdayPosition + 1);\n break;\n }\n case 'End': {\n // Move to last weekday position\n newDate = addDays(date, day.weekdayPositionFromEnd);\n break;\n }\n case 'PageUp': {\n if (event.altKey) {\n // Move to previous year w/ Alt/Option key\n newDate = addYears(date, -1);\n } else {\n // Move to previous month\n newDate = addMonths(date, -1);\n }\n break;\n }\n case 'PageDown': {\n if (event.altKey) {\n // Move to next year w/ Alt/Option key\n newDate = addYears(date, 1);\n } else {\n // Move to next month\n newDate = addMonths(date, 1);\n }\n break;\n }\n }\n if (newDate) {\n event.preventDefault();\n focusDate(newDate).catch();\n }\n };\n\n const onKeydown = (event: KeyboardEvent) => {\n const day = focusedDay.value;\n if (day != null) {\n onDayKeydown(day, event);\n }\n };\n\n const onWeeknumberClick = (week: CalendarWeek, event: MouseEvent) => {\n emit('weeknumberclick', week, event);\n };\n\n // #endregion Methods\n\n // #region Lifecycle methods\n\n // Created\n refreshPages({\n page: props.initialPage,\n position: props.initialPagePosition,\n });\n\n // Mounted\n onMounted(() => {\n if (!props.disablePageSwipe && containerRef.value) {\n // Add swipe handler to move to next and previous pages\n removeHandlers = addHorizontalSwipeHandler(\n containerRef.value,\n ({ toLeft = false, toRight = false }) => {\n if (toLeft) {\n moveNext();\n } else if (toRight) {\n movePrev();\n }\n },\n getDefault('touch'),\n );\n }\n });\n\n // Unmounted\n onUnmounted(() => {\n _pages.value = [];\n if (removeHandlers) removeHandlers();\n });\n\n // #endregion Lifecycle methods\n\n // #region Watch\n\n watch(\n () => locale.value,\n () => {\n refreshPages();\n },\n );\n\n watch(\n () => count.value,\n () => refreshPages(),\n );\n\n watch(\n () => props.view,\n () => (_view.value = props.view),\n );\n\n watch(\n () => _view.value,\n () => {\n handleWatcher('view', () => {\n refreshPages();\n });\n emit('update:view', _view.value);\n },\n );\n\n watch(\n () => focusableDay.value,\n () => {\n forDays(_pages.value, day => refreshFocusable(day));\n },\n );\n\n watchEffect(() => {\n emit('update:pages', _pages.value);\n // Refresh state for days\n forDays(_pages.value, day => {\n // Refresh disabled state\n refreshDisabled(day);\n // Refresh focusable state\n refreshFocusable(day);\n });\n });\n\n // #endregion Watch\n\n const context = {\n emit,\n slots,\n containerRef,\n navPopoverRef,\n focusedDay,\n inTransition,\n navPopoverId,\n dayPopoverId,\n view: _view,\n pages: _pages,\n transitionName,\n theme,\n color,\n displayMode,\n locale,\n masks,\n attributes,\n disabledAttribute,\n disabledDates,\n attributeContext,\n days,\n dayCells,\n count,\n step,\n firstPage,\n lastPage,\n canMovePrev,\n canMoveNext,\n minPage,\n maxPage,\n isMonthly,\n isWeekly,\n isDaily,\n navVisibility,\n showWeeknumbers,\n showIsoWeeknumbers,\n getDateAddress,\n canMove,\n canMoveBy,\n move,\n moveBy,\n movePrev,\n moveNext,\n onTransitionBeforeEnter,\n onTransitionAfterEnter,\n tryFocusDate,\n focusDate,\n onKeydown,\n onDayKeydown,\n onDayClick,\n onDayMouseenter,\n onDayMouseleave,\n onDayFocusin,\n onDayFocusout,\n onWeeknumberClick,\n };\n provide(contextKey, context);\n return context;\n}\n\nexport function useCalendar(): CalendarContext {\n const context = inject(contextKey);\n if (context) return context;\n throw new Error(\n 'Calendar context missing. Please verify this component is nested within a valid context provider.',\n );\n}\n","\n \n \n\n\n\n\n\n","import type { ComponentPublicInstance, Directive, DirectiveBinding } from 'vue';\nimport type { Placement } from '@popperjs/core';\nimport { elementContains, on, resolveEl } from './helpers';\n\nexport type PopoverVisibility = 'click' | 'hover' | 'hover-focus' | 'focus';\n\nexport interface PopoverOptions {\n id: string;\n visibility: PopoverVisibility;\n isInteractive: boolean;\n autoHide: boolean;\n force: boolean;\n target: unknown;\n placement: Placement;\n modifiers: any;\n data: any;\n showDelay: number;\n hideDelay: number;\n}\n\nexport interface PopoverState {\n isVisible: boolean;\n target: unknown;\n data: any;\n transition: string;\n placement: Placement;\n direction: string;\n positionFixed: false;\n modifiers: any[];\n isInteractive: boolean;\n visibility: PopoverVisibility;\n isHovered: boolean;\n isFocused: boolean;\n autoHide: boolean;\n force: boolean;\n}\n\nexport interface PopoverEvent {\n detail: Partial;\n}\n\nexport interface PopoverEventHandlers {\n click: (e: MouseEvent) => void;\n mousemove: (e: MouseEvent) => void;\n mouseleave: (e: MouseEvent) => void;\n focusin: (e: MouseEvent) => void;\n focusout: (e: MouseEvent) => void;\n}\n\nexport function showPopover(opts: Partial) {\n if (document) {\n document.dispatchEvent(\n new CustomEvent('show-popover', {\n detail: opts,\n }),\n );\n }\n}\n\nexport function hidePopover(opts: Partial) {\n if (document) {\n document.dispatchEvent(\n new CustomEvent('hide-popover', {\n detail: opts,\n }),\n );\n }\n}\n\nexport function togglePopover(opts: Partial) {\n if (document) {\n document.dispatchEvent(\n new CustomEvent('toggle-popover', {\n detail: opts,\n }),\n );\n }\n}\n\nexport function getPopoverEventHandlers(\n opts: Partial,\n): Partial {\n const { visibility } = opts;\n const click = visibility === 'click';\n const hover = visibility === 'hover';\n const hoverFocus = visibility === 'hover-focus';\n const focus = visibility === 'focus';\n opts.autoHide = !click;\n let hovered = false;\n let focused = false;\n\n const clickHandler = (e: MouseEvent) => {\n if (click) {\n togglePopover({\n ...opts,\n target: opts.target || (e.currentTarget as HTMLElement),\n });\n e.stopPropagation();\n }\n };\n const mouseMoveHandler = (e: MouseEvent) => {\n if (!hovered) {\n hovered = true;\n if (hover || hoverFocus) {\n showPopover({\n ...opts,\n target: opts.target || (e.currentTarget as HTMLElement),\n });\n }\n }\n };\n const mouseLeaveHandler = () => {\n if (hovered) {\n hovered = false;\n if (hover || (hoverFocus && !focused)) {\n hidePopover(opts);\n }\n }\n };\n const focusInHandler = (e: FocusEvent) => {\n if (!focused) {\n focused = true;\n if (focus || hoverFocus) {\n showPopover({\n ...opts,\n target: opts.target || (e.currentTarget as HTMLElement),\n });\n }\n }\n };\n const focusOutHandler = (e: FocusEvent) => {\n if (\n focused &&\n !elementContains(e.currentTarget as Node, e.relatedTarget as Element)\n ) {\n focused = false;\n if (focus || (hoverFocus && !hovered)) {\n hidePopover(opts);\n }\n }\n };\n\n const handlers: Record = {};\n switch (opts.visibility) {\n case 'click':\n handlers.click = clickHandler;\n break;\n case 'hover':\n handlers.mousemove = mouseMoveHandler;\n handlers.mouseleave = mouseLeaveHandler;\n break;\n case 'focus':\n handlers.focusin = focusInHandler;\n handlers.focusout = focusOutHandler;\n break;\n case 'hover-focus':\n handlers.mousemove = mouseMoveHandler;\n handlers.mouseleave = mouseLeaveHandler;\n handlers.focusin = focusInHandler;\n handlers.focusout = focusOutHandler;\n break;\n }\n return handlers;\n}\n\nconst removeHandlers = (target: Element | ComponentPublicInstance | string) => {\n const el = resolveEl(target);\n if (el == null) return;\n const handlers = (el as any).popoverHandlers;\n if (!handlers || !handlers.length) return;\n handlers.forEach((handler: Function) => handler());\n delete (el as any).popoverHandlers;\n};\n\nconst addHandlers = (\n target: Element | ComponentPublicInstance | string,\n opts: Partial,\n) => {\n const el = resolveEl(target);\n if (el == null) return;\n const remove: Function[] = [];\n const handlers = getPopoverEventHandlers(opts);\n Object.entries(handlers).forEach(([event, handler]) => {\n remove.push(on(el, event, handler as EventListener));\n });\n (el as any).popoverHandlers = remove;\n};\n\nexport const popoverDirective: Directive = {\n mounted(el: any, binding: DirectiveBinding) {\n const { value } = binding;\n if (!value) return;\n addHandlers(el, value);\n },\n updated(el: any, binding: DirectiveBinding) {\n const { oldValue, value } = binding;\n const oldVisibility = oldValue?.visibility;\n const newVisibility = value?.visibility;\n if (oldVisibility !== newVisibility) {\n if (oldVisibility) {\n removeHandlers(el);\n if (!newVisibility) hidePopover(oldValue);\n }\n if (newVisibility) {\n addHandlers(el, value);\n }\n }\n },\n unmounted(el: Element) {\n removeHandlers(el);\n },\n};\n","\n \n\n\n\n\n\n","\n \n \n
\n \n
\n \n {{ day.label }}\n
\n \n \n
\n \n
\n
\n\n\n\n\n\n","\n \n
\n
\n
\n \n
\n {{ label }}\n
\n
\n \n
\n \n
\n {{ week.weeknumberDisplay }}\n
\n \n
\n
\n
\n
\n\n\n\n\n\n","\n \n
\n \n \n {{ data }}\n \n \n
\n \n
\n\n\n\n\n\n","import {\n type ExtractPropTypes,\n type PropType,\n ref,\n computed,\n watch,\n onMounted,\n provide,\n inject,\n} from 'vue';\nimport { useCalendar } from './calendar';\nimport type { Page } from '../utils/page';\nimport { getMonthDates } from '../utils/date/helpers';\nimport { head, last, pad } from '../utils/helpers';\n\nexport interface YearItem {\n year: number;\n id: string;\n label: string;\n ariaLabel: string;\n isActive: boolean;\n isCurrent: boolean;\n isDisabled: boolean;\n click: () => void;\n}\n\nexport interface MonthItem extends YearItem {\n month: number;\n}\n\nexport type IQuerySelector = Pick;\n\nexport type CalendarNavContext = ReturnType;\n\nexport type CalendarNavProps = Readonly>;\n\nexport const propsDef = {\n value: { type: Object as PropType, required: true },\n};\n\nexport const emitsDef = ['input'];\n\nconst contextKey = '__vc_calendar_nav_context__';\n\nexport function createCalendarNav(props: CalendarNavProps, { emit }: any) {\n const monthMode = ref(true);\n const yearIndex = ref(0);\n const yearGroupIndex = ref(0);\n const yearGroupCount = 12;\n const navContainer = ref(null);\n\n const { locale, masks, canMove, getDateAddress } = useCalendar();\n\n function focusFirstItem() {\n // Use setTimeout instead of $nextTick so it plays nice with popperjs\n setTimeout(() => {\n if (navContainer.value == null) return;\n // Set focus on the first enabled nav item\n const focusableEl = navContainer.value.querySelector(\n '.vc-nav-item:not(:disabled)',\n ) as HTMLElement;\n if (focusableEl) {\n focusableEl.focus();\n }\n }, 10);\n }\n\n function monthClick(month: number, year: number) {\n emit('input', { month, year }, { position: currentPosition.value });\n }\n\n function yearClick(year: number) {\n yearIndex.value = year;\n monthMode.value = true;\n focusFirstItem();\n }\n\n function getYearItems(yearGroupIndex: number): YearItem[] {\n const { year: thisYear } = getDateAddress(new Date());\n const startYear = yearGroupIndex * yearGroupCount;\n const endYear = startYear + yearGroupCount;\n const items = [];\n for (let year = startYear; year < endYear; year += 1) {\n let enabled = false;\n for (let month = 1; month < 12; month++) {\n enabled = canMove({ month, year }, { position: currentPosition.value });\n if (enabled) break;\n }\n items.push({\n year,\n id: year.toString(),\n label: year.toString(),\n ariaLabel: year.toString(),\n isActive: year === currentYear.value,\n isCurrent: year === thisYear,\n isDisabled: !enabled,\n click: () => yearClick(year),\n });\n }\n return items;\n }\n\n function getMonthItems(year: number): MonthItem[] {\n const { month: thisMonth, year: thisYear } = getDateAddress(new Date());\n return getMonthDates().map((d, i: number) => {\n const month = i + 1;\n return {\n month,\n year,\n id: `${year}.${pad(month, 2)}`,\n label: locale.value.formatDate(d, masks.value.navMonths),\n ariaLabel: locale.value.formatDate(d, 'MMMM YYYY'),\n isActive: month === currentMonth.value && year === currentYear.value,\n isCurrent: month === thisMonth && year === thisYear,\n isDisabled: !canMove(\n { month, year },\n { position: currentPosition.value },\n ),\n click: () => monthClick(month, year),\n };\n });\n }\n\n function getYearGroupIndex(year: number) {\n return Math.floor(year / yearGroupCount);\n }\n\n function toggleMode() {\n monthMode.value = !monthMode.value;\n }\n\n // #region Move methods\n\n function movePrev() {\n if (!prevItemsEnabled.value) return;\n if (monthMode.value) {\n movePrevYear();\n }\n movePrevYearGroup();\n }\n\n function moveNext() {\n if (!nextItemsEnabled.value) return;\n if (monthMode.value) {\n moveNextYear();\n }\n moveNextYearGroup();\n }\n\n function movePrevYear() {\n yearIndex.value--;\n }\n\n function moveNextYear() {\n yearIndex.value++;\n }\n\n function movePrevYearGroup() {\n yearGroupIndex.value--;\n }\n\n function moveNextYearGroup() {\n yearGroupIndex.value++;\n }\n\n // #endregion Move methods\n\n const currentMonth = computed(() => props.value?.month || 0);\n\n const currentYear = computed(() => props.value?.year || 0);\n\n const currentPosition = computed(() => props.value?.position || 1);\n\n const monthItems = computed(() => getMonthItems(yearIndex.value));\n\n const yearItems = computed(() => getYearItems(yearGroupIndex.value));\n\n const firstYear = computed(() => head(yearItems.value.map(i => i.year)));\n\n const lastYear = computed(() => last(yearItems.value.map(i => i.year)));\n\n const title = computed(() => {\n return monthMode.value\n ? yearIndex.value\n : `${firstYear.value} - ${lastYear.value}`;\n });\n\n const prevMonthItemsEnabled = computed(() =>\n getMonthItems(yearIndex.value - 1).some(i => !i.isDisabled),\n );\n\n const prevYearItemsEnabled = computed(() =>\n getYearItems(yearGroupIndex.value - 1).some(i => !i.isDisabled),\n );\n\n const prevItemsEnabled = computed(() =>\n monthMode.value ? prevMonthItemsEnabled.value : prevYearItemsEnabled.value,\n );\n\n const nextMonthItemsEnabled = computed(() =>\n getMonthItems(yearIndex.value + 1).some(i => !i.isDisabled),\n );\n\n const nextYearItemsEnabled = computed(() =>\n getYearItems(yearGroupIndex.value + 1).some(i => !i.isDisabled),\n );\n\n const nextItemsEnabled = computed(() =>\n monthMode.value ? nextMonthItemsEnabled.value : nextYearItemsEnabled.value,\n );\n\n const activeItems = computed(() =>\n monthMode.value ? monthItems.value : yearItems.value,\n );\n\n watch(\n () => currentYear.value,\n () => {\n yearIndex.value = currentYear.value;\n },\n );\n\n watch(\n () => yearIndex.value,\n val => {\n yearGroupIndex.value = getYearGroupIndex(val);\n },\n );\n\n yearIndex.value = currentYear.value;\n\n onMounted(() => focusFirstItem());\n\n const context = {\n navContainer,\n title,\n monthMode,\n currentMonth,\n currentYear,\n activeItems,\n prevItemsEnabled,\n nextItemsEnabled,\n toggleMode,\n movePrev,\n moveNext,\n movePrevYear,\n moveNextYear,\n movePrevYearGroup,\n moveNextYearGroup,\n };\n provide(contextKey, context);\n return context;\n}\n\nexport function useCalendarNav(): CalendarNavContext {\n const context = inject(contextKey);\n if (context) return context;\n throw new Error(\n 'CalendarNav context missing. Please verify this component is nested within a valid context provider.',\n );\n}\n","\n \n \n \n \n \n
\n \n
\n
\n\n\n\n\n\n","\n \n \n \n \n \n\n\n\n","\n \n \n \n
\n \n
\n \n
\n {{\n attribute.popover ? attribute.popover.label : 'No content provided'\n }}\n
\n
\n\n\n\n\n\n","\n \n \n \n \n \n \n \n\n\n\n","\n \n \n
\n \n
\n \n \n \n \n
\n \n
\n
\n
\n \n \n \n \n\n\n\n\n\n","\n \n \n \n
\n\n\n\n\n\n\n\n","import {\n type SetupContext,\n type ExtractPropTypes,\n type PropType,\n ref,\n computed,\n watch,\n onMounted,\n nextTick,\n toRef,\n inject,\n provide,\n} from 'vue';\nimport Calendar from '../components/Calendar.vue';\nimport Popover from '../components/Popover.vue';\nimport { getDefault } from '../utils/defaults';\nimport type { AttributeConfig } from '../utils/attribute';\nimport {\n type CalendarDay,\n getPageAddressForDate,\n pageIsBetweenPages,\n} from '../utils/page';\nimport {\n isNumber,\n isString,\n isObject,\n isArray,\n isDate,\n defaultsDeep,\n createGuid,\n} from '../utils/helpers';\nimport type {\n DatePatch,\n DateParts,\n DatePartsRules,\n} from '../utils/date/helpers';\nimport type { SimpleDateRange } from '../utils/date/range';\nimport {\n type PopoverOptions,\n showPopover as sp,\n hidePopover as hp,\n togglePopover as tp,\n getPopoverEventHandlers,\n} from '../utils/popovers';\nimport { propsDef as basePropsDef, createBase } from './base';\nimport type { MoveTarget, MoveOptions } from './calendar';\n\nexport type DateType = 'date' | 'string' | 'number';\n\nexport interface DateConfig {\n type: DateType;\n rules: DatePartsRules;\n mask?: string;\n}\n\nconst contextKey = '__vc_date_picker_context__';\n\nexport type DateModes = 'date' | 'datetime' | 'time';\n\nexport type ValueTarget = 'start' | 'end';\n\nexport interface UpdateOptions {\n config: any;\n patch: DatePatch;\n debounce: number;\n clearIfEqual: boolean;\n formatInput: boolean;\n hidePopover: boolean;\n dragging: boolean;\n targetPriority: ValueTarget;\n moveToValue: boolean;\n}\n\nexport interface ModelModifiers {\n number?: boolean;\n string?: boolean;\n range?: boolean;\n}\n\nexport type DatePickerDate = number | string | Date | null;\nexport type DatePickerRangeArray = [DatePickerDate, DatePickerDate];\nexport type DatePickerRangeObject = Partial<{\n start: DatePickerDate;\n end: DatePickerDate;\n}>;\n\nexport type DatePickerContext = ReturnType;\n\nexport type DatePickerProps = Readonly>;\n\nexport const propsDef = {\n ...basePropsDef,\n mode: { type: String, default: 'date' },\n modelValue: {\n type: [Number, String, Date, Object] as PropType<\n number | string | Date | DatePickerRangeObject | null\n >,\n },\n modelModifiers: {\n type: Object as PropType,\n default: () => ({}),\n },\n rules: [String, Object] as PropType<'auto' | DatePartsRules>,\n is24hr: Boolean,\n hideTimeHeader: Boolean,\n timeAccuracy: { type: Number, default: 2 },\n isRequired: Boolean,\n isRange: Boolean,\n updateOnInput: {\n type: Boolean,\n default: () => getDefault('datePicker.updateOnInput'),\n },\n inputDebounce: {\n type: Number,\n default: () => getDefault('datePicker.inputDebounce'),\n },\n popover: {\n type: [Boolean, Object] as PropType>,\n default: true,\n },\n dragAttribute: Object as PropType,\n selectAttribute: Object as PropType,\n attributes: [Object, Array],\n};\n\nexport const emits = [\n 'update:modelValue',\n 'drag',\n 'dayclick',\n 'daykeydown',\n 'popover-will-show',\n 'popover-did-show',\n 'popover-will-hide',\n 'popover-did-hide',\n];\n\nexport function createDatePicker(\n props: DatePickerProps,\n ctx: SetupContext,\n) {\n const baseCtx = createBase(props);\n const { locale, masks, disabledAttribute } = baseCtx;\n const { emit } = ctx;\n\n const showCalendar = ref(false);\n const datePickerPopoverId = ref(createGuid());\n const dateValue = ref(null);\n const dragValue = ref(null);\n const inputValues = ref(['', '']);\n const popoverRef = ref | null>(null);\n const calendarRef = ref | null>(null);\n\n let updateTimeout: undefined | number = undefined;\n let dragTrackingValue: null | SimpleDateRange;\n let watchValue = true;\n\n // #region Computed\n\n const isRange = computed(() => {\n return props.isRange || props.modelModifiers.range === true;\n });\n\n const valueStart = computed(() =>\n isRange.value && dateValue.value != null\n ? (dateValue.value as SimpleDateRange).start\n : null,\n );\n\n const valueEnd = computed(() =>\n isRange.value && dateValue.value != null\n ? (dateValue.value as SimpleDateRange).end\n : null,\n );\n\n const isDateMode = computed(() => props.mode.toLowerCase() === 'date');\n const isDateTimeMode = computed(\n () => props.mode.toLowerCase() === 'datetime',\n );\n const isTimeMode = computed(() => props.mode.toLowerCase() === 'time');\n\n const isDragging = computed(() => !!dragValue.value);\n\n const modelConfig = computed(() => {\n let type: DateType = 'date';\n if (props.modelModifiers.number) type = 'number';\n if (props.modelModifiers.string) type = 'string';\n const mask = masks.value.modelValue || 'iso';\n return normalizeConfig({ type, mask });\n });\n\n const dateParts = computed(() =>\n getDateParts(dragValue.value ?? dateValue.value),\n );\n\n const inputMask = computed(() => {\n if (isTimeMode.value) {\n return props.is24hr ? masks.value.inputTime24hr : masks.value.inputTime;\n }\n if (isDateTimeMode.value) {\n return props.is24hr\n ? masks.value.inputDateTime24hr\n : masks.value.inputDateTime;\n }\n return masks.value.input;\n });\n\n const inputMaskHasTime = computed(() => /[Hh]/g.test(inputMask.value));\n\n const inputMaskHasDate = computed(() =>\n /[dD]{1,2}|Do|W{1,4}|M{1,4}|YY(?:YY)?/g.test(inputMask.value),\n );\n\n const inputMaskPatch = computed(() => {\n if (inputMaskHasTime.value && inputMaskHasDate.value) {\n return 'dateTime';\n }\n if (inputMaskHasDate.value) return 'date';\n if (inputMaskHasTime.value) return 'time';\n return undefined;\n });\n\n const popover = computed(() => {\n const target = popoverRef.value?.$el.previousElementSibling ?? undefined;\n return defaultsDeep({}, props.popover, getDefault('datePicker.popover'), {\n target,\n }) as Partial;\n });\n\n const popoverEvents = computed(() =>\n getPopoverEventHandlers({\n ...popover.value,\n id: datePickerPopoverId.value,\n }),\n );\n\n const inputValue = computed(() => {\n return isRange.value\n ? {\n start: inputValues.value[0],\n end: inputValues.value[1],\n }\n : inputValues.value[0];\n });\n\n const inputEvents = computed(() => {\n const events = (['start', 'end'] as const).map(target => ({\n input: onInputInput(target),\n change: onInputChange(target),\n keyup: onInputKeyup,\n ...(props.popover && popoverEvents.value),\n }));\n return isRange.value\n ? {\n start: events[0],\n end: events[1],\n }\n : events[0];\n });\n\n const selectAttribute = computed(() => {\n if (!hasValue(dateValue.value)) return null;\n const attribute = {\n key: 'select-drag',\n ...props.selectAttribute,\n dates: dateValue.value,\n pinPage: true,\n };\n const { dot, bar, highlight, content } = attribute;\n if (!dot && !bar && !highlight && !content) {\n attribute.highlight = true;\n }\n return attribute;\n });\n\n const dragAttribute = computed(() => {\n if (!isRange.value || !hasValue(dragValue.value)) {\n return null;\n }\n const attribute = {\n key: 'select-drag',\n ...props.dragAttribute,\n dates: dragValue.value,\n };\n const { dot, bar, highlight, content } = attribute;\n if (!dot && !bar && !highlight && !content) {\n attribute.highlight = {\n startEnd: {\n fillMode: 'outline',\n },\n };\n }\n return attribute;\n });\n\n const attributes = computed(() => {\n const attrs = isArray(props.attributes) ? [...props.attributes] : [];\n if (dragAttribute.value) {\n attrs.unshift(dragAttribute.value);\n } else if (selectAttribute.value) {\n attrs.unshift(selectAttribute.value);\n }\n return attrs;\n });\n\n const rules = computed(() => {\n return normalizeConfig(\n props.rules === 'auto' ? getAutoRules() : props.rules ?? {},\n );\n });\n\n // #endregion Computed\n\n function getAutoRules() {\n const _rules = {\n ms: [0, 999],\n sec: [0, 59],\n min: [0, 59],\n hr: [0, 23],\n };\n const accuracy = isDateMode.value ? 0 : props.timeAccuracy;\n return [0, 1].map(i => {\n switch (accuracy) {\n case 0:\n return {\n hours: _rules.hr[i],\n minutes: _rules.min[i],\n seconds: _rules.sec[i],\n milliseconds: _rules.ms[i],\n };\n case 1:\n return {\n minutes: _rules.min[i],\n seconds: _rules.sec[i],\n milliseconds: _rules.ms[i],\n };\n case 3:\n return { milliseconds: _rules.ms[i] };\n case 4:\n return {};\n default:\n return { seconds: _rules.sec[i], milliseconds: _rules.ms[i] };\n }\n });\n }\n\n function normalizeConfig(config: T | T[]): T[] {\n if (isArray(config)) {\n if (config.length === 1) return [config[0], config[0]];\n return config;\n }\n return [config, config];\n }\n\n function normalizeDateConfig(\n config: Partial | Partial[],\n ): DateConfig[] {\n return normalizeConfig(config).map(\n (c, i) =>\n ({\n ...c,\n rules: rules.value[i],\n } as DateConfig),\n );\n }\n\n function hasDateValue(value: unknown) {\n if (isNumber(value)) return !isNaN(value);\n if (isDate(value)) return !isNaN(value.getTime());\n if (isString(value)) return value !== '';\n return value != null;\n }\n\n function hasValue(value: any) {\n if (isRange.value) {\n return (\n isObject(value) && hasDateValue(value.start) && hasDateValue(value.end)\n );\n }\n return hasDateValue(value);\n }\n\n function datesAreEqual(a: any, b: any): boolean {\n const aIsDate = isDate(a);\n const bIsDate = isDate(b);\n if (!aIsDate && !bIsDate) return true;\n if (aIsDate !== bIsDate) return false;\n return a.getTime() === b.getTime();\n }\n\n function valuesAreEqual(a: any, b: any) {\n if (isRange.value) {\n const aHasValue = hasValue(a);\n const bHasValue = hasValue(b);\n if (!aHasValue && !bHasValue) return true;\n if (aHasValue !== bHasValue) return false;\n return datesAreEqual(a.start, b.start) && datesAreEqual(a.end, b.end);\n }\n return datesAreEqual(a, b);\n }\n\n function valueIsDisabled(value: any) {\n if (!hasValue(value) || !disabledAttribute.value) return false;\n return disabledAttribute.value.intersectsRange(locale.value.range(value));\n }\n\n function normalizeValue(\n value: any,\n config: DateConfig[],\n patch: DatePatch,\n targetPriority?: ValueTarget,\n ): Date | SimpleDateRange | null {\n if (!hasValue(value)) return null;\n if (isRange.value) {\n const start = locale.value.toDate(value.start, {\n ...config[0],\n fillDate: valueStart.value ?? undefined,\n patch,\n });\n const end = locale.value.toDate(value.end, {\n ...config[1],\n fillDate: valueEnd.value ?? undefined,\n patch,\n });\n return sortRange({ start, end }, targetPriority);\n }\n return locale.value.toDateOrNull(value, {\n ...config[0],\n fillDate: dateValue.value as Date,\n patch,\n });\n }\n\n function denormalizeValue(value: any, config: DateConfig[]) {\n if (isRange.value) {\n if (!hasValue(value)) return null;\n return {\n start: locale.value.fromDate(value.start, config[0]),\n end: locale.value.fromDate(value.end, config[1]),\n };\n }\n return locale.value.fromDate(value, config[0]);\n }\n\n function updateValue(\n value: any,\n opts: Partial = {},\n ): Promise> {\n clearTimeout(updateTimeout);\n return new Promise(resolve => {\n const { debounce = 0, ...args } = opts;\n if (debounce > 0) {\n updateTimeout = window.setTimeout(() => {\n resolve(forceUpdateValue(value, args));\n }, debounce);\n } else {\n resolve(forceUpdateValue(value, args));\n }\n });\n }\n\n function forceUpdateValue(\n value: any,\n {\n config = modelConfig.value,\n patch = 'dateTime',\n clearIfEqual = false,\n formatInput: fInput = true,\n hidePopover: hPopover = false,\n dragging = isDragging.value,\n targetPriority,\n moveToValue: mValue = false,\n }: Partial = {},\n ) {\n // 1. Normalization\n const normalizedConfig = normalizeDateConfig(config);\n let normalizedValue = normalizeValue(\n value,\n normalizedConfig,\n patch,\n targetPriority,\n );\n\n // 2a. Validation against disabled dates\n const isDisabled = valueIsDisabled(normalizedValue);\n if (isDisabled) {\n if (dragging) return null;\n normalizedValue = dateValue.value;\n // Don't allow hiding popover\n hPopover = false;\n // 2b. Validation against is-required or clearIfEqual\n } else if (normalizedValue == null && props.isRequired) {\n // Reset to previous value if it was cleared but is required\n normalizedValue = dateValue.value;\n // 2c. Validation against clearIfEqual\n } else if (\n // Clear value if same value was passed\n normalizedValue != null &&\n valuesAreEqual(dateValue.value, normalizedValue) &&\n clearIfEqual\n ) {\n normalizedValue = null;\n }\n\n // 3. Assignment\n const valueRef = dragging ? dragValue : dateValue;\n const notify = !valuesAreEqual(valueRef.value, normalizedValue);\n valueRef.value = normalizedValue;\n // Clear drag value if needed\n if (!dragging) dragValue.value = null;\n // Denormalize value using the model config\n const denormalizedValue = denormalizeValue(\n normalizedValue,\n modelConfig.value,\n );\n\n // 4. Notification\n if (notify) {\n watchValue = false;\n emit(dragging ? 'drag' : 'update:modelValue', denormalizedValue);\n nextTick(() => (watchValue = true));\n }\n\n // 5. Hide popover if needed\n if (hPopover && !dragging) hidePopover();\n\n // 6. Format inputs if needed\n if (fInput) formatInput();\n\n // 7. Move to range target if needed\n if (mValue) {\n nextTick(() => moveToValue(targetPriority ?? 'start'));\n }\n\n return denormalizedValue;\n }\n\n function formatInput() {\n nextTick(() => {\n const config = normalizeDateConfig({\n type: 'string',\n mask: inputMask.value,\n });\n const value = denormalizeValue(\n dragValue.value || dateValue.value,\n config,\n );\n if (isRange.value) {\n // @ts-ignore\n inputValues.value = [value && value.start, value && value.end];\n } else {\n inputValues.value = [value as string, ''];\n }\n });\n }\n\n function onInputUpdate(\n inputValue: string,\n target: ValueTarget,\n opts: Partial,\n ) {\n inputValues.value.splice(target === 'start' ? 0 : 1, 1, inputValue);\n const value = isRange.value\n ? {\n start: inputValues.value[0],\n end: inputValues.value[1] || inputValues.value[0],\n }\n : inputValue;\n const config = {\n type: 'string',\n mask: inputMask.value,\n };\n updateValue(value, {\n ...opts,\n config,\n patch: inputMaskPatch.value,\n targetPriority: target,\n moveToValue: true,\n });\n }\n\n function onInputInput(target: ValueTarget) {\n return (e: InputEvent) => {\n if (!props.updateOnInput) return;\n onInputUpdate((e.currentTarget).value, target, {\n formatInput: false,\n hidePopover: false,\n debounce: props.inputDebounce,\n });\n };\n }\n\n function onInputChange(target: ValueTarget) {\n return (e: InputEvent) => {\n onInputUpdate((e.currentTarget).value, target, {\n formatInput: true,\n hidePopover: false,\n });\n };\n }\n\n function onInputKeyup(e: KeyboardEvent) {\n // Escape key only\n if (e.key !== 'Escape') return;\n updateValue(dateValue.value, {\n formatInput: true,\n hidePopover: true,\n });\n }\n\n function getDateParts(value: any): (DateParts | null)[] {\n if (isRange.value) {\n return [\n value && value.start ? locale.value.getDateParts(value.start) : null,\n value && value.end ? locale.value.getDateParts(value.end) : null,\n ];\n }\n return [value ? locale.value.getDateParts(value) : null];\n }\n\n function cancelDrag() {\n dragValue.value = null;\n formatInput();\n }\n\n function onPopoverBeforeShow(el: HTMLElement) {\n emit('popover-will-show', el);\n }\n\n function onPopoverAfterShow(el: HTMLElement) {\n emit('popover-did-show', el);\n }\n\n function onPopoverBeforeHide(el: HTMLElement) {\n cancelDrag();\n emit('popover-will-hide', el);\n }\n\n function onPopoverAfterHide(el: HTMLElement) {\n emit('popover-did-hide', el);\n }\n\n function handleDayClick(day: CalendarDay) {\n const opts: Partial = {\n patch: 'date',\n formatInput: true,\n hidePopover: true,\n };\n if (isRange.value) {\n const dragging = !isDragging.value;\n if (dragging) {\n dragTrackingValue = { start: day.startDate, end: day.endDate };\n } else if (dragTrackingValue != null) {\n dragTrackingValue.end = day.date;\n }\n updateValue(dragTrackingValue, {\n ...opts,\n dragging,\n });\n } else {\n updateValue(day.date, {\n ...opts,\n clearIfEqual: !props.isRequired,\n });\n }\n }\n\n function onDayClick(day: CalendarDay, event: MouseEvent) {\n handleDayClick(day);\n // Re-emit event\n emit('dayclick', day, event);\n }\n\n function onDayKeydown(day: CalendarDay, event: KeyboardEvent) {\n switch (event.key) {\n case ' ':\n case 'Enter': {\n handleDayClick(day);\n event.preventDefault();\n break;\n }\n case 'Escape': {\n hidePopover();\n }\n }\n // Re-emit event\n emit('daykeydown', day, event);\n }\n\n function onDayMouseEnter(day: CalendarDay, event: MouseEvent) {\n if (!isDragging.value || dragTrackingValue == null) return;\n dragTrackingValue.end = day.date;\n updateValue(sortRange(dragTrackingValue), {\n patch: 'date',\n formatInput: true,\n });\n }\n\n function showPopover(opts: Partial = {}) {\n sp({\n ...popover.value,\n ...opts,\n isInteractive: true,\n id: datePickerPopoverId.value,\n });\n }\n\n function hidePopover(opts: Partial = {}) {\n hp({\n hideDelay: 10,\n force: true,\n ...popover.value,\n ...opts,\n id: datePickerPopoverId.value,\n });\n }\n\n function togglePopover(opts: Partial) {\n tp({\n ...popover.value,\n ...opts,\n isInteractive: true,\n id: datePickerPopoverId.value,\n });\n }\n\n function sortRange(range: any, priority?: ValueTarget) {\n const { start, end } = range;\n if (start > end) {\n switch (priority) {\n case 'start':\n return { start, end: start };\n case 'end':\n return { start: end, end };\n default:\n return { start: end, end: start };\n }\n }\n return { start, end };\n }\n\n function getPageForValue(isStart: boolean) {\n if (hasValue(dateValue.value)) {\n const date = isRange.value\n ? isStart\n ? valueStart.value\n : valueEnd.value\n : dateValue.value;\n return getPageAddressForDate(date as Date, 'monthly', locale.value);\n }\n return null;\n }\n\n async function move(target: MoveTarget, opts: Partial = {}) {\n if (calendarRef.value == null) return false;\n return calendarRef.value.move(target, opts);\n }\n\n async function moveBy(pages: number, opts: Partial = {}) {\n if (calendarRef.value == null) return false;\n return calendarRef.value.moveBy(pages, opts);\n }\n\n async function moveToValue(\n target: ValueTarget,\n opts: Partial = {},\n ) {\n if (calendarRef.value == null) return false;\n const { firstPage, lastPage, move } = calendarRef.value;\n const start = target !== 'end';\n const page = getPageForValue(start);\n const position = start ? 1 : -1;\n if (!page || pageIsBetweenPages(page, firstPage, lastPage)) return false;\n return move(page, {\n position,\n ...opts,\n });\n }\n\n // #endregion Methods\n\n // #region Watch\n\n watch(\n () => props.isRange,\n val => {\n if (val) {\n console.warn(\n 'The `is-range` prop will be deprecated in future releases. Please use the `range` modifier.',\n );\n }\n },\n { immediate: true },\n );\n watch(\n () => inputMask.value,\n () => formatInput(),\n );\n watch(\n () => props.modelValue,\n val => {\n if (!watchValue) return;\n forceUpdateValue(val, {\n formatInput: true,\n hidePopover: false,\n });\n },\n );\n watch(\n () => rules.value,\n () => {\n if (isObject(props.rules)) {\n forceUpdateValue(props.modelValue, {\n formatInput: true,\n hidePopover: false,\n });\n }\n },\n );\n watch(\n () => props.timezone,\n () => {\n forceUpdateValue(dateValue.value, { formatInput: true });\n },\n );\n\n // #endregion Watch\n\n // #region Lifecycle\n\n // Set initial date value (no validation applied)\n const config = normalizeConfig(modelConfig.value);\n dateValue.value = normalizeValue(props.modelValue, config, 'dateTime');\n\n onMounted(() => {\n forceUpdateValue(props.modelValue, {\n formatInput: true,\n hidePopover: false,\n });\n });\n\n // Created\n // Waiting a tick allows calendar to initialize page\n nextTick(() => (showCalendar.value = true));\n\n // #endregion Lifecycle\n\n const context = {\n ...baseCtx,\n showCalendar,\n datePickerPopoverId,\n popoverRef,\n popoverEvents,\n calendarRef,\n isRange,\n isTimeMode,\n isDateTimeMode,\n is24hr: toRef(props, 'is24hr'),\n hideTimeHeader: toRef(props, 'hideTimeHeader'),\n timeAccuracy: toRef(props, 'timeAccuracy'),\n isDragging,\n inputValue,\n inputEvents,\n dateParts,\n attributes,\n rules,\n move,\n moveBy,\n moveToValue,\n updateValue,\n showPopover,\n hidePopover,\n togglePopover,\n onDayClick,\n onDayKeydown,\n onDayMouseEnter,\n onPopoverBeforeShow,\n onPopoverAfterShow,\n onPopoverBeforeHide,\n onPopoverAfterHide,\n };\n provide(contextKey, context);\n return context;\n}\n\nexport function useDatePicker() {\n const context = inject(contextKey);\n if (context) return context;\n throw new Error(\n 'DatePicker context missing. Please verify this component is nested within a valid context provider.',\n );\n}\n","import { computed } from 'vue';\nimport { arrayHasItems } from '../utils/helpers';\nimport {\n SimpleDateParts,\n DateParts,\n getDatePartsOptions,\n isDateParts,\n} from '../utils/date/helpers';\nimport { useBase } from '../use/base';\nimport { useDatePicker } from '../use/datePicker';\n\nconst _amOptions = [\n { value: 0, label: '12' },\n { value: 1, label: '1' },\n { value: 2, label: '2' },\n { value: 3, label: '3' },\n { value: 4, label: '4' },\n { value: 5, label: '5' },\n { value: 6, label: '6' },\n { value: 7, label: '7' },\n { value: 8, label: '8' },\n { value: 9, label: '9' },\n { value: 10, label: '10' },\n { value: 11, label: '11' },\n];\nconst _pmOptions = [\n { value: 12, label: '12' },\n { value: 13, label: '1' },\n { value: 14, label: '2' },\n { value: 15, label: '3' },\n { value: 16, label: '4' },\n { value: 17, label: '5' },\n { value: 18, label: '6' },\n { value: 19, label: '7' },\n { value: 20, label: '8' },\n { value: 21, label: '9' },\n { value: 22, label: '10' },\n { value: 23, label: '11' },\n];\n\nexport interface TimePickerProps {\n position: number;\n}\n\nexport type TimePickerContext = ReturnType;\n\nexport function createTimePicker(props: TimePickerProps) {\n const ctx = useDatePicker();\n const {\n locale,\n isRange,\n isTimeMode,\n dateParts,\n rules,\n is24hr,\n hideTimeHeader,\n timeAccuracy,\n updateValue: updateDpValue,\n } = ctx;\n\n function updateParts(newParts: Partial) {\n newParts = Object.assign(parts.value, newParts);\n let newValue = null;\n if (isRange.value) {\n const start = isStart.value ? newParts : dateParts.value[0];\n const end = isStart.value ? dateParts.value[1] : newParts;\n newValue = { start, end };\n } else {\n newValue = newParts;\n }\n updateDpValue(newValue, {\n patch: 'time',\n targetPriority: isStart.value ? 'start' : 'end',\n moveToValue: true,\n });\n }\n\n const isStart = computed(() => props.position === 0);\n const parts = computed(\n () => dateParts.value[props.position] || { isValid: false },\n );\n const partsValid = computed(() => isDateParts(parts.value));\n const isValid = computed(() => !!parts.value.isValid);\n const showHeader = computed(() => {\n return !hideTimeHeader.value && isValid.value;\n });\n\n const date = computed(() => {\n if (!partsValid.value) return null;\n let date = locale.value.toDate(parts.value as Partial);\n if ((parts.value as DateParts).hours === 24) {\n date = new Date(date.getTime() - 1);\n }\n return date;\n });\n\n const hours = computed({\n get() {\n return (parts.value as DateParts).hours;\n },\n set(val) {\n updateParts({ hours: val });\n },\n });\n\n const minutes = computed({\n get() {\n return (parts.value as DateParts).minutes;\n },\n set(val) {\n updateParts({ minutes: val });\n },\n });\n\n const seconds = computed({\n get() {\n return (parts.value as DateParts).seconds;\n },\n set(val) {\n updateParts({ seconds: val });\n },\n });\n\n const milliseconds = computed({\n get() {\n return (parts.value as DateParts).milliseconds;\n },\n set(val) {\n updateParts({ milliseconds: val });\n },\n });\n\n const isAM = computed({\n get() {\n return (parts.value as DateParts).hours < 12;\n },\n set(value) {\n value = String(value).toLowerCase() == 'true';\n let hValue = hours.value;\n if (value && hValue >= 12) {\n hValue -= 12;\n } else if (!value && hValue < 12) {\n hValue += 12;\n }\n updateParts({ hours: hValue });\n },\n });\n\n const options = computed(() =>\n getDatePartsOptions(parts.value as DateParts, rules.value[props.position]),\n );\n\n const amHourOptions = computed(() => {\n return _amOptions.filter(opt =>\n options.value.hours.some(ho => ho.value === opt.value),\n );\n });\n\n const pmHourOptions = computed(() => {\n return _pmOptions.filter(opt =>\n options.value.hours.some(ho => ho.value === opt.value),\n );\n });\n\n const hourOptions = computed(() => {\n if (is24hr.value) return options.value.hours;\n if (isAM.value) return amHourOptions.value;\n return pmHourOptions.value;\n });\n\n const isAMOptions = computed(() => {\n const result = [];\n if (arrayHasItems(amHourOptions.value))\n result.push({ value: true, label: 'AM' });\n if (arrayHasItems(pmHourOptions.value))\n result.push({ value: false, label: 'PM' });\n return result;\n });\n\n return {\n ...ctx,\n showHeader,\n timeAccuracy,\n parts,\n isValid,\n date,\n hours,\n minutes,\n seconds,\n milliseconds,\n options,\n hourOptions,\n isAM,\n isAMOptions,\n is24hr,\n };\n}\n","\n \n
\n \n \n
\n \n \n 1\">\n :\n \n \n 2\">\n :\n \n \n 3\">\n .\n \n \n \n
\n
\n\n\n\n\n\n","\n","/**\n * vee-validate v4.7.4\n * (c) 2023 Abdelrahman Awad\n * @license MIT\n */\nimport { getCurrentInstance, inject, warn as warn$1, ref, watch, unref, computed, reactive, onUnmounted, nextTick, onMounted, provide, isRef, onBeforeUnmount, defineComponent, toRef, resolveDynamicComponent, h, watchEffect, markRaw } from 'vue';\nimport { setupDevtoolsPlugin } from '@vue/devtools-api';\n\nfunction isCallable(fn) {\r\n return typeof fn === 'function';\r\n}\r\nfunction isNullOrUndefined(value) {\r\n return value === null || value === undefined;\r\n}\r\nconst isObject = (obj) => obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj);\r\nfunction isIndex(value) {\r\n return Number(value) >= 0;\r\n}\r\nfunction toNumber(value) {\r\n const n = parseFloat(value);\r\n return isNaN(n) ? value : n;\r\n}\n\nconst RULES = {};\r\n/**\r\n * Adds a custom validator to the list of validation rules.\r\n */\r\nfunction defineRule(id, validator) {\r\n // makes sure new rules are properly formatted.\r\n guardExtend(id, validator);\r\n RULES[id] = validator;\r\n}\r\n/**\r\n * Gets an already defined rule\r\n */\r\nfunction resolveRule(id) {\r\n return RULES[id];\r\n}\r\n/**\r\n * Guards from extension violations.\r\n */\r\nfunction guardExtend(id, validator) {\r\n if (isCallable(validator)) {\r\n return;\r\n }\r\n throw new Error(`Extension Error: The validator '${id}' must be a function.`);\r\n}\n\nconst FormContextKey = Symbol('vee-validate-form');\r\nconst FieldContextKey = Symbol('vee-validate-field-instance');\r\nconst IS_ABSENT = Symbol('Default empty value');\n\nconst isClient = typeof window !== 'undefined';\r\nfunction isLocator(value) {\r\n return isCallable(value) && !!value.__locatorRef;\r\n}\r\nfunction isYupValidator(value) {\r\n return !!value && isCallable(value.validate);\r\n}\r\nfunction hasCheckedAttr(type) {\r\n return type === 'checkbox' || type === 'radio';\r\n}\r\nfunction isContainerValue(value) {\r\n return isObject(value) || Array.isArray(value);\r\n}\r\n/**\r\n * True if the value is an empty object or array\r\n */\r\nfunction isEmptyContainer(value) {\r\n if (Array.isArray(value)) {\r\n return value.length === 0;\r\n }\r\n return isObject(value) && Object.keys(value).length === 0;\r\n}\r\n/**\r\n * Checks if the path opted out of nested fields using `[fieldName]` syntax\r\n */\r\nfunction isNotNestedPath(path) {\r\n return /^\\[.+\\]$/i.test(path);\r\n}\r\n/**\r\n * Checks if an element is a native HTML5 multi-select input element\r\n */\r\nfunction isNativeMultiSelect(el) {\r\n return isNativeSelect(el) && el.multiple;\r\n}\r\n/**\r\n * Checks if an element is a native HTML5 select input element\r\n */\r\nfunction isNativeSelect(el) {\r\n return el.tagName === 'SELECT';\r\n}\r\n/**\r\n * Checks if a tag name with attrs object will render a native multi-select element\r\n */\r\nfunction isNativeMultiSelectNode(tag, attrs) {\r\n // The falsy value array is the values that Vue won't add the `multiple` prop if it has one of these values\r\n const hasTruthyBindingValue = ![false, null, undefined, 0].includes(attrs.multiple) && !Number.isNaN(attrs.multiple);\r\n return tag === 'select' && 'multiple' in attrs && hasTruthyBindingValue;\r\n}\r\n/**\r\n * Checks if a node should have a `:value` binding or not\r\n *\r\n * These nodes should not have a value binding\r\n * For files, because they are not reactive\r\n * For multi-selects because the value binding will reset the value\r\n */\r\nfunction shouldHaveValueBinding(tag, attrs) {\r\n return !isNativeMultiSelectNode(tag, attrs) && attrs.type !== 'file' && !hasCheckedAttr(attrs.type);\r\n}\r\nfunction isFormSubmitEvent(evt) {\r\n return isEvent(evt) && evt.target && 'submit' in evt.target;\r\n}\r\nfunction isEvent(evt) {\r\n if (!evt) {\r\n return false;\r\n }\r\n if (typeof Event !== 'undefined' && isCallable(Event) && evt instanceof Event) {\r\n return true;\r\n }\r\n // this is for IE and Cypress #3161\r\n /* istanbul ignore next */\r\n if (evt && evt.srcElement) {\r\n return true;\r\n }\r\n return false;\r\n}\r\nfunction isPropPresent(obj, prop) {\r\n return prop in obj && obj[prop] !== IS_ABSENT;\r\n}\r\n/**\r\n * Compares if two values are the same borrowed from:\r\n * https://github.com/epoberezkin/fast-deep-equal\r\n * We added a case for file matching since `Object.keys` doesn't work with Files.\r\n * */\r\nfunction isEqual(a, b) {\r\n if (a === b)\r\n return true;\r\n if (a && b && typeof a === 'object' && typeof b === 'object') {\r\n if (a.constructor !== b.constructor)\r\n return false;\r\n // eslint-disable-next-line no-var\r\n var length, i, keys;\r\n if (Array.isArray(a)) {\r\n length = a.length;\r\n // eslint-disable-next-line eqeqeq\r\n if (length != b.length)\r\n return false;\r\n for (i = length; i-- !== 0;)\r\n if (!isEqual(a[i], b[i]))\r\n return false;\r\n return true;\r\n }\r\n if (a instanceof Map && b instanceof Map) {\r\n if (a.size !== b.size)\r\n return false;\r\n for (i of a.entries())\r\n if (!b.has(i[0]))\r\n return false;\r\n for (i of a.entries())\r\n if (!isEqual(i[1], b.get(i[0])))\r\n return false;\r\n return true;\r\n }\r\n // We added this part for file comparison, arguably a little naive but should work for most cases.\r\n // #3911\r\n if (isFile(a) && isFile(b)) {\r\n if (a.size !== b.size)\r\n return false;\r\n if (a.name !== b.name)\r\n return false;\r\n if (a.lastModified !== b.lastModified)\r\n return false;\r\n if (a.type !== b.type)\r\n return false;\r\n return true;\r\n }\r\n if (a instanceof Set && b instanceof Set) {\r\n if (a.size !== b.size)\r\n return false;\r\n for (i of a.entries())\r\n if (!b.has(i[0]))\r\n return false;\r\n return true;\r\n }\r\n if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {\r\n length = a.length;\r\n // eslint-disable-next-line eqeqeq\r\n if (length != b.length)\r\n return false;\r\n for (i = length; i-- !== 0;)\r\n if (a[i] !== b[i])\r\n return false;\r\n return true;\r\n }\r\n if (a.constructor === RegExp)\r\n return a.source === b.source && a.flags === b.flags;\r\n if (a.valueOf !== Object.prototype.valueOf)\r\n return a.valueOf() === b.valueOf();\r\n if (a.toString !== Object.prototype.toString)\r\n return a.toString() === b.toString();\r\n keys = Object.keys(a);\r\n length = keys.length;\r\n if (length !== Object.keys(b).length)\r\n return false;\r\n for (i = length; i-- !== 0;)\r\n if (!Object.prototype.hasOwnProperty.call(b, keys[i]))\r\n return false;\r\n for (i = length; i-- !== 0;) {\r\n // eslint-disable-next-line no-var\r\n var key = keys[i];\r\n if (!isEqual(a[key], b[key]))\r\n return false;\r\n }\r\n return true;\r\n }\r\n // true if both NaN, false otherwise\r\n // eslint-disable-next-line no-self-compare\r\n return a !== a && b !== b;\r\n}\r\nfunction isFile(a) {\r\n if (!isClient) {\r\n return false;\r\n }\r\n return a instanceof File;\r\n}\n\nfunction set(obj, key, val) {\n\tif (typeof val.value === 'object') val.value = klona(val.value);\n\tif (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === '__proto__') {\n\t\tObject.defineProperty(obj, key, val);\n\t} else obj[key] = val.value;\n}\n\nfunction klona(x) {\n\tif (typeof x !== 'object') return x;\n\n\tvar i=0, k, list, tmp, str=Object.prototype.toString.call(x);\n\n\tif (str === '[object Object]') {\n\t\ttmp = Object.create(x.__proto__ || null);\n\t} else if (str === '[object Array]') {\n\t\ttmp = Array(x.length);\n\t} else if (str === '[object Set]') {\n\t\ttmp = new Set;\n\t\tx.forEach(function (val) {\n\t\t\ttmp.add(klona(val));\n\t\t});\n\t} else if (str === '[object Map]') {\n\t\ttmp = new Map;\n\t\tx.forEach(function (val, key) {\n\t\t\ttmp.set(klona(key), klona(val));\n\t\t});\n\t} else if (str === '[object Date]') {\n\t\ttmp = new Date(+x);\n\t} else if (str === '[object RegExp]') {\n\t\ttmp = new RegExp(x.source, x.flags);\n\t} else if (str === '[object DataView]') {\n\t\ttmp = new x.constructor( klona(x.buffer) );\n\t} else if (str === '[object ArrayBuffer]') {\n\t\ttmp = x.slice(0);\n\t} else if (str.slice(-6) === 'Array]') {\n\t\t// ArrayBuffer.isView(x)\n\t\t// ~> `new` bcuz `Buffer.slice` => ref\n\t\ttmp = new x.constructor(x);\n\t}\n\n\tif (tmp) {\n\t\tfor (list=Object.getOwnPropertySymbols(x); i < list.length; i++) {\n\t\t\tset(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));\n\t\t}\n\n\t\tfor (i=0, list=Object.getOwnPropertyNames(x); i < list.length; i++) {\n\t\t\tif (Object.hasOwnProperty.call(tmp, k=list[i]) && tmp[k] === x[k]) continue;\n\t\t\tset(tmp, k, Object.getOwnPropertyDescriptor(x, k));\n\t\t}\n\t}\n\n\treturn tmp || x;\n}\n\nfunction cleanupNonNestedPath(path) {\r\n if (isNotNestedPath(path)) {\r\n return path.replace(/\\[|\\]/gi, '');\r\n }\r\n return path;\r\n}\r\nfunction getFromPath(object, path, fallback) {\r\n if (!object) {\r\n return fallback;\r\n }\r\n if (isNotNestedPath(path)) {\r\n return object[cleanupNonNestedPath(path)];\r\n }\r\n const resolvedValue = (path || '')\r\n .split(/\\.|\\[(\\d+)\\]/)\r\n .filter(Boolean)\r\n .reduce((acc, propKey) => {\r\n if (isContainerValue(acc) && propKey in acc) {\r\n return acc[propKey];\r\n }\r\n return fallback;\r\n }, object);\r\n return resolvedValue;\r\n}\r\n/**\r\n * Sets a nested property value in a path, creates the path properties if it doesn't exist\r\n */\r\nfunction setInPath(object, path, value) {\r\n if (isNotNestedPath(path)) {\r\n object[cleanupNonNestedPath(path)] = value;\r\n return;\r\n }\r\n const keys = path.split(/\\.|\\[(\\d+)\\]/).filter(Boolean);\r\n let acc = object;\r\n for (let i = 0; i < keys.length; i++) {\r\n // Last key, set it\r\n if (i === keys.length - 1) {\r\n acc[keys[i]] = value;\r\n return;\r\n }\r\n // Key does not exist, create a container for it\r\n if (!(keys[i] in acc) || isNullOrUndefined(acc[keys[i]])) {\r\n // container can be either an object or an array depending on the next key if it exists\r\n acc[keys[i]] = isIndex(keys[i + 1]) ? [] : {};\r\n }\r\n acc = acc[keys[i]];\r\n }\r\n}\r\nfunction unset(object, key) {\r\n if (Array.isArray(object) && isIndex(key)) {\r\n object.splice(Number(key), 1);\r\n return;\r\n }\r\n if (isObject(object)) {\r\n delete object[key];\r\n }\r\n}\r\n/**\r\n * Removes a nested property from object\r\n */\r\nfunction unsetPath(object, path) {\r\n if (isNotNestedPath(path)) {\r\n delete object[cleanupNonNestedPath(path)];\r\n return;\r\n }\r\n const keys = path.split(/\\.|\\[(\\d+)\\]/).filter(Boolean);\r\n let acc = object;\r\n for (let i = 0; i < keys.length; i++) {\r\n // Last key, unset it\r\n if (i === keys.length - 1) {\r\n unset(acc, keys[i]);\r\n break;\r\n }\r\n // Key does not exist, exit\r\n if (!(keys[i] in acc) || isNullOrUndefined(acc[keys[i]])) {\r\n break;\r\n }\r\n acc = acc[keys[i]];\r\n }\r\n const pathValues = keys.map((_, idx) => {\r\n return getFromPath(object, keys.slice(0, idx).join('.'));\r\n });\r\n for (let i = pathValues.length - 1; i >= 0; i--) {\r\n if (!isEmptyContainer(pathValues[i])) {\r\n continue;\r\n }\r\n if (i === 0) {\r\n unset(object, keys[0]);\r\n continue;\r\n }\r\n unset(pathValues[i - 1], keys[i - 1]);\r\n }\r\n}\r\n/**\r\n * A typed version of Object.keys\r\n */\r\nfunction keysOf(record) {\r\n return Object.keys(record);\r\n}\r\n// Uses same component provide as its own injections\r\n// Due to changes in https://github.com/vuejs/vue-next/pull/2424\r\nfunction injectWithSelf(symbol, def = undefined) {\r\n const vm = getCurrentInstance();\r\n return (vm === null || vm === void 0 ? void 0 : vm.provides[symbol]) || inject(symbol, def);\r\n}\r\nfunction warn(message) {\r\n warn$1(`[vee-validate]: ${message}`);\r\n}\r\n/**\r\n * Ensures we deal with a singular field value\r\n */\r\nfunction normalizeField(field) {\r\n if (Array.isArray(field)) {\r\n return field[0];\r\n }\r\n return field;\r\n}\r\nfunction resolveNextCheckboxValue(currentValue, checkedValue, uncheckedValue) {\r\n if (Array.isArray(currentValue)) {\r\n const newVal = [...currentValue];\r\n // Use isEqual since checked object values can possibly fail the equality check #3883\r\n const idx = newVal.findIndex(v => isEqual(v, checkedValue));\r\n idx >= 0 ? newVal.splice(idx, 1) : newVal.push(checkedValue);\r\n return newVal;\r\n }\r\n return isEqual(currentValue, checkedValue) ? uncheckedValue : checkedValue;\r\n}\r\n/**\r\n * Creates a throttled function that only invokes the provided function (`func`) at most once per within a given number of milliseconds\r\n * (`limit`)\r\n */\r\nfunction throttle(func, limit) {\r\n let inThrottle;\r\n let lastResult;\r\n return function (...args) {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context = this;\r\n if (!inThrottle) {\r\n inThrottle = true;\r\n setTimeout(() => (inThrottle = false), limit);\r\n lastResult = func.apply(context, args);\r\n }\r\n return lastResult;\r\n };\r\n}\r\nfunction debounceAsync(inner, ms = 0) {\r\n let timer = null;\r\n let resolves = [];\r\n return function (...args) {\r\n // Run the function after a certain amount of time\r\n if (timer) {\r\n window.clearTimeout(timer);\r\n }\r\n timer = window.setTimeout(() => {\r\n // Get the result of the inner function, then apply it to the resolve function of\r\n // each promise that has been created since the last time the inner function was run\r\n const result = inner(...args);\r\n resolves.forEach(r => r(result));\r\n resolves = [];\r\n }, ms);\r\n return new Promise(resolve => resolves.push(resolve));\r\n };\r\n}\r\nfunction applyModelModifiers(value, modifiers) {\r\n if (!isObject(modifiers)) {\r\n return value;\r\n }\r\n if (modifiers.number) {\r\n return toNumber(value);\r\n }\r\n return value;\r\n}\r\nfunction withLatest(fn, onDone) {\r\n let latestRun;\r\n return async function runLatest(...args) {\r\n const pending = fn(...args);\r\n latestRun = pending;\r\n const result = await pending;\r\n if (pending !== latestRun) {\r\n return result;\r\n }\r\n latestRun = undefined;\r\n onDone(result, args);\r\n return result;\r\n };\r\n}\r\nfunction computedDeep({ get, set }) {\r\n const baseRef = ref(klona(get()));\r\n watch(get, newValue => {\r\n if (isEqual(newValue, baseRef.value)) {\r\n return;\r\n }\r\n baseRef.value = klona(newValue);\r\n }, {\r\n deep: true,\r\n });\r\n watch(baseRef, newValue => {\r\n if (isEqual(newValue, get())) {\r\n return;\r\n }\r\n set(klona(newValue));\r\n }, {\r\n deep: true,\r\n });\r\n return baseRef;\r\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nconst normalizeChildren = (tag, context, slotProps) => {\r\n if (!context.slots.default) {\r\n return context.slots.default;\r\n }\r\n if (typeof tag === 'string' || !tag) {\r\n return context.slots.default(slotProps());\r\n }\r\n return {\r\n default: () => { var _a, _b; return (_b = (_a = context.slots).default) === null || _b === void 0 ? void 0 : _b.call(_a, slotProps()); },\r\n };\r\n};\r\n/**\r\n * Vue adds a `_value` prop at the moment on the input elements to store the REAL value on them, real values are different than the `value` attribute\r\n * as they do not get casted to strings unlike `el.value` which preserves user-code behavior\r\n */\r\nfunction getBoundValue(el) {\r\n if (hasValueBinding(el)) {\r\n return el._value;\r\n }\r\n return undefined;\r\n}\r\n/**\r\n * Vue adds a `_value` prop at the moment on the input elements to store the REAL value on them, real values are different than the `value` attribute\r\n * as they do not get casted to strings unlike `el.value` which preserves user-code behavior\r\n */\r\nfunction hasValueBinding(el) {\r\n return '_value' in el;\r\n}\n\nfunction normalizeEventValue(value) {\r\n if (!isEvent(value)) {\r\n return value;\r\n }\r\n const input = value.target;\r\n // Vue sets the current bound value on `_value` prop\r\n // for checkboxes it it should fetch the value binding type as is (boolean instead of string)\r\n if (hasCheckedAttr(input.type) && hasValueBinding(input)) {\r\n return getBoundValue(input);\r\n }\r\n if (input.type === 'file' && input.files) {\r\n const files = Array.from(input.files);\r\n return input.multiple ? files : files[0];\r\n }\r\n if (isNativeMultiSelect(input)) {\r\n return Array.from(input.options)\r\n .filter(opt => opt.selected && !opt.disabled)\r\n .map(getBoundValue);\r\n }\r\n // makes sure we get the actual `option` bound value\r\n // #3440\r\n if (isNativeSelect(input)) {\r\n const selectedOption = Array.from(input.options).find(opt => opt.selected);\r\n return selectedOption ? getBoundValue(selectedOption) : input.value;\r\n }\r\n return input.value;\r\n}\n\n/**\r\n * Normalizes the given rules expression.\r\n */\r\nfunction normalizeRules(rules) {\r\n const acc = {};\r\n Object.defineProperty(acc, '_$$isNormalized', {\r\n value: true,\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n });\r\n if (!rules) {\r\n return acc;\r\n }\r\n // Object is already normalized, skip.\r\n if (isObject(rules) && rules._$$isNormalized) {\r\n return rules;\r\n }\r\n if (isObject(rules)) {\r\n return Object.keys(rules).reduce((prev, curr) => {\r\n const params = normalizeParams(rules[curr]);\r\n if (rules[curr] !== false) {\r\n prev[curr] = buildParams(params);\r\n }\r\n return prev;\r\n }, acc);\r\n }\r\n /* istanbul ignore if */\r\n if (typeof rules !== 'string') {\r\n return acc;\r\n }\r\n return rules.split('|').reduce((prev, rule) => {\r\n const parsedRule = parseRule(rule);\r\n if (!parsedRule.name) {\r\n return prev;\r\n }\r\n prev[parsedRule.name] = buildParams(parsedRule.params);\r\n return prev;\r\n }, acc);\r\n}\r\n/**\r\n * Normalizes a rule param.\r\n */\r\nfunction normalizeParams(params) {\r\n if (params === true) {\r\n return [];\r\n }\r\n if (Array.isArray(params)) {\r\n return params;\r\n }\r\n if (isObject(params)) {\r\n return params;\r\n }\r\n return [params];\r\n}\r\nfunction buildParams(provided) {\r\n const mapValueToLocator = (value) => {\r\n // A target param using interpolation\r\n if (typeof value === 'string' && value[0] === '@') {\r\n return createLocator(value.slice(1));\r\n }\r\n return value;\r\n };\r\n if (Array.isArray(provided)) {\r\n return provided.map(mapValueToLocator);\r\n }\r\n // #3073\r\n if (provided instanceof RegExp) {\r\n return [provided];\r\n }\r\n return Object.keys(provided).reduce((prev, key) => {\r\n prev[key] = mapValueToLocator(provided[key]);\r\n return prev;\r\n }, {});\r\n}\r\n/**\r\n * Parses a rule string expression.\r\n */\r\nconst parseRule = (rule) => {\r\n let params = [];\r\n const name = rule.split(':')[0];\r\n if (rule.includes(':')) {\r\n params = rule.split(':').slice(1).join(':').split(',');\r\n }\r\n return { name, params };\r\n};\r\nfunction createLocator(value) {\r\n const locator = (crossTable) => {\r\n const val = getFromPath(crossTable, value) || crossTable[value];\r\n return val;\r\n };\r\n locator.__locatorRef = value;\r\n return locator;\r\n}\r\nfunction extractLocators(params) {\r\n if (Array.isArray(params)) {\r\n return params.filter(isLocator);\r\n }\r\n return keysOf(params)\r\n .filter(key => isLocator(params[key]))\r\n .map(key => params[key]);\r\n}\n\nconst DEFAULT_CONFIG = {\r\n generateMessage: ({ field }) => `${field} is not valid.`,\r\n bails: true,\r\n validateOnBlur: true,\r\n validateOnChange: true,\r\n validateOnInput: false,\r\n validateOnModelUpdate: true,\r\n};\r\nlet currentConfig = Object.assign({}, DEFAULT_CONFIG);\r\nconst getConfig = () => currentConfig;\r\nconst setConfig = (newConf) => {\r\n currentConfig = Object.assign(Object.assign({}, currentConfig), newConf);\r\n};\r\nconst configure = setConfig;\n\n/**\r\n * Validates a value against the rules.\r\n */\r\nasync function validate(value, rules, options = {}) {\r\n const shouldBail = options === null || options === void 0 ? void 0 : options.bails;\r\n const field = {\r\n name: (options === null || options === void 0 ? void 0 : options.name) || '{field}',\r\n rules,\r\n label: options === null || options === void 0 ? void 0 : options.label,\r\n bails: shouldBail !== null && shouldBail !== void 0 ? shouldBail : true,\r\n formData: (options === null || options === void 0 ? void 0 : options.values) || {},\r\n };\r\n const result = await _validate(field, value);\r\n const errors = result.errors;\r\n return {\r\n errors,\r\n valid: !errors.length,\r\n };\r\n}\r\n/**\r\n * Starts the validation process.\r\n */\r\nasync function _validate(field, value) {\r\n if (isYupValidator(field.rules)) {\r\n return validateFieldWithYup(value, field.rules, { bails: field.bails });\r\n }\r\n // if a generic function or chain of generic functions\r\n if (isCallable(field.rules) || Array.isArray(field.rules)) {\r\n const ctx = {\r\n field: field.label || field.name,\r\n name: field.name,\r\n label: field.label,\r\n form: field.formData,\r\n value: value,\r\n };\r\n // Normalize the pipeline\r\n const pipeline = Array.isArray(field.rules) ? field.rules : [field.rules];\r\n const length = pipeline.length;\r\n const errors = [];\r\n for (let i = 0; i < length; i++) {\r\n const rule = pipeline[i];\r\n const result = await rule(value, ctx);\r\n const isValid = typeof result !== 'string' && result;\r\n if (isValid) {\r\n continue;\r\n }\r\n const message = typeof result === 'string' ? result : _generateFieldError(ctx);\r\n errors.push(message);\r\n if (field.bails) {\r\n return {\r\n errors,\r\n };\r\n }\r\n }\r\n return {\r\n errors,\r\n };\r\n }\r\n const normalizedContext = Object.assign(Object.assign({}, field), { rules: normalizeRules(field.rules) });\r\n const errors = [];\r\n const rulesKeys = Object.keys(normalizedContext.rules);\r\n const length = rulesKeys.length;\r\n for (let i = 0; i < length; i++) {\r\n const rule = rulesKeys[i];\r\n const result = await _test(normalizedContext, value, {\r\n name: rule,\r\n params: normalizedContext.rules[rule],\r\n });\r\n if (result.error) {\r\n errors.push(result.error);\r\n if (field.bails) {\r\n return {\r\n errors,\r\n };\r\n }\r\n }\r\n }\r\n return {\r\n errors,\r\n };\r\n}\r\n/**\r\n * Handles yup validation\r\n */\r\nasync function validateFieldWithYup(value, validator, opts) {\r\n var _a;\r\n const errors = await validator\r\n .validate(value, {\r\n abortEarly: (_a = opts.bails) !== null && _a !== void 0 ? _a : true,\r\n })\r\n .then(() => [])\r\n .catch((err) => {\r\n // Yup errors have a name prop one them.\r\n // https://github.com/jquense/yup#validationerrorerrors-string--arraystring-value-any-path-string\r\n if (err.name === 'ValidationError') {\r\n return err.errors;\r\n }\r\n // re-throw the error so we don't hide it\r\n throw err;\r\n });\r\n return {\r\n errors,\r\n };\r\n}\r\n/**\r\n * Tests a single input value against a rule.\r\n */\r\nasync function _test(field, value, rule) {\r\n const validator = resolveRule(rule.name);\r\n if (!validator) {\r\n throw new Error(`No such validator '${rule.name}' exists.`);\r\n }\r\n const params = fillTargetValues(rule.params, field.formData);\r\n const ctx = {\r\n field: field.label || field.name,\r\n name: field.name,\r\n label: field.label,\r\n value,\r\n form: field.formData,\r\n rule: Object.assign(Object.assign({}, rule), { params }),\r\n };\r\n const result = await validator(value, params, ctx);\r\n if (typeof result === 'string') {\r\n return {\r\n error: result,\r\n };\r\n }\r\n return {\r\n error: result ? undefined : _generateFieldError(ctx),\r\n };\r\n}\r\n/**\r\n * Generates error messages.\r\n */\r\nfunction _generateFieldError(fieldCtx) {\r\n const message = getConfig().generateMessage;\r\n if (!message) {\r\n return 'Field is invalid';\r\n }\r\n return message(fieldCtx);\r\n}\r\nfunction fillTargetValues(params, crossTable) {\r\n const normalize = (value) => {\r\n if (isLocator(value)) {\r\n return value(crossTable);\r\n }\r\n return value;\r\n };\r\n if (Array.isArray(params)) {\r\n return params.map(normalize);\r\n }\r\n return Object.keys(params).reduce((acc, param) => {\r\n acc[param] = normalize(params[param]);\r\n return acc;\r\n }, {});\r\n}\r\nasync function validateYupSchema(schema, values) {\r\n const errorObjects = await schema\r\n .validate(values, { abortEarly: false })\r\n .then(() => [])\r\n .catch((err) => {\r\n // Yup errors have a name prop one them.\r\n // https://github.com/jquense/yup#validationerrorerrors-string--arraystring-value-any-path-string\r\n if (err.name !== 'ValidationError') {\r\n throw err;\r\n }\r\n // list of aggregated errors\r\n return err.inner || [];\r\n });\r\n const results = {};\r\n const errors = {};\r\n for (const error of errorObjects) {\r\n const messages = error.errors;\r\n results[error.path] = { valid: !messages.length, errors: messages };\r\n if (messages.length) {\r\n errors[error.path] = messages[0];\r\n }\r\n }\r\n return {\r\n valid: !errorObjects.length,\r\n results,\r\n errors,\r\n };\r\n}\r\nasync function validateObjectSchema(schema, values, opts) {\r\n const paths = keysOf(schema);\r\n const validations = paths.map(async (path) => {\r\n var _a, _b, _c;\r\n const strings = (_a = opts === null || opts === void 0 ? void 0 : opts.names) === null || _a === void 0 ? void 0 : _a[path];\r\n const fieldResult = await validate(getFromPath(values, path), schema[path], {\r\n name: (strings === null || strings === void 0 ? void 0 : strings.name) || path,\r\n label: strings === null || strings === void 0 ? void 0 : strings.label,\r\n values: values,\r\n bails: (_c = (_b = opts === null || opts === void 0 ? void 0 : opts.bailsMap) === null || _b === void 0 ? void 0 : _b[path]) !== null && _c !== void 0 ? _c : true,\r\n });\r\n return Object.assign(Object.assign({}, fieldResult), { path });\r\n });\r\n let isAllValid = true;\r\n const validationResults = await Promise.all(validations);\r\n const results = {};\r\n const errors = {};\r\n for (const result of validationResults) {\r\n results[result.path] = {\r\n valid: result.valid,\r\n errors: result.errors,\r\n };\r\n if (!result.valid) {\r\n isAllValid = false;\r\n errors[result.path] = result.errors[0];\r\n }\r\n }\r\n return {\r\n valid: isAllValid,\r\n results,\r\n errors,\r\n };\r\n}\n\nlet ID_COUNTER = 0;\r\nfunction useFieldState(path, init) {\r\n const { value, initialValue, setInitialValue } = _useFieldValue(path, init.modelValue, init.form);\r\n const { errorMessage, errors, setErrors } = _useFieldErrors(path, init.form);\r\n const meta = _useFieldMeta(value, initialValue, errors);\r\n const id = ID_COUNTER >= Number.MAX_SAFE_INTEGER ? 0 : ++ID_COUNTER;\r\n function setState(state) {\r\n var _a;\r\n if ('value' in state) {\r\n value.value = state.value;\r\n }\r\n if ('errors' in state) {\r\n setErrors(state.errors);\r\n }\r\n if ('touched' in state) {\r\n meta.touched = (_a = state.touched) !== null && _a !== void 0 ? _a : meta.touched;\r\n }\r\n if ('initialValue' in state) {\r\n setInitialValue(state.initialValue);\r\n }\r\n }\r\n return {\r\n id,\r\n path,\r\n value,\r\n initialValue,\r\n meta,\r\n errors,\r\n errorMessage,\r\n setState,\r\n };\r\n}\r\n/**\r\n * Creates the field value and resolves the initial value\r\n */\r\nfunction _useFieldValue(path, modelValue, form) {\r\n const modelRef = ref(unref(modelValue));\r\n function resolveInitialValue() {\r\n if (!form) {\r\n return unref(modelRef);\r\n }\r\n return getFromPath(form.meta.value.initialValues, unref(path), unref(modelRef));\r\n }\r\n function setInitialValue(value) {\r\n if (!form) {\r\n modelRef.value = value;\r\n return;\r\n }\r\n form.stageInitialValue(unref(path), value, true);\r\n }\r\n const initialValue = computed(resolveInitialValue);\r\n // if no form is associated, use a regular ref.\r\n if (!form) {\r\n const value = ref(resolveInitialValue());\r\n return {\r\n value,\r\n initialValue,\r\n setInitialValue,\r\n };\r\n }\r\n // to set the initial value, first check if there is a current value, if there is then use it.\r\n // otherwise use the configured initial value if it exists.\r\n // prioritize model value over form values\r\n // #3429\r\n const currentValue = modelValue ? unref(modelValue) : getFromPath(form.values, unref(path), unref(initialValue));\r\n form.stageInitialValue(unref(path), currentValue, true);\r\n // otherwise use a computed setter that triggers the `setFieldValue`\r\n const value = computed({\r\n get() {\r\n return getFromPath(form.values, unref(path));\r\n },\r\n set(newVal) {\r\n form.setFieldValue(unref(path), newVal);\r\n },\r\n });\r\n return {\r\n value,\r\n initialValue,\r\n setInitialValue,\r\n };\r\n}\r\n/**\r\n * Creates meta flags state and some associated effects with them\r\n */\r\nfunction _useFieldMeta(currentValue, initialValue, errors) {\r\n const meta = reactive({\r\n touched: false,\r\n pending: false,\r\n valid: true,\r\n validated: !!unref(errors).length,\r\n initialValue: computed(() => unref(initialValue)),\r\n dirty: computed(() => {\r\n return !isEqual(unref(currentValue), unref(initialValue));\r\n }),\r\n });\r\n watch(errors, value => {\r\n meta.valid = !value.length;\r\n }, {\r\n immediate: true,\r\n flush: 'sync',\r\n });\r\n return meta;\r\n}\r\n/**\r\n * Creates the error message state for the field state\r\n */\r\nfunction _useFieldErrors(path, form) {\r\n function normalizeErrors(messages) {\r\n if (!messages) {\r\n return [];\r\n }\r\n return Array.isArray(messages) ? messages : [messages];\r\n }\r\n if (!form) {\r\n const errors = ref([]);\r\n return {\r\n errors,\r\n errorMessage: computed(() => errors.value[0]),\r\n setErrors: (messages) => {\r\n errors.value = normalizeErrors(messages);\r\n },\r\n };\r\n }\r\n const errors = computed(() => form.errorBag.value[unref(path)] || []);\r\n return {\r\n errors,\r\n errorMessage: computed(() => errors.value[0]),\r\n setErrors: (messages) => {\r\n form.setFieldErrorBag(unref(path), normalizeErrors(messages));\r\n },\r\n };\r\n}\n\nfunction installDevtoolsPlugin(app) {\r\n if ((process.env.NODE_ENV !== 'production')) {\r\n setupDevtoolsPlugin({\r\n id: 'vee-validate-devtools-plugin',\r\n label: 'VeeValidate Plugin',\r\n packageName: 'vee-validate',\r\n homepage: 'https://vee-validate.logaretm.com/v4',\r\n app,\r\n logo: 'https://vee-validate.logaretm.com/v4/logo.png',\r\n }, setupApiHooks);\r\n }\r\n}\r\nconst DEVTOOLS_FORMS = {};\r\nconst DEVTOOLS_FIELDS = {};\r\nlet API;\r\nconst refreshInspector = throttle(() => {\r\n setTimeout(async () => {\r\n await nextTick();\r\n API === null || API === void 0 ? void 0 : API.sendInspectorState(INSPECTOR_ID);\r\n API === null || API === void 0 ? void 0 : API.sendInspectorTree(INSPECTOR_ID);\r\n }, 100);\r\n}, 100);\r\nfunction registerFormWithDevTools(form) {\r\n const vm = getCurrentInstance();\r\n if (!API) {\r\n const app = vm === null || vm === void 0 ? void 0 : vm.appContext.app;\r\n if (!app) {\r\n return;\r\n }\r\n installDevtoolsPlugin(app);\r\n }\r\n DEVTOOLS_FORMS[form.formId] = Object.assign({}, form);\r\n DEVTOOLS_FORMS[form.formId]._vm = vm;\r\n onUnmounted(() => {\r\n delete DEVTOOLS_FORMS[form.formId];\r\n refreshInspector();\r\n });\r\n refreshInspector();\r\n}\r\nfunction registerSingleFieldWithDevtools(field) {\r\n const vm = getCurrentInstance();\r\n if (!API) {\r\n const app = vm === null || vm === void 0 ? void 0 : vm.appContext.app;\r\n if (!app) {\r\n return;\r\n }\r\n installDevtoolsPlugin(app);\r\n }\r\n DEVTOOLS_FIELDS[field.id] = Object.assign({}, field);\r\n DEVTOOLS_FIELDS[field.id]._vm = vm;\r\n onUnmounted(() => {\r\n delete DEVTOOLS_FIELDS[field.id];\r\n refreshInspector();\r\n });\r\n refreshInspector();\r\n}\r\nconst INSPECTOR_ID = 'vee-validate-inspector';\r\nconst COLORS = {\r\n error: 0xbd4b4b,\r\n success: 0x06d77b,\r\n unknown: 0x54436b,\r\n white: 0xffffff,\r\n black: 0x000000,\r\n blue: 0x035397,\r\n purple: 0xb980f0,\r\n orange: 0xf5a962,\r\n gray: 0xbbbfca,\r\n};\r\nlet SELECTED_NODE = null;\r\nfunction setupApiHooks(api) {\r\n API = api;\r\n api.addInspector({\r\n id: INSPECTOR_ID,\r\n icon: 'rule',\r\n label: 'vee-validate',\r\n noSelectionText: 'Select a vee-validate node to inspect',\r\n actions: [\r\n {\r\n icon: 'done_outline',\r\n tooltip: 'Validate selected item',\r\n action: async () => {\r\n if (!SELECTED_NODE) {\r\n console.error('There is not a valid selected vee-validate node or component');\r\n return;\r\n }\r\n const result = await SELECTED_NODE.validate();\r\n console.log(result);\r\n },\r\n },\r\n {\r\n icon: 'delete_sweep',\r\n tooltip: 'Clear validation state of the selected item',\r\n action: () => {\r\n if (!SELECTED_NODE) {\r\n console.error('There is not a valid selected vee-validate node or component');\r\n return;\r\n }\r\n if ('id' in SELECTED_NODE) {\r\n SELECTED_NODE.resetField();\r\n return;\r\n }\r\n SELECTED_NODE.resetForm();\r\n },\r\n },\r\n ],\r\n });\r\n api.on.getInspectorTree(payload => {\r\n if (payload.inspectorId !== INSPECTOR_ID) {\r\n return;\r\n }\r\n const forms = Object.values(DEVTOOLS_FORMS);\r\n const fields = Object.values(DEVTOOLS_FIELDS);\r\n payload.rootNodes = [\r\n ...forms.map(mapFormForDevtoolsInspector),\r\n ...fields.map(field => mapFieldForDevtoolsInspector(field)),\r\n ];\r\n });\r\n api.on.getInspectorState((payload, ctx) => {\r\n if (payload.inspectorId !== INSPECTOR_ID || ctx.currentTab !== `custom-inspector:${INSPECTOR_ID}`) {\r\n return;\r\n }\r\n const { form, field, type } = decodeNodeId(payload.nodeId);\r\n if (form && type === 'form') {\r\n payload.state = buildFormState(form);\r\n SELECTED_NODE = form;\r\n return;\r\n }\r\n if (field && type === 'field') {\r\n payload.state = buildFieldState(field);\r\n SELECTED_NODE = field;\r\n return;\r\n }\r\n SELECTED_NODE = null;\r\n });\r\n}\r\nfunction mapFormForDevtoolsInspector(form) {\r\n const { textColor, bgColor } = getTagTheme(form);\r\n const formTreeNodes = {};\r\n Object.values(form.fieldsByPath.value).forEach(field => {\r\n const fieldInstance = Array.isArray(field) ? field[0] : field;\r\n if (!fieldInstance) {\r\n return;\r\n }\r\n setInPath(formTreeNodes, unref(fieldInstance.name), mapFieldForDevtoolsInspector(fieldInstance, form));\r\n });\r\n function buildFormTree(tree, path = []) {\r\n const key = [...path].pop();\r\n if ('id' in tree) {\r\n return Object.assign(Object.assign({}, tree), { label: key || tree.label });\r\n }\r\n if (isObject(tree)) {\r\n return {\r\n id: `${path.join('.')}`,\r\n label: key || '',\r\n children: Object.keys(tree).map(key => buildFormTree(tree[key], [...path, key])),\r\n };\r\n }\r\n if (Array.isArray(tree)) {\r\n return {\r\n id: `${path.join('.')}`,\r\n label: `${key}[]`,\r\n children: tree.map((c, idx) => buildFormTree(c, [...path, String(idx)])),\r\n };\r\n }\r\n return { id: '', label: '', children: [] };\r\n }\r\n const { children } = buildFormTree(formTreeNodes);\r\n return {\r\n id: encodeNodeId(form),\r\n label: 'Form',\r\n children,\r\n tags: [\r\n {\r\n label: 'Form',\r\n textColor,\r\n backgroundColor: bgColor,\r\n },\r\n {\r\n label: `${Object.keys(form.fieldsByPath.value).length} fields`,\r\n textColor: COLORS.white,\r\n backgroundColor: COLORS.unknown,\r\n },\r\n ],\r\n };\r\n}\r\nfunction mapFieldForDevtoolsInspector(field, form) {\r\n const fieldInstance = normalizeField(field);\r\n const { textColor, bgColor } = getTagTheme(fieldInstance);\r\n const isGroup = Array.isArray(field) && field.length > 1;\r\n return {\r\n id: encodeNodeId(form, fieldInstance, !isGroup),\r\n label: unref(fieldInstance.name),\r\n children: Array.isArray(field) ? field.map(fieldItem => mapFieldForDevtoolsInspector(fieldItem, form)) : undefined,\r\n tags: [\r\n isGroup\r\n ? undefined\r\n : {\r\n label: 'Field',\r\n textColor,\r\n backgroundColor: bgColor,\r\n },\r\n !form\r\n ? {\r\n label: 'Standalone',\r\n textColor: COLORS.black,\r\n backgroundColor: COLORS.gray,\r\n }\r\n : undefined,\r\n !isGroup && fieldInstance.type === 'checkbox'\r\n ? {\r\n label: 'Checkbox',\r\n textColor: COLORS.white,\r\n backgroundColor: COLORS.blue,\r\n }\r\n : undefined,\r\n !isGroup && fieldInstance.type === 'radio'\r\n ? {\r\n label: 'Radio',\r\n textColor: COLORS.white,\r\n backgroundColor: COLORS.purple,\r\n }\r\n : undefined,\r\n isGroup\r\n ? {\r\n label: 'Group',\r\n textColor: COLORS.black,\r\n backgroundColor: COLORS.orange,\r\n }\r\n : undefined,\r\n ].filter(Boolean),\r\n };\r\n}\r\nfunction encodeNodeId(form, field, encodeIndex = true) {\r\n const fieldPath = form ? unref(field === null || field === void 0 ? void 0 : field.name) : field === null || field === void 0 ? void 0 : field.id;\r\n const fieldGroup = fieldPath ? form === null || form === void 0 ? void 0 : form.fieldsByPath.value[fieldPath] : undefined;\r\n let idx;\r\n if (encodeIndex && field && Array.isArray(fieldGroup)) {\r\n idx = fieldGroup.indexOf(field);\r\n }\r\n const idObject = { f: form === null || form === void 0 ? void 0 : form.formId, ff: fieldPath, idx, type: field ? 'field' : 'form' };\r\n return btoa(JSON.stringify(idObject));\r\n}\r\nfunction decodeNodeId(nodeId) {\r\n try {\r\n const idObject = JSON.parse(atob(nodeId));\r\n const form = DEVTOOLS_FORMS[idObject.f];\r\n if (!form && idObject.ff) {\r\n const field = DEVTOOLS_FIELDS[idObject.ff];\r\n if (!field) {\r\n return {};\r\n }\r\n return {\r\n type: idObject.type,\r\n field,\r\n };\r\n }\r\n if (!form) {\r\n return {};\r\n }\r\n const fieldGroup = form.fieldsByPath.value[idObject.ff];\r\n return {\r\n type: idObject.type,\r\n form,\r\n field: Array.isArray(fieldGroup) ? fieldGroup[idObject.idx || 0] : fieldGroup,\r\n };\r\n }\r\n catch (err) {\r\n // console.error(`Devtools: [vee-validate] Failed to parse node id ${nodeId}`);\r\n }\r\n return {};\r\n}\r\nfunction buildFieldState(field) {\r\n const { errors, meta, value } = field;\r\n return {\r\n 'Field state': [\r\n { key: 'errors', value: errors.value },\r\n {\r\n key: 'initialValue',\r\n value: meta.initialValue,\r\n },\r\n {\r\n key: 'currentValue',\r\n value: value.value,\r\n },\r\n {\r\n key: 'touched',\r\n value: meta.touched,\r\n },\r\n {\r\n key: 'dirty',\r\n value: meta.dirty,\r\n },\r\n {\r\n key: 'valid',\r\n value: meta.valid,\r\n },\r\n ],\r\n };\r\n}\r\nfunction buildFormState(form) {\r\n const { errorBag, meta, values, isSubmitting, submitCount } = form;\r\n return {\r\n 'Form state': [\r\n {\r\n key: 'submitCount',\r\n value: submitCount.value,\r\n },\r\n {\r\n key: 'isSubmitting',\r\n value: isSubmitting.value,\r\n },\r\n {\r\n key: 'touched',\r\n value: meta.value.touched,\r\n },\r\n {\r\n key: 'dirty',\r\n value: meta.value.dirty,\r\n },\r\n {\r\n key: 'valid',\r\n value: meta.value.valid,\r\n },\r\n {\r\n key: 'initialValues',\r\n value: meta.value.initialValues,\r\n },\r\n {\r\n key: 'currentValues',\r\n value: values,\r\n },\r\n {\r\n key: 'errors',\r\n value: keysOf(errorBag.value).reduce((acc, key) => {\r\n var _a;\r\n const message = (_a = errorBag.value[key]) === null || _a === void 0 ? void 0 : _a[0];\r\n if (message) {\r\n acc[key] = message;\r\n }\r\n return acc;\r\n }, {}),\r\n },\r\n ],\r\n };\r\n}\r\n/**\r\n * Resolves the tag color based on the form state\r\n */\r\nfunction getTagTheme(fieldOrForm) {\r\n // const fallbackColors = {\r\n // bgColor: COLORS.unknown,\r\n // textColor: COLORS.white,\r\n // };\r\n const isValid = 'id' in fieldOrForm ? fieldOrForm.meta.valid : fieldOrForm.meta.value.valid;\r\n return {\r\n bgColor: isValid ? COLORS.success : COLORS.error,\r\n textColor: isValid ? COLORS.black : COLORS.white,\r\n };\r\n}\n\n/**\r\n * Creates a field composite.\r\n */\r\nfunction useField(name, rules, opts) {\r\n if (hasCheckedAttr(opts === null || opts === void 0 ? void 0 : opts.type)) {\r\n return useCheckboxField(name, rules, opts);\r\n }\r\n return _useField(name, rules, opts);\r\n}\r\nfunction _useField(name, rules, opts) {\r\n const { initialValue: modelValue, validateOnMount, bails, type, checkedValue, label, validateOnValueUpdate, uncheckedValue, controlled, keepValueOnUnmount, modelPropName, syncVModel, form: controlForm, } = normalizeOptions(unref(name), opts);\r\n const injectedForm = controlled ? injectWithSelf(FormContextKey) : undefined;\r\n const form = controlForm || injectedForm;\r\n // a flag indicating if the field is about to be removed/unmounted.\r\n let markedForRemoval = false;\r\n const { id, value, initialValue, meta, setState, errors, errorMessage } = useFieldState(name, {\r\n modelValue,\r\n form,\r\n });\r\n if (syncVModel) {\r\n useVModel({ value, prop: modelPropName, handleChange });\r\n }\r\n /**\r\n * Handles common onBlur meta update\r\n */\r\n const handleBlur = () => {\r\n meta.touched = true;\r\n };\r\n const normalizedRules = computed(() => {\r\n let rulesValue = unref(rules);\r\n const schema = unref(form === null || form === void 0 ? void 0 : form.schema);\r\n if (schema && !isYupValidator(schema)) {\r\n rulesValue = extractRuleFromSchema(schema, unref(name)) || rulesValue;\r\n }\r\n if (isYupValidator(rulesValue) || isCallable(rulesValue) || Array.isArray(rulesValue)) {\r\n return rulesValue;\r\n }\r\n return normalizeRules(rulesValue);\r\n });\r\n async function validateCurrentValue(mode) {\r\n var _a, _b;\r\n if (form === null || form === void 0 ? void 0 : form.validateSchema) {\r\n return (_a = (await form.validateSchema(mode)).results[unref(name)]) !== null && _a !== void 0 ? _a : { valid: true, errors: [] };\r\n }\r\n return validate(value.value, normalizedRules.value, {\r\n name: unref(name),\r\n label: unref(label),\r\n values: (_b = form === null || form === void 0 ? void 0 : form.values) !== null && _b !== void 0 ? _b : {},\r\n bails,\r\n });\r\n }\r\n const validateWithStateMutation = withLatest(async () => {\r\n meta.pending = true;\r\n meta.validated = true;\r\n return validateCurrentValue('validated-only');\r\n }, result => {\r\n if (markedForRemoval) {\r\n result.valid = true;\r\n result.errors = [];\r\n }\r\n setState({ errors: result.errors });\r\n meta.pending = false;\r\n return result;\r\n });\r\n const validateValidStateOnly = withLatest(async () => {\r\n return validateCurrentValue('silent');\r\n }, result => {\r\n if (markedForRemoval) {\r\n result.valid = true;\r\n }\r\n meta.valid = result.valid;\r\n return result;\r\n });\r\n function validate$1(opts) {\r\n if ((opts === null || opts === void 0 ? void 0 : opts.mode) === 'silent') {\r\n return validateValidStateOnly();\r\n }\r\n return validateWithStateMutation();\r\n }\r\n // Common input/change event handler\r\n function handleChange(e, shouldValidate = true) {\r\n const newValue = normalizeEventValue(e);\r\n value.value = newValue;\r\n if (!validateOnValueUpdate && shouldValidate) {\r\n validateWithStateMutation();\r\n }\r\n }\r\n // Runs the initial validation\r\n onMounted(() => {\r\n if (validateOnMount) {\r\n return validateWithStateMutation();\r\n }\r\n // validate self initially if no form was handling this\r\n // forms should have their own initial silent validation run to make things more efficient\r\n if (!form || !form.validateSchema) {\r\n validateValidStateOnly();\r\n }\r\n });\r\n function setTouched(isTouched) {\r\n meta.touched = isTouched;\r\n }\r\n let unwatchValue;\r\n let lastWatchedValue = klona(value.value);\r\n function watchValue() {\r\n unwatchValue = watch(value, (val, oldVal) => {\r\n if (isEqual(val, oldVal) && isEqual(val, lastWatchedValue)) {\r\n return;\r\n }\r\n const validateFn = validateOnValueUpdate ? validateWithStateMutation : validateValidStateOnly;\r\n validateFn();\r\n lastWatchedValue = klona(val);\r\n }, {\r\n deep: true,\r\n });\r\n }\r\n watchValue();\r\n function resetField(state) {\r\n var _a;\r\n unwatchValue === null || unwatchValue === void 0 ? void 0 : unwatchValue();\r\n const newValue = state && 'value' in state ? state.value : initialValue.value;\r\n setState({\r\n value: klona(newValue),\r\n initialValue: klona(newValue),\r\n touched: (_a = state === null || state === void 0 ? void 0 : state.touched) !== null && _a !== void 0 ? _a : false,\r\n errors: (state === null || state === void 0 ? void 0 : state.errors) || [],\r\n });\r\n meta.pending = false;\r\n meta.validated = false;\r\n validateValidStateOnly();\r\n // need to watch at next tick to avoid triggering the value watcher\r\n nextTick(() => {\r\n watchValue();\r\n });\r\n }\r\n function setValue(newValue) {\r\n value.value = newValue;\r\n }\r\n function setErrors(errors) {\r\n setState({ errors: Array.isArray(errors) ? errors : [errors] });\r\n }\r\n const field = {\r\n id,\r\n name,\r\n label,\r\n value,\r\n meta,\r\n errors,\r\n errorMessage,\r\n type,\r\n checkedValue,\r\n uncheckedValue,\r\n bails,\r\n keepValueOnUnmount,\r\n resetField,\r\n handleReset: () => resetField(),\r\n validate: validate$1,\r\n handleChange,\r\n handleBlur,\r\n setState,\r\n setTouched,\r\n setErrors,\r\n setValue,\r\n };\r\n provide(FieldContextKey, field);\r\n if (isRef(rules) && typeof unref(rules) !== 'function') {\r\n watch(rules, (value, oldValue) => {\r\n if (isEqual(value, oldValue)) {\r\n return;\r\n }\r\n meta.validated ? validateWithStateMutation() : validateValidStateOnly();\r\n }, {\r\n deep: true,\r\n });\r\n }\r\n if ((process.env.NODE_ENV !== 'production')) {\r\n field._vm = getCurrentInstance();\r\n watch(() => (Object.assign(Object.assign({ errors: errors.value }, meta), { value: value.value })), refreshInspector, {\r\n deep: true,\r\n });\r\n if (!form) {\r\n registerSingleFieldWithDevtools(field);\r\n }\r\n }\r\n // if no associated form return the field API immediately\r\n if (!form) {\r\n return field;\r\n }\r\n // associate the field with the given form\r\n form.register(field);\r\n onBeforeUnmount(() => {\r\n markedForRemoval = true;\r\n form.unregister(field);\r\n });\r\n // extract cross-field dependencies in a computed prop\r\n const dependencies = computed(() => {\r\n const rulesVal = normalizedRules.value;\r\n // is falsy, a function schema or a yup schema\r\n if (!rulesVal || isCallable(rulesVal) || isYupValidator(rulesVal) || Array.isArray(rulesVal)) {\r\n return {};\r\n }\r\n return Object.keys(rulesVal).reduce((acc, rule) => {\r\n const deps = extractLocators(rulesVal[rule])\r\n .map((dep) => dep.__locatorRef)\r\n .reduce((depAcc, depName) => {\r\n const depValue = getFromPath(form.values, depName) || form.values[depName];\r\n if (depValue !== undefined) {\r\n depAcc[depName] = depValue;\r\n }\r\n return depAcc;\r\n }, {});\r\n Object.assign(acc, deps);\r\n return acc;\r\n }, {});\r\n });\r\n // Adds a watcher that runs the validation whenever field dependencies change\r\n watch(dependencies, (deps, oldDeps) => {\r\n // Skip if no dependencies or if the field wasn't manipulated\r\n if (!Object.keys(deps).length) {\r\n return;\r\n }\r\n const shouldValidate = !isEqual(deps, oldDeps);\r\n if (shouldValidate) {\r\n meta.validated ? validateWithStateMutation() : validateValidStateOnly();\r\n }\r\n });\r\n return field;\r\n}\r\n/**\r\n * Normalizes partial field options to include the full options\r\n */\r\nfunction normalizeOptions(name, opts) {\r\n const defaults = () => ({\r\n initialValue: undefined,\r\n validateOnMount: false,\r\n bails: true,\r\n label: name,\r\n validateOnValueUpdate: true,\r\n keepValueOnUnmount: undefined,\r\n modelPropName: 'modelValue',\r\n syncVModel: true,\r\n controlled: true,\r\n });\r\n if (!opts) {\r\n return defaults();\r\n }\r\n // TODO: Deprecate this in next major release\r\n const checkedValue = 'valueProp' in opts ? opts.valueProp : opts.checkedValue;\r\n const controlled = 'standalone' in opts ? !opts.standalone : opts.controlled;\r\n return Object.assign(Object.assign(Object.assign({}, defaults()), (opts || {})), { controlled: controlled !== null && controlled !== void 0 ? controlled : true, checkedValue });\r\n}\r\n/**\r\n * Extracts the validation rules from a schema\r\n */\r\nfunction extractRuleFromSchema(schema, fieldName) {\r\n // no schema at all\r\n if (!schema) {\r\n return undefined;\r\n }\r\n // there is a key on the schema object for this field\r\n return schema[fieldName];\r\n}\r\nfunction useCheckboxField(name, rules, opts) {\r\n const form = !(opts === null || opts === void 0 ? void 0 : opts.standalone) ? injectWithSelf(FormContextKey) : undefined;\r\n const checkedValue = opts === null || opts === void 0 ? void 0 : opts.checkedValue;\r\n const uncheckedValue = opts === null || opts === void 0 ? void 0 : opts.uncheckedValue;\r\n function patchCheckboxApi(field) {\r\n const handleChange = field.handleChange;\r\n const checked = computed(() => {\r\n const currentValue = unref(field.value);\r\n const checkedVal = unref(checkedValue);\r\n return Array.isArray(currentValue)\r\n ? currentValue.findIndex(v => isEqual(v, checkedVal)) >= 0\r\n : isEqual(checkedVal, currentValue);\r\n });\r\n function handleCheckboxChange(e, shouldValidate = true) {\r\n var _a;\r\n if (checked.value === ((_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.checked)) {\r\n if (shouldValidate) {\r\n field.validate();\r\n }\r\n return;\r\n }\r\n let newValue = normalizeEventValue(e);\r\n // Single checkbox field without a form to toggle it's value\r\n if (!form) {\r\n newValue = resolveNextCheckboxValue(unref(field.value), unref(checkedValue), unref(uncheckedValue));\r\n }\r\n handleChange(newValue, shouldValidate);\r\n }\r\n return Object.assign(Object.assign({}, field), { checked,\r\n checkedValue,\r\n uncheckedValue, handleChange: handleCheckboxChange });\r\n }\r\n return patchCheckboxApi(_useField(name, rules, opts));\r\n}\r\nfunction useVModel({ prop, value, handleChange }) {\r\n const vm = getCurrentInstance();\r\n /* istanbul ignore next */\r\n if (!vm) {\r\n if ((process.env.NODE_ENV !== 'production')) {\r\n console.warn('Failed to setup model events because `useField` was not called in setup.');\r\n }\r\n return;\r\n }\r\n const propName = prop || 'modelValue';\r\n const emitName = `update:${propName}`;\r\n // Component doesn't have a model prop setup (must be defined on the props)\r\n if (!(propName in vm.props)) {\r\n return;\r\n }\r\n watch(value, newValue => {\r\n if (isEqual(newValue, getCurrentModelValue(vm, propName))) {\r\n return;\r\n }\r\n vm.emit(emitName, newValue);\r\n });\r\n watch(() => getCurrentModelValue(vm, propName), propValue => {\r\n if (propValue === IS_ABSENT && value.value === undefined) {\r\n return;\r\n }\r\n const newValue = propValue === IS_ABSENT ? undefined : propValue;\r\n if (isEqual(newValue, applyModelModifiers(value.value, vm.props.modelModifiers))) {\r\n return;\r\n }\r\n handleChange(newValue);\r\n });\r\n}\r\nfunction getCurrentModelValue(vm, propName) {\r\n return vm.props[propName];\r\n}\n\nconst FieldImpl = defineComponent({\r\n name: 'Field',\r\n inheritAttrs: false,\r\n props: {\r\n as: {\r\n type: [String, Object],\r\n default: undefined,\r\n },\r\n name: {\r\n type: String,\r\n required: true,\r\n },\r\n rules: {\r\n type: [Object, String, Function],\r\n default: undefined,\r\n },\r\n validateOnMount: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n validateOnBlur: {\r\n type: Boolean,\r\n default: undefined,\r\n },\r\n validateOnChange: {\r\n type: Boolean,\r\n default: undefined,\r\n },\r\n validateOnInput: {\r\n type: Boolean,\r\n default: undefined,\r\n },\r\n validateOnModelUpdate: {\r\n type: Boolean,\r\n default: undefined,\r\n },\r\n bails: {\r\n type: Boolean,\r\n default: () => getConfig().bails,\r\n },\r\n label: {\r\n type: String,\r\n default: undefined,\r\n },\r\n uncheckedValue: {\r\n type: null,\r\n default: undefined,\r\n },\r\n modelValue: {\r\n type: null,\r\n default: IS_ABSENT,\r\n },\r\n modelModifiers: {\r\n type: null,\r\n default: () => ({}),\r\n },\r\n 'onUpdate:modelValue': {\r\n type: null,\r\n default: undefined,\r\n },\r\n standalone: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n keepValue: {\r\n type: Boolean,\r\n default: undefined,\r\n },\r\n },\r\n setup(props, ctx) {\r\n const rules = toRef(props, 'rules');\r\n const name = toRef(props, 'name');\r\n const label = toRef(props, 'label');\r\n const uncheckedValue = toRef(props, 'uncheckedValue');\r\n const keepValue = toRef(props, 'keepValue');\r\n const { errors, value, errorMessage, validate: validateField, handleChange, handleBlur, setTouched, resetField, handleReset, meta, checked, setErrors, } = useField(name, rules, {\r\n validateOnMount: props.validateOnMount,\r\n bails: props.bails,\r\n standalone: props.standalone,\r\n type: ctx.attrs.type,\r\n initialValue: resolveInitialValue(props, ctx),\r\n // Only for checkboxes and radio buttons\r\n checkedValue: ctx.attrs.value,\r\n uncheckedValue,\r\n label,\r\n validateOnValueUpdate: false,\r\n keepValueOnUnmount: keepValue,\r\n });\r\n // If there is a v-model applied on the component we need to emit the `update:modelValue` whenever the value binding changes\r\n const onChangeHandler = function handleChangeWithModel(e, shouldValidate = true) {\r\n handleChange(e, shouldValidate);\r\n ctx.emit('update:modelValue', value.value);\r\n };\r\n const handleInput = (e) => {\r\n if (!hasCheckedAttr(ctx.attrs.type)) {\r\n value.value = normalizeEventValue(e);\r\n }\r\n };\r\n const onInputHandler = function handleInputWithModel(e) {\r\n handleInput(e);\r\n ctx.emit('update:modelValue', value.value);\r\n };\r\n const fieldProps = computed(() => {\r\n const { validateOnInput, validateOnChange, validateOnBlur, validateOnModelUpdate } = resolveValidationTriggers(props);\r\n const baseOnBlur = [handleBlur, ctx.attrs.onBlur, validateOnBlur ? validateField : undefined].filter(Boolean);\r\n const baseOnInput = [(e) => onChangeHandler(e, validateOnInput), ctx.attrs.onInput].filter(Boolean);\r\n const baseOnChange = [(e) => onChangeHandler(e, validateOnChange), ctx.attrs.onChange].filter(Boolean);\r\n const attrs = {\r\n name: props.name,\r\n onBlur: baseOnBlur,\r\n onInput: baseOnInput,\r\n onChange: baseOnChange,\r\n };\r\n attrs['onUpdate:modelValue'] = e => onChangeHandler(e, validateOnModelUpdate);\r\n if (hasCheckedAttr(ctx.attrs.type) && checked) {\r\n attrs.checked = checked.value;\r\n }\r\n const tag = resolveTag(props, ctx);\r\n if (shouldHaveValueBinding(tag, ctx.attrs)) {\r\n attrs.value = value.value;\r\n }\r\n return attrs;\r\n });\r\n function slotProps() {\r\n return {\r\n field: fieldProps.value,\r\n value: value.value,\r\n meta,\r\n errors: errors.value,\r\n errorMessage: errorMessage.value,\r\n validate: validateField,\r\n resetField,\r\n handleChange: onChangeHandler,\r\n handleInput: onInputHandler,\r\n handleReset,\r\n handleBlur,\r\n setTouched,\r\n setErrors,\r\n };\r\n }\r\n ctx.expose({\r\n setErrors,\r\n setTouched,\r\n reset: resetField,\r\n validate: validateField,\r\n handleChange,\r\n });\r\n return () => {\r\n const tag = resolveDynamicComponent(resolveTag(props, ctx));\r\n const children = normalizeChildren(tag, ctx, slotProps);\r\n if (tag) {\r\n return h(tag, Object.assign(Object.assign({}, ctx.attrs), fieldProps.value), children);\r\n }\r\n return children;\r\n };\r\n },\r\n});\r\nfunction resolveTag(props, ctx) {\r\n let tag = props.as || '';\r\n if (!props.as && !ctx.slots.default) {\r\n tag = 'input';\r\n }\r\n return tag;\r\n}\r\nfunction resolveValidationTriggers(props) {\r\n var _a, _b, _c, _d;\r\n const { validateOnInput, validateOnChange, validateOnBlur, validateOnModelUpdate } = getConfig();\r\n return {\r\n validateOnInput: (_a = props.validateOnInput) !== null && _a !== void 0 ? _a : validateOnInput,\r\n validateOnChange: (_b = props.validateOnChange) !== null && _b !== void 0 ? _b : validateOnChange,\r\n validateOnBlur: (_c = props.validateOnBlur) !== null && _c !== void 0 ? _c : validateOnBlur,\r\n validateOnModelUpdate: (_d = props.validateOnModelUpdate) !== null && _d !== void 0 ? _d : validateOnModelUpdate,\r\n };\r\n}\r\nfunction resolveInitialValue(props, ctx) {\r\n // Gets the initial value either from `value` prop/attr or `v-model` binding (modelValue)\r\n // For checkboxes and radio buttons it will always be the model value not the `value` attribute\r\n if (!hasCheckedAttr(ctx.attrs.type)) {\r\n return isPropPresent(props, 'modelValue') ? props.modelValue : ctx.attrs.value;\r\n }\r\n return isPropPresent(props, 'modelValue') ? props.modelValue : undefined;\r\n}\r\nconst Field = FieldImpl;\n\nlet FORM_COUNTER = 0;\r\nfunction useForm(opts) {\r\n var _a;\r\n const formId = FORM_COUNTER++;\r\n const controlledModelPaths = new Set();\r\n // Prevents fields from double resetting their values, which causes checkboxes to toggle their initial value\r\n // TODO: This won't be needed if we centralize all the state inside the `form` for form inputs\r\n let RESET_LOCK = false;\r\n // A lookup containing fields or field groups\r\n const fieldsByPath = ref({});\r\n // If the form is currently submitting\r\n const isSubmitting = ref(false);\r\n // The number of times the user tried to submit the form\r\n const submitCount = ref(0);\r\n // field arrays managed by this form\r\n const fieldArrays = [];\r\n // a private ref for all form values\r\n const formValues = reactive(klona(unref(opts === null || opts === void 0 ? void 0 : opts.initialValues) || {}));\r\n // the source of errors for the form fields\r\n const { errorBag, setErrorBag, setFieldErrorBag } = useErrorBag(opts === null || opts === void 0 ? void 0 : opts.initialErrors);\r\n // Gets the first error of each field\r\n const errors = computed(() => {\r\n return keysOf(errorBag.value).reduce((acc, key) => {\r\n const bag = errorBag.value[key];\r\n if (bag && bag.length) {\r\n acc[key] = bag[0];\r\n }\r\n return acc;\r\n }, {});\r\n });\r\n function getFirstFieldAtPath(path) {\r\n const fieldOrGroup = fieldsByPath.value[path];\r\n return Array.isArray(fieldOrGroup) ? fieldOrGroup[0] : fieldOrGroup;\r\n }\r\n function fieldExists(path) {\r\n return !!fieldsByPath.value[path];\r\n }\r\n /**\r\n * Holds a computed reference to all fields names and labels\r\n */\r\n const fieldNames = computed(() => {\r\n return keysOf(fieldsByPath.value).reduce((names, path) => {\r\n const field = getFirstFieldAtPath(path);\r\n if (field) {\r\n names[path] = { name: unref(field.name) || '', label: unref(field.label) || '' };\r\n }\r\n return names;\r\n }, {});\r\n });\r\n const fieldBailsMap = computed(() => {\r\n return keysOf(fieldsByPath.value).reduce((map, path) => {\r\n var _a;\r\n const field = getFirstFieldAtPath(path);\r\n if (field) {\r\n map[path] = (_a = field.bails) !== null && _a !== void 0 ? _a : true;\r\n }\r\n return map;\r\n }, {});\r\n });\r\n // mutable non-reactive reference to initial errors\r\n // we need this to process initial errors then unset them\r\n const initialErrors = Object.assign({}, ((opts === null || opts === void 0 ? void 0 : opts.initialErrors) || {}));\r\n const keepValuesOnUnmount = (_a = opts === null || opts === void 0 ? void 0 : opts.keepValuesOnUnmount) !== null && _a !== void 0 ? _a : false;\r\n // initial form values\r\n const { initialValues, originalInitialValues, setInitialValues } = useFormInitialValues(fieldsByPath, formValues, opts === null || opts === void 0 ? void 0 : opts.initialValues);\r\n // form meta aggregations\r\n const meta = useFormMeta(fieldsByPath, formValues, originalInitialValues, errors);\r\n const controlledValues = computed(() => {\r\n return [...controlledModelPaths, ...keysOf(fieldsByPath.value)].reduce((acc, path) => {\r\n const value = getFromPath(formValues, path);\r\n setInPath(acc, path, value);\r\n return acc;\r\n }, {});\r\n });\r\n const schema = opts === null || opts === void 0 ? void 0 : opts.validationSchema;\r\n /**\r\n * Batches validation runs in 5ms batches\r\n * Must have two distinct batch queues to make sure they don't override each other settings #3783\r\n */\r\n const debouncedSilentValidation = debounceAsync(_validateSchema, 5);\r\n const debouncedValidation = debounceAsync(_validateSchema, 5);\r\n const validateSchema = withLatest(async (mode) => {\r\n return (await mode) === 'silent' ? debouncedSilentValidation() : debouncedValidation();\r\n }, (formResult, [mode]) => {\r\n // fields by id lookup\r\n const fieldsById = formCtx.fieldsByPath.value || {};\r\n // errors fields names, we need it to also check if custom errors are updated\r\n const currentErrorsPaths = keysOf(formCtx.errorBag.value);\r\n // collect all the keys from the schema and all fields\r\n // this ensures we have a complete keymap of all the fields\r\n const paths = [\r\n ...new Set([...keysOf(formResult.results), ...keysOf(fieldsById), ...currentErrorsPaths]),\r\n ];\r\n // aggregates the paths into a single result object while applying the results on the fields\r\n return paths.reduce((validation, path) => {\r\n const field = fieldsById[path];\r\n const messages = (formResult.results[path] || { errors: [] }).errors;\r\n const fieldResult = {\r\n errors: messages,\r\n valid: !messages.length,\r\n };\r\n validation.results[path] = fieldResult;\r\n if (!fieldResult.valid) {\r\n validation.errors[path] = fieldResult.errors[0];\r\n }\r\n // field not rendered\r\n if (!field) {\r\n setFieldError(path, messages);\r\n return validation;\r\n }\r\n // always update the valid flag regardless of the mode\r\n applyFieldMutation(field, f => (f.meta.valid = fieldResult.valid));\r\n if (mode === 'silent') {\r\n return validation;\r\n }\r\n const wasValidated = Array.isArray(field) ? field.some(f => f.meta.validated) : field.meta.validated;\r\n if (mode === 'validated-only' && !wasValidated) {\r\n return validation;\r\n }\r\n applyFieldMutation(field, f => f.setState({ errors: fieldResult.errors }));\r\n return validation;\r\n }, { valid: formResult.valid, results: {}, errors: {} });\r\n });\r\n function makeSubmissionFactory(onlyControlled) {\r\n return function submitHandlerFactory(fn, onValidationError) {\r\n return function submissionHandler(e) {\r\n if (e instanceof Event) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }\r\n // Touch all fields\r\n setTouched(keysOf(fieldsByPath.value).reduce((acc, field) => {\r\n acc[field] = true;\r\n return acc;\r\n }, {}));\r\n isSubmitting.value = true;\r\n submitCount.value++;\r\n return validate()\r\n .then(result => {\r\n const values = klona(formValues);\r\n if (result.valid && typeof fn === 'function') {\r\n const controlled = klona(controlledValues.value);\r\n return fn(onlyControlled ? controlled : values, {\r\n evt: e,\r\n controlledValues: controlled,\r\n setErrors,\r\n setFieldError,\r\n setTouched,\r\n setFieldTouched,\r\n setValues,\r\n setFieldValue,\r\n resetForm,\r\n resetField,\r\n });\r\n }\r\n if (!result.valid && typeof onValidationError === 'function') {\r\n onValidationError({\r\n values,\r\n evt: e,\r\n errors: result.errors,\r\n results: result.results,\r\n });\r\n }\r\n })\r\n .then(returnVal => {\r\n isSubmitting.value = false;\r\n return returnVal;\r\n }, err => {\r\n isSubmitting.value = false;\r\n // re-throw the err so it doesn't go silent\r\n throw err;\r\n });\r\n };\r\n };\r\n }\r\n const handleSubmitImpl = makeSubmissionFactory(false);\r\n const handleSubmit = handleSubmitImpl;\r\n handleSubmit.withControlled = makeSubmissionFactory(true);\r\n const formCtx = {\r\n formId,\r\n fieldsByPath,\r\n values: formValues,\r\n controlledValues,\r\n errorBag,\r\n errors,\r\n schema,\r\n submitCount,\r\n meta,\r\n isSubmitting,\r\n fieldArrays,\r\n keepValuesOnUnmount,\r\n validateSchema: unref(schema) ? validateSchema : undefined,\r\n validate,\r\n register: registerField,\r\n unregister: unregisterField,\r\n setFieldErrorBag,\r\n validateField,\r\n setFieldValue,\r\n setValues,\r\n setErrors,\r\n setFieldError,\r\n setFieldTouched,\r\n setTouched,\r\n resetForm,\r\n resetField,\r\n handleSubmit,\r\n stageInitialValue,\r\n unsetInitialValue,\r\n setFieldInitialValue,\r\n useFieldModel,\r\n };\r\n function isFieldGroup(fieldOrGroup) {\r\n return Array.isArray(fieldOrGroup);\r\n }\r\n function applyFieldMutation(fieldOrGroup, mutation) {\r\n if (Array.isArray(fieldOrGroup)) {\r\n return fieldOrGroup.forEach(mutation);\r\n }\r\n return mutation(fieldOrGroup);\r\n }\r\n function mutateAllFields(mutation) {\r\n Object.values(fieldsByPath.value).forEach(field => {\r\n if (!field) {\r\n return;\r\n }\r\n // avoid resetting the field values, because they should've been reset already.\r\n applyFieldMutation(field, mutation);\r\n });\r\n }\r\n /**\r\n * Manually sets an error message on a specific field\r\n */\r\n function setFieldError(field, message) {\r\n setFieldErrorBag(field, message);\r\n }\r\n /**\r\n * Sets errors for the fields specified in the object\r\n */\r\n function setErrors(fields) {\r\n setErrorBag(fields);\r\n }\r\n /**\r\n * Sets a single field value\r\n */\r\n function setFieldValue(field, value, { force } = { force: false }) {\r\n var _a;\r\n const fieldInstance = fieldsByPath.value[field];\r\n const clonedValue = klona(value);\r\n // field wasn't found, create a virtual field as a placeholder\r\n if (!fieldInstance) {\r\n setInPath(formValues, field, clonedValue);\r\n return;\r\n }\r\n if (isFieldGroup(fieldInstance) && ((_a = fieldInstance[0]) === null || _a === void 0 ? void 0 : _a.type) === 'checkbox' && !Array.isArray(value)) {\r\n // Multiple checkboxes, and only one of them got updated\r\n const newValue = klona(resolveNextCheckboxValue(getFromPath(formValues, field) || [], value, undefined));\r\n setInPath(formValues, field, newValue);\r\n return;\r\n }\r\n let newValue = clonedValue;\r\n // Single Checkbox: toggles the field value unless the field is being reset then force it\r\n if (!isFieldGroup(fieldInstance) && fieldInstance.type === 'checkbox' && !force && !RESET_LOCK) {\r\n newValue = klona(resolveNextCheckboxValue(getFromPath(formValues, field), value, unref(fieldInstance.uncheckedValue)));\r\n }\r\n setInPath(formValues, field, newValue);\r\n }\r\n /**\r\n * Sets multiple fields values\r\n */\r\n function setValues(fields) {\r\n // clean up old values\r\n keysOf(formValues).forEach(key => {\r\n delete formValues[key];\r\n });\r\n // set up new values\r\n keysOf(fields).forEach(path => {\r\n setFieldValue(path, fields[path]);\r\n });\r\n // regenerate the arrays when the form values change\r\n fieldArrays.forEach(f => f && f.reset());\r\n }\r\n function createModel(path) {\r\n const { value } = _useFieldValue(path, undefined, formCtx);\r\n watch(value, () => {\r\n if (!fieldExists(unref(path))) {\r\n validate({ mode: 'validated-only' });\r\n }\r\n }, {\r\n deep: true,\r\n });\r\n controlledModelPaths.add(unref(path));\r\n return value;\r\n }\r\n function useFieldModel(path) {\r\n if (!Array.isArray(path)) {\r\n return createModel(path);\r\n }\r\n return path.map(createModel);\r\n }\r\n /**\r\n * Sets the touched meta state on a field\r\n */\r\n function setFieldTouched(field, isTouched) {\r\n const fieldInstance = fieldsByPath.value[field];\r\n if (fieldInstance) {\r\n applyFieldMutation(fieldInstance, f => f.setTouched(isTouched));\r\n }\r\n }\r\n /**\r\n * Sets the touched meta state on multiple fields\r\n */\r\n function setTouched(fields) {\r\n keysOf(fields).forEach(field => {\r\n setFieldTouched(field, !!fields[field]);\r\n });\r\n }\r\n function resetField(field, state) {\r\n const fieldInstance = fieldsByPath.value[field];\r\n if (fieldInstance) {\r\n applyFieldMutation(fieldInstance, f => f.resetField(state));\r\n }\r\n }\r\n /**\r\n * Resets all fields\r\n */\r\n function resetForm(state) {\r\n RESET_LOCK = true;\r\n // Reset all field states first\r\n mutateAllFields(f => f.resetField());\r\n // reset values\r\n const newValues = (state === null || state === void 0 ? void 0 : state.values) ? state.values : originalInitialValues.value;\r\n setInitialValues(newValues);\r\n setValues(newValues);\r\n if (state === null || state === void 0 ? void 0 : state.touched) {\r\n setTouched(state.touched);\r\n }\r\n setErrors((state === null || state === void 0 ? void 0 : state.errors) || {});\r\n submitCount.value = (state === null || state === void 0 ? void 0 : state.submitCount) || 0;\r\n nextTick(() => {\r\n RESET_LOCK = false;\r\n });\r\n }\r\n function insertFieldAtPath(field, path) {\r\n const rawField = markRaw(field);\r\n const fieldPath = path;\r\n // first field at that path\r\n if (!fieldsByPath.value[fieldPath]) {\r\n fieldsByPath.value[fieldPath] = rawField;\r\n return;\r\n }\r\n const fieldAtPath = fieldsByPath.value[fieldPath];\r\n if (fieldAtPath && !Array.isArray(fieldAtPath)) {\r\n fieldsByPath.value[fieldPath] = [fieldAtPath];\r\n }\r\n // add the new array to that path\r\n fieldsByPath.value[fieldPath] = [...fieldsByPath.value[fieldPath], rawField];\r\n }\r\n function removeFieldFromPath(field, path) {\r\n const fieldPath = path;\r\n const fieldAtPath = fieldsByPath.value[fieldPath];\r\n if (!fieldAtPath) {\r\n return;\r\n }\r\n // same field at path\r\n if (!isFieldGroup(fieldAtPath) && field.id === fieldAtPath.id) {\r\n delete fieldsByPath.value[fieldPath];\r\n return;\r\n }\r\n if (isFieldGroup(fieldAtPath)) {\r\n const idx = fieldAtPath.findIndex(f => f.id === field.id);\r\n if (idx === -1) {\r\n return;\r\n }\r\n fieldAtPath.splice(idx, 1);\r\n if (!fieldAtPath.length) {\r\n delete fieldsByPath.value[fieldPath];\r\n }\r\n }\r\n }\r\n function registerField(field) {\r\n const fieldPath = unref(field.name);\r\n insertFieldAtPath(field, fieldPath);\r\n if (isRef(field.name)) {\r\n // ensures when a field's name was already taken that it preserves its same value\r\n // necessary for fields generated by loops\r\n watch(field.name, async (newPath, oldPath) => {\r\n // cache the value\r\n await nextTick();\r\n removeFieldFromPath(field, oldPath);\r\n insertFieldAtPath(field, newPath);\r\n // re-validate if either path had errors before\r\n if (errors.value[oldPath] || errors.value[newPath]) {\r\n // clear up both paths errors\r\n setFieldError(oldPath, undefined);\r\n validateField(newPath);\r\n }\r\n // clean up the old path if no other field is sharing that name\r\n // #3325\r\n await nextTick();\r\n if (!fieldExists(oldPath)) {\r\n unsetPath(formValues, oldPath);\r\n }\r\n });\r\n }\r\n // if field already had errors (initial errors) that's not user-set, validate it again to ensure state is correct\r\n // the difference being that `initialErrors` will contain the error message while other errors (pre-validated schema) won't have them as initial errors\r\n // #3342\r\n const initialErrorMessage = unref(field.errorMessage);\r\n if (initialErrorMessage && (initialErrors === null || initialErrors === void 0 ? void 0 : initialErrors[fieldPath]) !== initialErrorMessage) {\r\n validateField(fieldPath);\r\n }\r\n // marks the initial error as \"consumed\" so it won't be matched later with same non-initial error\r\n delete initialErrors[fieldPath];\r\n }\r\n function unregisterField(field) {\r\n const fieldName = unref(field.name);\r\n const fieldInstance = fieldsByPath.value[fieldName];\r\n const isGroup = !!fieldInstance && isFieldGroup(fieldInstance);\r\n removeFieldFromPath(field, fieldName);\r\n // clears a field error on unmounted\r\n // we wait till next tick to make sure if the field is completely removed and doesn't have any siblings like checkboxes\r\n nextTick(() => {\r\n var _a;\r\n const shouldKeepValue = (_a = unref(field.keepValueOnUnmount)) !== null && _a !== void 0 ? _a : unref(keepValuesOnUnmount);\r\n const currentGroupValue = getFromPath(formValues, fieldName);\r\n // The boolean here is we check if the field still belongs to the same control group with that name\r\n // if another group claimed the name, we should avoid handling it since it is no longer the same group\r\n // this happens with `v-for` over some checkboxes and field arrays.\r\n // also if the group no longer exist we can assume this group was the last one that controlled it\r\n const isSameGroup = isGroup && (fieldInstance === fieldsByPath.value[fieldName] || !fieldsByPath.value[fieldName]);\r\n // group field that still has a dangling value, the field may exist or not after it was removed.\r\n // This used to be handled in the useField composable but the form has better context on when it should/not happen.\r\n // if it does belong to it that means the group still exists\r\n // #3844\r\n if (isSameGroup && !shouldKeepValue) {\r\n if (Array.isArray(currentGroupValue)) {\r\n const valueIdx = currentGroupValue.findIndex(i => isEqual(i, unref(field.checkedValue)));\r\n if (valueIdx > -1) {\r\n const newVal = [...currentGroupValue];\r\n newVal.splice(valueIdx, 1);\r\n setFieldValue(fieldName, newVal, { force: true });\r\n }\r\n }\r\n else if (currentGroupValue === unref(field.checkedValue)) {\r\n // Remove field if it is a group but does not have an array value, like for radio inputs #3963\r\n unsetPath(formValues, fieldName);\r\n }\r\n }\r\n // Field was removed entirely, we should unset its path\r\n // #3384\r\n if (!fieldExists(fieldName)) {\r\n setFieldError(fieldName, undefined);\r\n // Checks if the field was configured to be unset during unmount or not\r\n // Checks both the form-level config and field-level one\r\n // Field has the priority if it is set, otherwise it goes to the form settings\r\n if (shouldKeepValue) {\r\n return;\r\n }\r\n // Don't apply emptyContainer check unless the current group value is an array\r\n if (isGroup && Array.isArray(currentGroupValue) && !isEmptyContainer(currentGroupValue)) {\r\n return;\r\n }\r\n unsetPath(formValues, fieldName);\r\n }\r\n });\r\n }\r\n async function validate(opts) {\r\n const mode = (opts === null || opts === void 0 ? void 0 : opts.mode) || 'force';\r\n if (mode === 'force') {\r\n mutateAllFields(f => (f.meta.validated = true));\r\n }\r\n if (formCtx.validateSchema) {\r\n return formCtx.validateSchema(mode);\r\n }\r\n // No schema, each field is responsible to validate itself\r\n const validations = await Promise.all(Object.values(fieldsByPath.value).map(field => {\r\n const fieldInstance = Array.isArray(field) ? field[0] : field;\r\n if (!fieldInstance) {\r\n return Promise.resolve({ key: '', valid: true, errors: [] });\r\n }\r\n return fieldInstance.validate(opts).then((result) => {\r\n return {\r\n key: unref(fieldInstance.name),\r\n valid: result.valid,\r\n errors: result.errors,\r\n };\r\n });\r\n }));\r\n const results = {};\r\n const errors = {};\r\n for (const validation of validations) {\r\n results[validation.key] = {\r\n valid: validation.valid,\r\n errors: validation.errors,\r\n };\r\n if (validation.errors.length) {\r\n errors[validation.key] = validation.errors[0];\r\n }\r\n }\r\n return {\r\n valid: validations.every(r => r.valid),\r\n results,\r\n errors,\r\n };\r\n }\r\n async function validateField(field) {\r\n const fieldInstance = fieldsByPath.value[field];\r\n if (!fieldInstance) {\r\n warn$1(`field with name ${field} was not found`);\r\n return Promise.resolve({ errors: [], valid: true });\r\n }\r\n if (Array.isArray(fieldInstance)) {\r\n return fieldInstance.map(f => f.validate())[0];\r\n }\r\n return fieldInstance.validate();\r\n }\r\n function unsetInitialValue(path) {\r\n unsetPath(initialValues.value, path);\r\n }\r\n /**\r\n * Sneaky function to set initial field values\r\n */\r\n function stageInitialValue(path, value, updateOriginal = false) {\r\n setInPath(formValues, path, value);\r\n setFieldInitialValue(path, value);\r\n if (updateOriginal && !(opts === null || opts === void 0 ? void 0 : opts.initialValues)) {\r\n setInPath(originalInitialValues.value, path, klona(value));\r\n }\r\n }\r\n function setFieldInitialValue(path, value) {\r\n setInPath(initialValues.value, path, klona(value));\r\n }\r\n async function _validateSchema() {\r\n const schemaValue = unref(schema);\r\n if (!schemaValue) {\r\n return { valid: true, results: {}, errors: {} };\r\n }\r\n const formResult = isYupValidator(schemaValue)\r\n ? await validateYupSchema(schemaValue, formValues)\r\n : await validateObjectSchema(schemaValue, formValues, {\r\n names: fieldNames.value,\r\n bailsMap: fieldBailsMap.value,\r\n });\r\n return formResult;\r\n }\r\n const submitForm = handleSubmit((_, { evt }) => {\r\n if (isFormSubmitEvent(evt)) {\r\n evt.target.submit();\r\n }\r\n });\r\n // Trigger initial validation\r\n onMounted(() => {\r\n if (opts === null || opts === void 0 ? void 0 : opts.initialErrors) {\r\n setErrors(opts.initialErrors);\r\n }\r\n if (opts === null || opts === void 0 ? void 0 : opts.initialTouched) {\r\n setTouched(opts.initialTouched);\r\n }\r\n // if validate on mount was enabled\r\n if (opts === null || opts === void 0 ? void 0 : opts.validateOnMount) {\r\n validate();\r\n return;\r\n }\r\n // otherwise run initial silent validation through schema if available\r\n // the useField should skip their own silent validation if a yup schema is present\r\n if (formCtx.validateSchema) {\r\n formCtx.validateSchema('silent');\r\n }\r\n });\r\n if (isRef(schema)) {\r\n watch(schema, () => {\r\n var _a;\r\n (_a = formCtx.validateSchema) === null || _a === void 0 ? void 0 : _a.call(formCtx, 'validated-only');\r\n });\r\n }\r\n // Provide injections\r\n provide(FormContextKey, formCtx);\r\n if ((process.env.NODE_ENV !== 'production')) {\r\n registerFormWithDevTools(formCtx);\r\n watch(() => (Object.assign(Object.assign({ errors: errorBag.value }, meta.value), { values: formValues, isSubmitting: isSubmitting.value, submitCount: submitCount.value })), refreshInspector, {\r\n deep: true,\r\n });\r\n }\r\n return Object.assign(Object.assign({}, formCtx), { handleReset: () => resetForm(), submitForm });\r\n}\r\n/**\r\n * Manages form meta aggregation\r\n */\r\nfunction useFormMeta(fieldsByPath, currentValues, initialValues, errors) {\r\n const MERGE_STRATEGIES = {\r\n touched: 'some',\r\n pending: 'some',\r\n valid: 'every',\r\n };\r\n const isDirty = computed(() => {\r\n return !isEqual(currentValues, unref(initialValues));\r\n });\r\n function calculateFlags() {\r\n const fields = Object.values(fieldsByPath.value).flat(1).filter(Boolean);\r\n return keysOf(MERGE_STRATEGIES).reduce((acc, flag) => {\r\n const mergeMethod = MERGE_STRATEGIES[flag];\r\n acc[flag] = fields[mergeMethod](field => field.meta[flag]);\r\n return acc;\r\n }, {});\r\n }\r\n const flags = reactive(calculateFlags());\r\n watchEffect(() => {\r\n const value = calculateFlags();\r\n flags.touched = value.touched;\r\n flags.valid = value.valid;\r\n flags.pending = value.pending;\r\n });\r\n return computed(() => {\r\n return Object.assign(Object.assign({ initialValues: unref(initialValues) }, flags), { valid: flags.valid && !keysOf(errors.value).length, dirty: isDirty.value });\r\n });\r\n}\r\n/**\r\n * Manages the initial values prop\r\n */\r\nfunction useFormInitialValues(fields, formValues, providedValues) {\r\n // these are the mutable initial values as the fields are mounted/unmounted\r\n const initialValues = ref(klona(unref(providedValues)) || {});\r\n // these are the original initial value as provided by the user initially, they don't keep track of conditional fields\r\n // this is important because some conditional fields will overwrite the initial values for other fields who had the same name\r\n // like array fields, any push/insert operation will overwrite the initial values because they \"create new fields\"\r\n // so these are the values that the reset function should use\r\n // these only change when the user explicitly chanegs the initial values or when the user resets them with new values.\r\n const originalInitialValues = ref(klona(unref(providedValues)) || {});\r\n function setInitialValues(values, updateFields = false) {\r\n initialValues.value = klona(values);\r\n originalInitialValues.value = klona(values);\r\n if (!updateFields) {\r\n return;\r\n }\r\n // update the pristine non-touched fields\r\n // those are excluded because it's unlikely you want to change the form values using initial values\r\n // we mostly watch them for API population or newly inserted fields\r\n // if the user API is taking too much time before user interaction they should consider disabling or hiding their inputs until the values are ready\r\n keysOf(fields.value).forEach(fieldPath => {\r\n const field = fields.value[fieldPath];\r\n const wasTouched = Array.isArray(field) ? field.some(f => f.meta.touched) : field === null || field === void 0 ? void 0 : field.meta.touched;\r\n if (!field || wasTouched) {\r\n return;\r\n }\r\n const newValue = getFromPath(initialValues.value, fieldPath);\r\n setInPath(formValues, fieldPath, klona(newValue));\r\n });\r\n }\r\n if (isRef(providedValues)) {\r\n watch(providedValues, value => {\r\n setInitialValues(value, true);\r\n }, {\r\n deep: true,\r\n });\r\n }\r\n return {\r\n initialValues,\r\n originalInitialValues,\r\n setInitialValues,\r\n };\r\n}\r\nfunction useErrorBag(initialErrors) {\r\n const errorBag = ref({});\r\n function normalizeErrorItem(message) {\r\n return Array.isArray(message) ? message : message ? [message] : [];\r\n }\r\n /**\r\n * Manually sets an error message on a specific field\r\n */\r\n function setFieldErrorBag(field, message) {\r\n if (!message) {\r\n delete errorBag.value[field];\r\n return;\r\n }\r\n errorBag.value[field] = normalizeErrorItem(message);\r\n }\r\n /**\r\n * Sets errors for the fields specified in the object\r\n */\r\n function setErrorBag(fields) {\r\n errorBag.value = keysOf(fields).reduce((acc, key) => {\r\n const message = fields[key];\r\n if (message) {\r\n acc[key] = normalizeErrorItem(message);\r\n }\r\n return acc;\r\n }, {});\r\n }\r\n if (initialErrors) {\r\n setErrorBag(initialErrors);\r\n }\r\n return {\r\n errorBag,\r\n setErrorBag,\r\n setFieldErrorBag,\r\n };\r\n}\n\nconst FormImpl = defineComponent({\r\n name: 'Form',\r\n inheritAttrs: false,\r\n props: {\r\n as: {\r\n type: String,\r\n default: 'form',\r\n },\r\n validationSchema: {\r\n type: Object,\r\n default: undefined,\r\n },\r\n initialValues: {\r\n type: Object,\r\n default: undefined,\r\n },\r\n initialErrors: {\r\n type: Object,\r\n default: undefined,\r\n },\r\n initialTouched: {\r\n type: Object,\r\n default: undefined,\r\n },\r\n validateOnMount: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n onSubmit: {\r\n type: Function,\r\n default: undefined,\r\n },\r\n onInvalidSubmit: {\r\n type: Function,\r\n default: undefined,\r\n },\r\n keepValues: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n },\r\n setup(props, ctx) {\r\n const initialValues = toRef(props, 'initialValues');\r\n const validationSchema = toRef(props, 'validationSchema');\r\n const keepValues = toRef(props, 'keepValues');\r\n const { errors, values, meta, isSubmitting, submitCount, controlledValues, validate, validateField, handleReset, resetForm, handleSubmit, setErrors, setFieldError, setFieldValue, setValues, setFieldTouched, setTouched, resetField, } = useForm({\r\n validationSchema: validationSchema.value ? validationSchema : undefined,\r\n initialValues,\r\n initialErrors: props.initialErrors,\r\n initialTouched: props.initialTouched,\r\n validateOnMount: props.validateOnMount,\r\n keepValuesOnUnmount: keepValues,\r\n });\r\n const submitForm = handleSubmit((_, { evt }) => {\r\n if (isFormSubmitEvent(evt)) {\r\n evt.target.submit();\r\n }\r\n }, props.onInvalidSubmit);\r\n const onSubmit = props.onSubmit ? handleSubmit(props.onSubmit, props.onInvalidSubmit) : submitForm;\r\n function handleFormReset(e) {\r\n if (isEvent(e)) {\r\n // Prevent default form reset behavior\r\n e.preventDefault();\r\n }\r\n handleReset();\r\n if (typeof ctx.attrs.onReset === 'function') {\r\n ctx.attrs.onReset();\r\n }\r\n }\r\n function handleScopedSlotSubmit(evt, onSubmit) {\r\n const onSuccess = typeof evt === 'function' && !onSubmit ? evt : onSubmit;\r\n return handleSubmit(onSuccess, props.onInvalidSubmit)(evt);\r\n }\r\n function getValues() {\r\n return klona(values);\r\n }\r\n function getMeta() {\r\n return klona(meta.value);\r\n }\r\n function getErrors() {\r\n return klona(errors.value);\r\n }\r\n function slotProps() {\r\n return {\r\n meta: meta.value,\r\n errors: errors.value,\r\n values: values,\r\n isSubmitting: isSubmitting.value,\r\n submitCount: submitCount.value,\r\n controlledValues: controlledValues.value,\r\n validate,\r\n validateField,\r\n handleSubmit: handleScopedSlotSubmit,\r\n handleReset,\r\n submitForm,\r\n setErrors,\r\n setFieldError,\r\n setFieldValue,\r\n setValues,\r\n setFieldTouched,\r\n setTouched,\r\n resetForm,\r\n resetField,\r\n getValues,\r\n getMeta,\r\n getErrors,\r\n };\r\n }\r\n // expose these functions and methods as part of public API\r\n ctx.expose({\r\n setFieldError,\r\n setErrors,\r\n setFieldValue,\r\n setValues,\r\n setFieldTouched,\r\n setTouched,\r\n resetForm,\r\n validate,\r\n validateField,\r\n resetField,\r\n getValues,\r\n getMeta,\r\n getErrors,\r\n });\r\n return function renderForm() {\r\n // avoid resolving the form component as itself\r\n const tag = props.as === 'form' ? props.as : resolveDynamicComponent(props.as);\r\n const children = normalizeChildren(tag, ctx, slotProps);\r\n if (!props.as) {\r\n return children;\r\n }\r\n // Attributes to add on a native `form` tag\r\n const formAttrs = props.as === 'form'\r\n ? {\r\n // Disables native validation as vee-validate will handle it.\r\n novalidate: true,\r\n }\r\n : {};\r\n return h(tag, Object.assign(Object.assign(Object.assign({}, formAttrs), ctx.attrs), { onSubmit, onReset: handleFormReset }), children);\r\n };\r\n },\r\n});\r\nconst Form = FormImpl;\n\nfunction useFieldArray(arrayPath) {\r\n const form = injectWithSelf(FormContextKey, undefined);\r\n const fields = ref([]);\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n const noOp = () => { };\r\n const noOpApi = {\r\n fields,\r\n remove: noOp,\r\n push: noOp,\r\n swap: noOp,\r\n insert: noOp,\r\n update: noOp,\r\n replace: noOp,\r\n prepend: noOp,\r\n move: noOp,\r\n };\r\n if (!form) {\r\n warn('FieldArray requires being a child of `` or `useForm` being called before it. Array fields may not work correctly');\r\n return noOpApi;\r\n }\r\n if (!unref(arrayPath)) {\r\n warn('FieldArray requires a field path to be provided, did you forget to pass the `name` prop?');\r\n return noOpApi;\r\n }\r\n const alreadyExists = form.fieldArrays.find(a => unref(a.path) === unref(arrayPath));\r\n if (alreadyExists) {\r\n return alreadyExists;\r\n }\r\n let entryCounter = 0;\r\n function initFields() {\r\n const currentValues = getFromPath(form === null || form === void 0 ? void 0 : form.values, unref(arrayPath), []) || [];\r\n fields.value = currentValues.map(createEntry);\r\n updateEntryFlags();\r\n }\r\n initFields();\r\n function updateEntryFlags() {\r\n const fieldsLength = fields.value.length;\r\n for (let i = 0; i < fieldsLength; i++) {\r\n const entry = fields.value[i];\r\n entry.isFirst = i === 0;\r\n entry.isLast = i === fieldsLength - 1;\r\n }\r\n }\r\n function createEntry(value) {\r\n const key = entryCounter++;\r\n const entry = {\r\n key,\r\n value: computedDeep({\r\n get() {\r\n const currentValues = getFromPath(form === null || form === void 0 ? void 0 : form.values, unref(arrayPath), []) || [];\r\n const idx = fields.value.findIndex(e => e.key === key);\r\n return idx === -1 ? value : currentValues[idx];\r\n },\r\n set(value) {\r\n const idx = fields.value.findIndex(e => e.key === key);\r\n if (idx === -1) {\r\n warn(`Attempting to update a non-existent array item`);\r\n return;\r\n }\r\n update(idx, value);\r\n },\r\n }),\r\n isFirst: false,\r\n isLast: false,\r\n };\r\n return entry;\r\n }\r\n function remove(idx) {\r\n const pathName = unref(arrayPath);\r\n const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);\r\n if (!pathValue || !Array.isArray(pathValue)) {\r\n return;\r\n }\r\n const newValue = [...pathValue];\r\n newValue.splice(idx, 1);\r\n form === null || form === void 0 ? void 0 : form.unsetInitialValue(pathName + `[${idx}]`);\r\n form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);\r\n fields.value.splice(idx, 1);\r\n updateEntryFlags();\r\n }\r\n function push(value) {\r\n const pathName = unref(arrayPath);\r\n const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);\r\n const normalizedPathValue = isNullOrUndefined(pathValue) ? [] : pathValue;\r\n if (!Array.isArray(normalizedPathValue)) {\r\n return;\r\n }\r\n const newValue = [...normalizedPathValue];\r\n newValue.push(value);\r\n form === null || form === void 0 ? void 0 : form.stageInitialValue(pathName + `[${newValue.length - 1}]`, value);\r\n form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);\r\n fields.value.push(createEntry(value));\r\n updateEntryFlags();\r\n }\r\n function swap(indexA, indexB) {\r\n const pathName = unref(arrayPath);\r\n const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);\r\n if (!Array.isArray(pathValue) || !(indexA in pathValue) || !(indexB in pathValue)) {\r\n return;\r\n }\r\n const newValue = [...pathValue];\r\n const newFields = [...fields.value];\r\n // the old switcheroo\r\n const temp = newValue[indexA];\r\n newValue[indexA] = newValue[indexB];\r\n newValue[indexB] = temp;\r\n const tempEntry = newFields[indexA];\r\n newFields[indexA] = newFields[indexB];\r\n newFields[indexB] = tempEntry;\r\n form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);\r\n fields.value = newFields;\r\n updateEntryFlags();\r\n }\r\n function insert(idx, value) {\r\n const pathName = unref(arrayPath);\r\n const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);\r\n if (!Array.isArray(pathValue) || pathValue.length < idx) {\r\n return;\r\n }\r\n const newValue = [...pathValue];\r\n const newFields = [...fields.value];\r\n newValue.splice(idx, 0, value);\r\n newFields.splice(idx, 0, createEntry(value));\r\n form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);\r\n fields.value = newFields;\r\n updateEntryFlags();\r\n }\r\n function replace(arr) {\r\n const pathName = unref(arrayPath);\r\n form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, arr);\r\n initFields();\r\n }\r\n function update(idx, value) {\r\n const pathName = unref(arrayPath);\r\n const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);\r\n if (!Array.isArray(pathValue) || pathValue.length - 1 < idx) {\r\n return;\r\n }\r\n form === null || form === void 0 ? void 0 : form.setFieldValue(`${pathName}[${idx}]`, value);\r\n form === null || form === void 0 ? void 0 : form.validate({ mode: 'validated-only' });\r\n }\r\n function prepend(value) {\r\n const pathName = unref(arrayPath);\r\n const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);\r\n const normalizedPathValue = isNullOrUndefined(pathValue) ? [] : pathValue;\r\n if (!Array.isArray(normalizedPathValue)) {\r\n return;\r\n }\r\n const newValue = [value, ...normalizedPathValue];\r\n form === null || form === void 0 ? void 0 : form.stageInitialValue(pathName + `[${newValue.length - 1}]`, value);\r\n form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);\r\n fields.value.unshift(createEntry(value));\r\n updateEntryFlags();\r\n }\r\n function move(oldIdx, newIdx) {\r\n const pathName = unref(arrayPath);\r\n const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);\r\n const newValue = isNullOrUndefined(pathValue) ? [] : [...pathValue];\r\n if (!Array.isArray(pathValue) || !(oldIdx in pathValue) || !(newIdx in pathValue)) {\r\n return;\r\n }\r\n const newFields = [...fields.value];\r\n const movedItem = newFields[oldIdx];\r\n newFields.splice(oldIdx, 1);\r\n newFields.splice(newIdx, 0, movedItem);\r\n const movedValue = newValue[oldIdx];\r\n newValue.splice(oldIdx, 1);\r\n newValue.splice(newIdx, 0, movedValue);\r\n form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);\r\n fields.value = newFields;\r\n updateEntryFlags();\r\n }\r\n const fieldArrayCtx = {\r\n fields,\r\n remove,\r\n push,\r\n swap,\r\n insert,\r\n update,\r\n replace,\r\n prepend,\r\n move,\r\n };\r\n form.fieldArrays.push(Object.assign({ path: arrayPath, reset: initFields }, fieldArrayCtx));\r\n onBeforeUnmount(() => {\r\n const idx = form.fieldArrays.findIndex(i => unref(i.path) === unref(arrayPath));\r\n if (idx >= 0) {\r\n form.fieldArrays.splice(idx, 1);\r\n }\r\n });\r\n return fieldArrayCtx;\r\n}\n\nconst FieldArrayImpl = defineComponent({\r\n name: 'FieldArray',\r\n inheritAttrs: false,\r\n props: {\r\n name: {\r\n type: String,\r\n required: true,\r\n },\r\n },\r\n setup(props, ctx) {\r\n const { push, remove, swap, insert, replace, update, prepend, move, fields } = useFieldArray(toRef(props, 'name'));\r\n function slotProps() {\r\n return {\r\n fields: fields.value,\r\n push,\r\n remove,\r\n swap,\r\n insert,\r\n update,\r\n replace,\r\n prepend,\r\n move,\r\n };\r\n }\r\n ctx.expose({\r\n push,\r\n remove,\r\n swap,\r\n insert,\r\n update,\r\n replace,\r\n prepend,\r\n move,\r\n });\r\n return () => {\r\n const children = normalizeChildren(undefined, ctx, slotProps);\r\n return children;\r\n };\r\n },\r\n});\r\nconst FieldArray = FieldArrayImpl;\n\nconst ErrorMessageImpl = defineComponent({\r\n name: 'ErrorMessage',\r\n props: {\r\n as: {\r\n type: String,\r\n default: undefined,\r\n },\r\n name: {\r\n type: String,\r\n required: true,\r\n },\r\n },\r\n setup(props, ctx) {\r\n const form = inject(FormContextKey, undefined);\r\n const message = computed(() => {\r\n return form === null || form === void 0 ? void 0 : form.errors.value[props.name];\r\n });\r\n function slotProps() {\r\n return {\r\n message: message.value,\r\n };\r\n }\r\n return () => {\r\n // Renders nothing if there are no messages\r\n if (!message.value) {\r\n return undefined;\r\n }\r\n const tag = (props.as ? resolveDynamicComponent(props.as) : props.as);\r\n const children = normalizeChildren(tag, ctx, slotProps);\r\n const attrs = Object.assign({ role: 'alert' }, ctx.attrs);\r\n // If no tag was specified and there are children\r\n // render the slot as is without wrapping it\r\n if (!tag && (Array.isArray(children) || !children) && (children === null || children === void 0 ? void 0 : children.length)) {\r\n return children;\r\n }\r\n // If no children in slot\r\n // render whatever specified and fallback to a with the message in it's contents\r\n if ((Array.isArray(children) || !children) && !(children === null || children === void 0 ? void 0 : children.length)) {\r\n return h(tag || 'span', attrs, message.value);\r\n }\r\n return h(tag, attrs, children);\r\n };\r\n },\r\n});\r\nconst ErrorMessage = ErrorMessageImpl;\n\nfunction useResetForm() {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n return function resetForm(state) {\r\n if (!form) {\r\n return;\r\n }\r\n return form.resetForm(state);\r\n };\r\n}\n\n/**\r\n * If a field is dirty or not\r\n */\r\nfunction useIsFieldDirty(path) {\r\n const form = injectWithSelf(FormContextKey);\r\n let field = path ? undefined : inject(FieldContextKey);\r\n return computed(() => {\r\n if (path) {\r\n field = normalizeField(form === null || form === void 0 ? void 0 : form.fieldsByPath.value[unref(path)]);\r\n }\r\n if (!field) {\r\n warn(`field with name ${unref(path)} was not found`);\r\n return false;\r\n }\r\n return field.meta.dirty;\r\n });\r\n}\n\n/**\r\n * If a field is touched or not\r\n */\r\nfunction useIsFieldTouched(path) {\r\n const form = injectWithSelf(FormContextKey);\r\n let field = path ? undefined : inject(FieldContextKey);\r\n return computed(() => {\r\n if (path) {\r\n field = normalizeField(form === null || form === void 0 ? void 0 : form.fieldsByPath.value[unref(path)]);\r\n }\r\n if (!field) {\r\n warn(`field with name ${unref(path)} was not found`);\r\n return false;\r\n }\r\n return field.meta.touched;\r\n });\r\n}\n\n/**\r\n * If a field is validated and is valid\r\n */\r\nfunction useIsFieldValid(path) {\r\n const form = injectWithSelf(FormContextKey);\r\n let field = path ? undefined : inject(FieldContextKey);\r\n return computed(() => {\r\n if (path) {\r\n field = normalizeField(form === null || form === void 0 ? void 0 : form.fieldsByPath.value[unref(path)]);\r\n }\r\n if (!field) {\r\n warn(`field with name ${unref(path)} was not found`);\r\n return false;\r\n }\r\n return field.meta.valid;\r\n });\r\n}\n\n/**\r\n * If the form is submitting or not\r\n */\r\nfunction useIsSubmitting() {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n return computed(() => {\r\n var _a;\r\n return (_a = form === null || form === void 0 ? void 0 : form.isSubmitting.value) !== null && _a !== void 0 ? _a : false;\r\n });\r\n}\n\n/**\r\n * Validates a single field\r\n */\r\nfunction useValidateField(path) {\r\n const form = injectWithSelf(FormContextKey);\r\n let field = path ? undefined : inject(FieldContextKey);\r\n return function validateField() {\r\n if (path) {\r\n field = normalizeField(form === null || form === void 0 ? void 0 : form.fieldsByPath.value[unref(path)]);\r\n }\r\n if (!field) {\r\n warn(`field with name ${unref(path)} was not found`);\r\n return Promise.resolve({\r\n errors: [],\r\n valid: true,\r\n });\r\n }\r\n return field.validate();\r\n };\r\n}\n\n/**\r\n * If the form is dirty or not\r\n */\r\nfunction useIsFormDirty() {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n return computed(() => {\r\n var _a;\r\n return (_a = form === null || form === void 0 ? void 0 : form.meta.value.dirty) !== null && _a !== void 0 ? _a : false;\r\n });\r\n}\n\n/**\r\n * If the form is touched or not\r\n */\r\nfunction useIsFormTouched() {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n return computed(() => {\r\n var _a;\r\n return (_a = form === null || form === void 0 ? void 0 : form.meta.value.touched) !== null && _a !== void 0 ? _a : false;\r\n });\r\n}\n\n/**\r\n * If the form has been validated and is valid\r\n */\r\nfunction useIsFormValid() {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n return computed(() => {\r\n var _a;\r\n return (_a = form === null || form === void 0 ? void 0 : form.meta.value.valid) !== null && _a !== void 0 ? _a : false;\r\n });\r\n}\n\n/**\r\n * Validate multiple fields\r\n */\r\nfunction useValidateForm() {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n return function validateField() {\r\n if (!form) {\r\n return Promise.resolve({ results: {}, errors: {}, valid: true });\r\n }\r\n return form.validate();\r\n };\r\n}\n\n/**\r\n * The number of form's submission count\r\n */\r\nfunction useSubmitCount() {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n return computed(() => {\r\n var _a;\r\n return (_a = form === null || form === void 0 ? void 0 : form.submitCount.value) !== null && _a !== void 0 ? _a : 0;\r\n });\r\n}\n\n/**\r\n * Gives access to a field's current value\r\n */\r\nfunction useFieldValue(path) {\r\n const form = injectWithSelf(FormContextKey);\r\n // We don't want to use self injected context as it doesn't make sense\r\n const field = path ? undefined : inject(FieldContextKey);\r\n return computed(() => {\r\n if (path) {\r\n return getFromPath(form === null || form === void 0 ? void 0 : form.values, unref(path));\r\n }\r\n return unref(field === null || field === void 0 ? void 0 : field.value);\r\n });\r\n}\n\n/**\r\n * Gives access to a form's values\r\n */\r\nfunction useFormValues() {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n return computed(() => {\r\n return (form === null || form === void 0 ? void 0 : form.values) || {};\r\n });\r\n}\n\n/**\r\n * Gives access to all form errors\r\n */\r\nfunction useFormErrors() {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n return computed(() => {\r\n return ((form === null || form === void 0 ? void 0 : form.errors.value) || {});\r\n });\r\n}\n\n/**\r\n * Gives access to a single field error\r\n */\r\nfunction useFieldError(path) {\r\n const form = injectWithSelf(FormContextKey);\r\n // We don't want to use self injected context as it doesn't make sense\r\n const field = path ? undefined : inject(FieldContextKey);\r\n return computed(() => {\r\n if (path) {\r\n return form === null || form === void 0 ? void 0 : form.errors.value[unref(path)];\r\n }\r\n return field === null || field === void 0 ? void 0 : field.errorMessage.value;\r\n });\r\n}\n\nfunction useSubmitForm(cb) {\r\n const form = injectWithSelf(FormContextKey);\r\n if (!form) {\r\n warn('No vee-validate or `useForm` was detected in the component tree');\r\n }\r\n const onSubmit = form ? form.handleSubmit(cb) : undefined;\r\n return function submitForm(e) {\r\n if (!onSubmit) {\r\n return;\r\n }\r\n return onSubmit(e);\r\n };\r\n}\n\nexport { ErrorMessage, Field, FieldArray, FieldContextKey, Form, FormContextKey, IS_ABSENT, configure, defineRule, useField, useFieldArray, useFieldError, useFieldValue, useForm, useFormErrors, useFormValues, useIsFieldDirty, useIsFieldTouched, useIsFieldValid, useIsFormDirty, useIsFormTouched, useIsFormValid, useIsSubmitting, useResetForm, useSubmitCount, useSubmitForm, useValidateField, useValidateForm, validate };\n","import * as Vue from 'vue'\n\nvar isVue2 = false\nvar isVue3 = true\nvar Vue2 = undefined\n\nfunction install() {}\n\nexport function set(target, key, val) {\n if (Array.isArray(target)) {\n target.length = Math.max(target.length, key)\n target.splice(key, 1, val)\n return val\n }\n target[key] = val\n return val\n}\n\nexport function del(target, key) {\n if (Array.isArray(target)) {\n target.splice(key, 1)\n return\n }\n delete target[key]\n}\n\nexport * from 'vue'\nexport {\n Vue,\n Vue2,\n isVue2,\n isVue3,\n install,\n}\n","\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n if (config('noDeprecation')) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (config('throwDeprecation')) {\n throw new Error(msg);\n } else if (config('traceDeprecation')) {\n console.trace(msg);\n } else {\n console.warn(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n try {\n if (!global.localStorage) return false;\n } catch (_) {\n return false;\n }\n var val = global.localStorage[name];\n if (null == val) return false;\n return String(val).toLowerCase() === 'true';\n}\n","var Vue = require('vue')\n\nObject.keys(Vue).forEach(function(key) {\n exports[key] = Vue[key]\n})\n\nexports.set = function(target, key, val) {\n if (Array.isArray(target)) {\n target.length = Math.max(target.length, key)\n target.splice(key, 1, val)\n return val\n }\n target[key] = val\n return val\n}\n\nexports.del = function(target, key) {\n if (Array.isArray(target)) {\n target.splice(key, 1)\n return\n }\n delete target[key]\n}\n\nexports.Vue = Vue\nexports.Vue2 = undefined\nexports.isVue2 = false\nexports.isVue3 = true\nexports.install = function(){}\n"],"sourceRoot":""}