stickyinc 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3575,24 +3575,24 @@ var require_fast_uri = __commonJS({
3575
3575
  function normalize(uri, options) {
3576
3576
  if (typeof uri === "string") {
3577
3577
  uri = /** @type {T} */
3578
- serialize(parse3(uri, options), options);
3578
+ serialize(parse4(uri, options), options);
3579
3579
  } else if (typeof uri === "object") {
3580
3580
  uri = /** @type {T} */
3581
- parse3(serialize(uri, options), options);
3581
+ parse4(serialize(uri, options), options);
3582
3582
  }
3583
3583
  return uri;
3584
3584
  }
3585
3585
  function resolve2(baseURI, relativeURI, options) {
3586
3586
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3587
- const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3587
+ const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
3588
3588
  schemelessOptions.skipEscape = true;
3589
3589
  return serialize(resolved, schemelessOptions);
3590
3590
  }
3591
3591
  function resolveComponent(base, relative, options, skipNormalization) {
3592
3592
  const target = {};
3593
3593
  if (!skipNormalization) {
3594
- base = parse3(serialize(base, options), options);
3595
- relative = parse3(serialize(relative, options), options);
3594
+ base = parse4(serialize(base, options), options);
3595
+ relative = parse4(serialize(relative, options), options);
3596
3596
  }
3597
3597
  options = options || {};
3598
3598
  if (!options.tolerant && relative.scheme) {
@@ -3644,13 +3644,13 @@ var require_fast_uri = __commonJS({
3644
3644
  function equal(uriA, uriB, options) {
3645
3645
  if (typeof uriA === "string") {
3646
3646
  uriA = unescape(uriA);
3647
- uriA = serialize(normalizeComponentEncoding(parse3(uriA, options), true), { ...options, skipEscape: true });
3647
+ uriA = serialize(normalizeComponentEncoding(parse4(uriA, options), true), { ...options, skipEscape: true });
3648
3648
  } else if (typeof uriA === "object") {
3649
3649
  uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
3650
3650
  }
3651
3651
  if (typeof uriB === "string") {
3652
3652
  uriB = unescape(uriB);
3653
- uriB = serialize(normalizeComponentEncoding(parse3(uriB, options), true), { ...options, skipEscape: true });
3653
+ uriB = serialize(normalizeComponentEncoding(parse4(uriB, options), true), { ...options, skipEscape: true });
3654
3654
  } else if (typeof uriB === "object") {
3655
3655
  uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
3656
3656
  }
@@ -3719,7 +3719,7 @@ var require_fast_uri = __commonJS({
3719
3719
  return uriTokens.join("");
3720
3720
  }
3721
3721
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
3722
- function parse3(uri, opts) {
3722
+ function parse4(uri, opts) {
3723
3723
  const options = Object.assign({}, opts);
3724
3724
  const parsed = {
3725
3725
  scheme: void 0,
@@ -3813,7 +3813,7 @@ var require_fast_uri = __commonJS({
3813
3813
  resolveComponent,
3814
3814
  equal,
3815
3815
  serialize,
3816
- parse: parse3
3816
+ parse: parse4
3817
3817
  };
3818
3818
  module.exports = fastUri;
3819
3819
  module.exports.default = fastUri;
@@ -4224,7 +4224,7 @@ var require_core = __commonJS({
4224
4224
  errorsText(errors = this.errors, { separator = ", ", dataVar = "data" } = {}) {
4225
4225
  if (!errors || errors.length === 0)
4226
4226
  return "No errors";
4227
- return errors.map((e) => `${dataVar}${e.instancePath} ${e.message}`).reduce((text, msg) => text + separator + msg);
4227
+ return errors.map((e) => `${dataVar}${e.instancePath} ${e.message}`).reduce((text2, msg) => text2 + separator + msg);
4228
4228
  }
4229
4229
  $dataMetaSchema(metaSchema, keywordsJsonPointers) {
4230
4230
  const rules = this.RULES.all;
@@ -21016,6 +21016,22 @@ import { mkdirSync } from "node:fs";
21016
21016
  import { homedir } from "node:os";
21017
21017
  import { dirname, join, resolve } from "node:path";
21018
21018
  import { DatabaseSync } from "node:sqlite";
21019
+
21020
+ // src/search.ts
21021
+ function searchWords(query) {
21022
+ return query.match(/[\p{L}\p{N}]+/gu) ?? [];
21023
+ }
21024
+ function ftsQuery(words) {
21025
+ return words.map((w) => `"${w}"*`).join(" ");
21026
+ }
21027
+ function toSqliteUtc(iso) {
21028
+ return iso.replace("T", " ").replace(/(\.\d+)?Z$/, "");
21029
+ }
21030
+ function likeAnywhere(word) {
21031
+ return `%${word.replace(/[\\%_]/g, "\\$&")}%`;
21032
+ }
21033
+
21034
+ // src/db.ts
21019
21035
  function dbPath() {
21020
21036
  const override = process.env.STICKYINC_DB;
21021
21037
  if (!override) return join(homedir(), ".stickyinc", "tasks.db");
@@ -21044,203 +21060,3255 @@ db.exec(`
21044
21060
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
21045
21061
  completed_at TEXT,
21046
21062
  due_at TEXT,
21063
+ due_phrase TEXT,
21047
21064
  source TEXT NOT NULL DEFAULT 'claude',
21048
- fingerprint TEXT
21065
+ fingerprint TEXT,
21066
+ source_client TEXT,
21067
+ source_ref TEXT,
21068
+ source_excerpt TEXT
21049
21069
  );
21050
21070
  CREATE INDEX IF NOT EXISTS idx_tasks_completed ON tasks(completed_at);
21051
21071
  CREATE INDEX IF NOT EXISTS idx_tasks_due ON tasks(due_at);
21052
21072
 
21053
- CREATE TABLE IF NOT EXISTS meta (
21054
- key TEXT PRIMARY KEY,
21055
- value TEXT NOT NULL
21056
- );
21073
+ CREATE TABLE IF NOT EXISTS meta (
21074
+ key TEXT PRIMARY KEY,
21075
+ value TEXT NOT NULL
21076
+ );
21077
+
21078
+ CREATE TABLE IF NOT EXISTS task_events (
21079
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
21080
+ event_uuid TEXT NOT NULL UNIQUE,
21081
+ task_uuid TEXT NOT NULL,
21082
+ op TEXT NOT NULL CHECK (op IN ('create','complete','uncomplete','edit','delete')),
21083
+ payload TEXT,
21084
+ device_id TEXT NOT NULL,
21085
+ ts TEXT NOT NULL DEFAULT (datetime('now')),
21086
+ lamport INTEGER NOT NULL DEFAULT 0
21087
+ );
21088
+ CREATE INDEX IF NOT EXISTS idx_task_events_task ON task_events(task_uuid);
21089
+ CREATE INDEX IF NOT EXISTS idx_task_events_lamport ON task_events(device_id, lamport);
21090
+
21091
+ -- User-defined routines: a named prompt, and a hint of when to run it
21092
+ -- (StickyInc doesn't run them itself; see docs/routines.md).
21093
+ CREATE TABLE IF NOT EXISTS routines (
21094
+ name TEXT PRIMARY KEY,
21095
+ prompt TEXT NOT NULL,
21096
+ schedule TEXT,
21097
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
21098
+ );
21099
+ `);
21100
+ {
21101
+ const cols = db.prepare(`PRAGMA table_info(tasks)`).all();
21102
+ if (!cols.some((c) => c.name === "fingerprint")) {
21103
+ db.exec(`ALTER TABLE tasks ADD COLUMN fingerprint TEXT`);
21104
+ }
21105
+ if (!cols.some((c) => c.name === "uuid")) {
21106
+ db.exec(`ALTER TABLE tasks ADD COLUMN uuid TEXT`);
21107
+ }
21108
+ if (!cols.some((c) => c.name === "due_phrase")) {
21109
+ db.exec(`ALTER TABLE tasks ADD COLUMN due_phrase TEXT`);
21110
+ }
21111
+ for (const col of ["source_client", "source_ref", "source_excerpt"]) {
21112
+ if (!cols.some((c) => c.name === col)) {
21113
+ db.exec(`ALTER TABLE tasks ADD COLUMN ${col} TEXT`);
21114
+ }
21115
+ }
21116
+ const pending = db.prepare(`SELECT id FROM tasks WHERE uuid IS NULL`).all();
21117
+ if (pending.length > 0) {
21118
+ const setUuid = db.prepare(`UPDATE tasks SET uuid = ? WHERE id = ?`);
21119
+ inTransaction(() => {
21120
+ for (const row of pending) setUuid.run(randomUUID(), row.id);
21121
+ });
21122
+ }
21123
+ }
21124
+ db.exec(`
21125
+ CREATE INDEX IF NOT EXISTS idx_tasks_fingerprint ON tasks(fingerprint);
21126
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_uuid ON tasks(uuid);
21127
+ `);
21128
+ function ensureDeviceId() {
21129
+ const row = db.prepare(`SELECT value FROM meta WHERE key = 'device_id'`).get();
21130
+ if (row) return row.value;
21131
+ const id = randomUUID();
21132
+ db.prepare(
21133
+ `INSERT OR IGNORE INTO meta (key, value) VALUES ('device_id', ?)`
21134
+ ).run(id);
21135
+ const final = db.prepare(`SELECT value FROM meta WHERE key = 'device_id'`).get();
21136
+ return final.value;
21137
+ }
21138
+ var DEVICE_ID = ensureDeviceId();
21139
+ function nextLamport() {
21140
+ const row = db.prepare(`SELECT MAX(lamport) as m FROM task_events WHERE device_id = ?`).get(DEVICE_ID);
21141
+ return (row.m ?? 0) + 1;
21142
+ }
21143
+ var insertEventStmt = db.prepare(
21144
+ `INSERT INTO task_events (event_uuid, task_uuid, op, payload, device_id, lamport)
21145
+ VALUES (?, ?, ?, ?, ?, ?)`
21146
+ );
21147
+ function recordEvent(op, taskUuid, payload) {
21148
+ insertEventStmt.run(
21149
+ randomUUID(),
21150
+ taskUuid,
21151
+ op,
21152
+ payload === null ? null : JSON.stringify(payload),
21153
+ DEVICE_ID,
21154
+ nextLamport()
21155
+ );
21156
+ }
21157
+ var insertTaskStmt = db.prepare(
21158
+ `INSERT INTO tasks (uuid, text, due_at, due_phrase, source, fingerprint,
21159
+ source_client, source_ref, source_excerpt)
21160
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`
21161
+ );
21162
+ var findOpenByFingerprintStmt = db.prepare(
21163
+ `SELECT * FROM tasks WHERE fingerprint = ? AND completed_at IS NULL LIMIT 1`
21164
+ );
21165
+ var countDoneTodayStmt = db.prepare(
21166
+ `SELECT COUNT(*) as n FROM tasks WHERE completed_at IS NOT NULL
21167
+ AND date(completed_at, 'localtime') = date('now', 'localtime')`
21168
+ );
21169
+ var selectOpenStmt = db.prepare(
21170
+ `SELECT * FROM tasks WHERE completed_at IS NULL ORDER BY
21171
+ CASE WHEN due_at IS NULL THEN 1 ELSE 0 END, due_at ASC, created_at ASC`
21172
+ );
21173
+ var selectAllStmt = db.prepare(
21174
+ `SELECT * FROM tasks ORDER BY created_at DESC LIMIT ?`
21175
+ );
21176
+ var selectRecentDoneStmt = db.prepare(
21177
+ `SELECT * FROM tasks
21178
+ WHERE completed_at IS NOT NULL
21179
+ AND completed_at >= datetime('now', ?)
21180
+ ORDER BY completed_at DESC`
21181
+ );
21182
+ var selectArchivedStmt = db.prepare(
21183
+ `SELECT * FROM tasks
21184
+ WHERE completed_at IS NOT NULL
21185
+ AND completed_at < datetime('now', ?)
21186
+ ORDER BY completed_at DESC
21187
+ LIMIT ?`
21188
+ );
21189
+ var completeTaskFindStmt = db.prepare(
21190
+ `SELECT uuid, completed_at FROM tasks WHERE id = ?`
21191
+ );
21192
+ var completeTaskUpdateStmt = db.prepare(
21193
+ `UPDATE tasks SET completed_at = datetime('now') WHERE id = ? AND completed_at IS NULL`
21194
+ );
21195
+ var getTaskStmt = db.prepare(`SELECT * FROM tasks WHERE id = ?`);
21196
+ function fingerprint(text2) {
21197
+ return createHash("sha256").update(text2.toLowerCase().replace(/\s+/g, " ").trim()).digest("hex").slice(0, 16);
21198
+ }
21199
+ function insertTask({ text: text2, due: due2 = null, source = "claude", from }) {
21200
+ const taskUuid = randomUUID();
21201
+ const row = {
21202
+ due_at: due2?.at ?? null,
21203
+ due_phrase: due2?.phrase ?? null,
21204
+ source_client: from?.client ?? null,
21205
+ source_ref: from?.ref ?? null,
21206
+ source_excerpt: from?.excerpt ?? null
21207
+ };
21208
+ const task = insertTaskStmt.get(
21209
+ taskUuid,
21210
+ text2,
21211
+ row.due_at,
21212
+ row.due_phrase,
21213
+ source,
21214
+ fingerprint(text2),
21215
+ row.source_client,
21216
+ row.source_ref,
21217
+ row.source_excerpt
21218
+ );
21219
+ recordEvent("create", taskUuid, { text: text2, ...row, due_ref: due2?.ref ?? null, source });
21220
+ return task;
21221
+ }
21222
+ function addTaskUnique(t) {
21223
+ return inTransaction(() => {
21224
+ const existing = findOpenByFingerprintStmt.get(fingerprint(t.text));
21225
+ if (existing) return { task: existing, inserted: false };
21226
+ return { task: insertTask(t), inserted: true };
21227
+ });
21228
+ }
21229
+ function countDoneToday() {
21230
+ return countDoneTodayStmt.get().n;
21231
+ }
21232
+ function listOpenTasks() {
21233
+ return selectOpenStmt.all();
21234
+ }
21235
+ function listAllTasks(limit = 50) {
21236
+ return selectAllStmt.all(limit);
21237
+ }
21238
+ function listRecentlyCompleted(hoursAgo = 24) {
21239
+ return selectRecentDoneStmt.all(`-${hoursAgo} hours`);
21240
+ }
21241
+ function listArchived(hoursAgo = 24, limit = 100) {
21242
+ return selectArchivedStmt.all(`-${hoursAgo} hours`, limit);
21243
+ }
21244
+ function completeTask(id) {
21245
+ return inTransaction(() => {
21246
+ const prior = completeTaskFindStmt.get(id);
21247
+ if (!prior) return null;
21248
+ const completed = prior.completed_at === null;
21249
+ if (completed) {
21250
+ completeTaskUpdateStmt.run(id);
21251
+ recordEvent("complete", prior.uuid, null);
21252
+ }
21253
+ return { task: getTaskStmt.get(id), completed };
21254
+ });
21255
+ }
21256
+ var HAS_FTS5 = (() => {
21257
+ try {
21258
+ db.exec(
21259
+ `CREATE VIRTUAL TABLE IF NOT EXISTS temp.task_search
21260
+ USING fts5(text, excerpt, tokenize = 'unicode61 remove_diacritics 2')`
21261
+ );
21262
+ return true;
21263
+ } catch {
21264
+ return false;
21265
+ }
21266
+ })();
21267
+ function searchTasks({
21268
+ query = "",
21269
+ status = "all",
21270
+ since,
21271
+ completedSince,
21272
+ limit = 20
21273
+ }) {
21274
+ const words = searchWords(query);
21275
+ const where = [];
21276
+ const params = [];
21277
+ if (status === "open") where.push("t.completed_at IS NULL");
21278
+ if (status === "done") where.push("t.completed_at IS NOT NULL");
21279
+ if (since) {
21280
+ where.push("t.created_at >= ?");
21281
+ params.push(toSqliteUtc(since));
21282
+ }
21283
+ if (completedSince) {
21284
+ where.push("t.completed_at >= ?");
21285
+ params.push(toSqliteUtc(completedSince));
21286
+ }
21287
+ if (words.length > 0 && HAS_FTS5) {
21288
+ db.exec(
21289
+ `DELETE FROM temp.task_search;
21290
+ INSERT INTO temp.task_search (rowid, text, excerpt)
21291
+ SELECT id, text, source_excerpt FROM main.tasks;`
21292
+ );
21293
+ const filters2 = where.map((w) => ` AND ${w}`).join("");
21294
+ return db.prepare(
21295
+ `SELECT t.* FROM temp.task_search JOIN main.tasks t ON t.id = task_search.rowid
21296
+ WHERE task_search MATCH ?${filters2}
21297
+ ORDER BY task_search.rank LIMIT ?`
21298
+ ).all(ftsQuery(words), ...params, limit);
21299
+ }
21300
+ for (const word of words) {
21301
+ where.push(`(t.text LIKE ? ESCAPE '\\' OR t.source_excerpt LIKE ? ESCAPE '\\')`);
21302
+ params.push(likeAnywhere(word), likeAnywhere(word));
21303
+ }
21304
+ const filters = where.length > 0 ? `WHERE ${where.join(" AND ")}` : "";
21305
+ return db.prepare(`SELECT t.* FROM main.tasks t ${filters} ORDER BY t.created_at DESC, t.id DESC LIMIT ?`).all(...params, limit);
21306
+ }
21307
+ function listRoutines() {
21308
+ return db.prepare(`SELECT * FROM routines ORDER BY name`).all();
21309
+ }
21310
+ function saveRoutine(r) {
21311
+ return inTransaction(() => {
21312
+ const existed = db.prepare(`SELECT 1 FROM routines WHERE name = ?`).get(r.name) !== void 0;
21313
+ db.prepare(
21314
+ `INSERT INTO routines (name, prompt, schedule, updated_at) VALUES (?, ?, ?, datetime('now'))
21315
+ ON CONFLICT (name) DO UPDATE SET prompt = excluded.prompt, schedule = excluded.schedule,
21316
+ updated_at = excluded.updated_at`
21317
+ ).run(r.name, r.prompt, r.schedule ?? null);
21318
+ return !existed;
21319
+ });
21320
+ }
21321
+ function deleteRoutine(name) {
21322
+ return Number(db.prepare(`DELETE FROM routines WHERE name = ?`).run(name).changes) > 0;
21323
+ }
21324
+
21325
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/types.js
21326
+ var Meridiem;
21327
+ (function(Meridiem2) {
21328
+ Meridiem2[Meridiem2["AM"] = 0] = "AM";
21329
+ Meridiem2[Meridiem2["PM"] = 1] = "PM";
21330
+ })(Meridiem || (Meridiem = {}));
21331
+ var Weekday;
21332
+ (function(Weekday2) {
21333
+ Weekday2[Weekday2["SUNDAY"] = 0] = "SUNDAY";
21334
+ Weekday2[Weekday2["MONDAY"] = 1] = "MONDAY";
21335
+ Weekday2[Weekday2["TUESDAY"] = 2] = "TUESDAY";
21336
+ Weekday2[Weekday2["WEDNESDAY"] = 3] = "WEDNESDAY";
21337
+ Weekday2[Weekday2["THURSDAY"] = 4] = "THURSDAY";
21338
+ Weekday2[Weekday2["FRIDAY"] = 5] = "FRIDAY";
21339
+ Weekday2[Weekday2["SATURDAY"] = 6] = "SATURDAY";
21340
+ })(Weekday || (Weekday = {}));
21341
+ var Month;
21342
+ (function(Month2) {
21343
+ Month2[Month2["JANUARY"] = 1] = "JANUARY";
21344
+ Month2[Month2["FEBRUARY"] = 2] = "FEBRUARY";
21345
+ Month2[Month2["MARCH"] = 3] = "MARCH";
21346
+ Month2[Month2["APRIL"] = 4] = "APRIL";
21347
+ Month2[Month2["MAY"] = 5] = "MAY";
21348
+ Month2[Month2["JUNE"] = 6] = "JUNE";
21349
+ Month2[Month2["JULY"] = 7] = "JULY";
21350
+ Month2[Month2["AUGUST"] = 8] = "AUGUST";
21351
+ Month2[Month2["SEPTEMBER"] = 9] = "SEPTEMBER";
21352
+ Month2[Month2["OCTOBER"] = 10] = "OCTOBER";
21353
+ Month2[Month2["NOVEMBER"] = 11] = "NOVEMBER";
21354
+ Month2[Month2["DECEMBER"] = 12] = "DECEMBER";
21355
+ })(Month || (Month = {}));
21356
+
21357
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/utils/dates.js
21358
+ function assignSimilarDate(component, target) {
21359
+ component.assign("day", target.getDate());
21360
+ component.assign("month", target.getMonth() + 1);
21361
+ component.assign("year", target.getFullYear());
21362
+ }
21363
+ function assignSimilarTime(component, target) {
21364
+ component.assign("hour", target.getHours());
21365
+ component.assign("minute", target.getMinutes());
21366
+ component.assign("second", target.getSeconds());
21367
+ component.assign("millisecond", target.getMilliseconds());
21368
+ component.assign("meridiem", target.getHours() < 12 ? Meridiem.AM : Meridiem.PM);
21369
+ }
21370
+ function implySimilarDate(component, target) {
21371
+ component.imply("day", target.getDate());
21372
+ component.imply("month", target.getMonth() + 1);
21373
+ component.imply("year", target.getFullYear());
21374
+ }
21375
+ function implySimilarTime(component, target) {
21376
+ component.imply("hour", target.getHours());
21377
+ component.imply("minute", target.getMinutes());
21378
+ component.imply("second", target.getSeconds());
21379
+ component.imply("millisecond", target.getMilliseconds());
21380
+ component.imply("meridiem", target.getHours() < 12 ? Meridiem.AM : Meridiem.PM);
21381
+ }
21382
+
21383
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/timezone.js
21384
+ var TIMEZONE_ABBR_MAP = {
21385
+ ACDT: 630,
21386
+ ACST: 570,
21387
+ ADT: -180,
21388
+ AEDT: 660,
21389
+ AEST: 600,
21390
+ AFT: 270,
21391
+ AKDT: -480,
21392
+ AKST: -540,
21393
+ ALMT: 360,
21394
+ AMST: -180,
21395
+ AMT: -240,
21396
+ ANAST: 720,
21397
+ ANAT: 720,
21398
+ AQTT: 300,
21399
+ ART: -180,
21400
+ AST: -240,
21401
+ AWDT: 540,
21402
+ AWST: 480,
21403
+ AZOST: 0,
21404
+ AZOT: -60,
21405
+ AZST: 300,
21406
+ AZT: 240,
21407
+ BNT: 480,
21408
+ BOT: -240,
21409
+ BRST: -120,
21410
+ BRT: -180,
21411
+ BST: 60,
21412
+ BTT: 360,
21413
+ CAST: 480,
21414
+ CAT: 120,
21415
+ CCT: 390,
21416
+ CDT: -300,
21417
+ CEST: 120,
21418
+ CET: {
21419
+ timezoneOffsetDuringDst: 2 * 60,
21420
+ timezoneOffsetNonDst: 60,
21421
+ dstStart: (year) => getLastWeekdayOfMonth(year, Month.MARCH, Weekday.SUNDAY, 2),
21422
+ dstEnd: (year) => getLastWeekdayOfMonth(year, Month.OCTOBER, Weekday.SUNDAY, 3)
21423
+ },
21424
+ CHADT: 825,
21425
+ CHAST: 765,
21426
+ CKT: -600,
21427
+ CLST: -180,
21428
+ CLT: -240,
21429
+ COT: -300,
21430
+ CST: -360,
21431
+ CT: {
21432
+ timezoneOffsetDuringDst: -5 * 60,
21433
+ timezoneOffsetNonDst: -6 * 60,
21434
+ dstStart: (year) => getNthWeekdayOfMonth(year, Month.MARCH, Weekday.SUNDAY, 2, 2),
21435
+ dstEnd: (year) => getNthWeekdayOfMonth(year, Month.NOVEMBER, Weekday.SUNDAY, 1, 2)
21436
+ },
21437
+ CVT: -60,
21438
+ CXT: 420,
21439
+ ChST: 600,
21440
+ DAVT: 420,
21441
+ EASST: -300,
21442
+ EAST: -360,
21443
+ EAT: 180,
21444
+ ECT: -300,
21445
+ EDT: -240,
21446
+ EEST: 180,
21447
+ EET: 120,
21448
+ EGST: 0,
21449
+ EGT: -60,
21450
+ EST: -300,
21451
+ ET: {
21452
+ timezoneOffsetDuringDst: -4 * 60,
21453
+ timezoneOffsetNonDst: -5 * 60,
21454
+ dstStart: (year) => getNthWeekdayOfMonth(year, Month.MARCH, Weekday.SUNDAY, 2, 2),
21455
+ dstEnd: (year) => getNthWeekdayOfMonth(year, Month.NOVEMBER, Weekday.SUNDAY, 1, 2)
21456
+ },
21457
+ FJST: 780,
21458
+ FJT: 720,
21459
+ FKST: -180,
21460
+ FKT: -240,
21461
+ FNT: -120,
21462
+ GALT: -360,
21463
+ GAMT: -540,
21464
+ GET: 240,
21465
+ GFT: -180,
21466
+ GILT: 720,
21467
+ GMT: 0,
21468
+ GST: 240,
21469
+ GYT: -240,
21470
+ HAA: -180,
21471
+ HAC: -300,
21472
+ HADT: -540,
21473
+ HAE: -240,
21474
+ HAP: -420,
21475
+ HAR: -360,
21476
+ HAST: -600,
21477
+ HAT: -90,
21478
+ HAY: -480,
21479
+ HKT: 480,
21480
+ HLV: -210,
21481
+ HNA: -240,
21482
+ HNC: -360,
21483
+ HNE: -300,
21484
+ HNP: -480,
21485
+ HNR: -420,
21486
+ HNT: -150,
21487
+ HNY: -540,
21488
+ HOVT: 420,
21489
+ ICT: 420,
21490
+ IDT: 180,
21491
+ IOT: 360,
21492
+ IRDT: 270,
21493
+ IRKST: 540,
21494
+ IRKT: 540,
21495
+ IRST: 210,
21496
+ IST: 330,
21497
+ JST: 540,
21498
+ KGT: 360,
21499
+ KRAST: 480,
21500
+ KRAT: 480,
21501
+ KST: 540,
21502
+ KUYT: 240,
21503
+ LHDT: 660,
21504
+ LHST: 630,
21505
+ LINT: 840,
21506
+ MAGST: 720,
21507
+ MAGT: 720,
21508
+ MART: -510,
21509
+ MAWT: 300,
21510
+ MDT: -360,
21511
+ MESZ: 120,
21512
+ MEZ: 60,
21513
+ MHT: 720,
21514
+ MMT: 390,
21515
+ MSD: 240,
21516
+ MSK: 180,
21517
+ MST: -420,
21518
+ MT: {
21519
+ timezoneOffsetDuringDst: -6 * 60,
21520
+ timezoneOffsetNonDst: -7 * 60,
21521
+ dstStart: (year) => getNthWeekdayOfMonth(year, Month.MARCH, Weekday.SUNDAY, 2, 2),
21522
+ dstEnd: (year) => getNthWeekdayOfMonth(year, Month.NOVEMBER, Weekday.SUNDAY, 1, 2)
21523
+ },
21524
+ MUT: 240,
21525
+ MVT: 300,
21526
+ MYT: 480,
21527
+ NCT: 660,
21528
+ NDT: -90,
21529
+ NFT: 690,
21530
+ NOVST: 420,
21531
+ NOVT: 360,
21532
+ NPT: 345,
21533
+ NST: -150,
21534
+ NUT: -660,
21535
+ NZDT: 780,
21536
+ NZST: 720,
21537
+ OMSST: 420,
21538
+ OMST: 420,
21539
+ PDT: -420,
21540
+ PET: -300,
21541
+ PETST: 720,
21542
+ PETT: 720,
21543
+ PGT: 600,
21544
+ PHOT: 780,
21545
+ PHT: 480,
21546
+ PKT: 300,
21547
+ PMDT: -120,
21548
+ PMST: -180,
21549
+ PONT: 660,
21550
+ PST: -480,
21551
+ PT: {
21552
+ timezoneOffsetDuringDst: -7 * 60,
21553
+ timezoneOffsetNonDst: -8 * 60,
21554
+ dstStart: (year) => getNthWeekdayOfMonth(year, Month.MARCH, Weekday.SUNDAY, 2, 2),
21555
+ dstEnd: (year) => getNthWeekdayOfMonth(year, Month.NOVEMBER, Weekday.SUNDAY, 1, 2)
21556
+ },
21557
+ PWT: 540,
21558
+ PYST: -180,
21559
+ PYT: -240,
21560
+ RET: 240,
21561
+ SAMT: 240,
21562
+ SAST: 120,
21563
+ SBT: 660,
21564
+ SCT: 240,
21565
+ SGT: 480,
21566
+ SRT: -180,
21567
+ SST: -660,
21568
+ TAHT: -600,
21569
+ TFT: 300,
21570
+ TJT: 300,
21571
+ TKT: 780,
21572
+ TLT: 540,
21573
+ TMT: 300,
21574
+ TVT: 720,
21575
+ ULAT: 480,
21576
+ UTC: 0,
21577
+ UYST: -120,
21578
+ UYT: -180,
21579
+ UZT: 300,
21580
+ VET: -210,
21581
+ VLAST: 660,
21582
+ VLAT: 660,
21583
+ VUT: 660,
21584
+ WAST: 120,
21585
+ WAT: 60,
21586
+ WEST: 60,
21587
+ WESZ: 60,
21588
+ WET: 0,
21589
+ WEZ: 0,
21590
+ WFT: 720,
21591
+ WGST: -120,
21592
+ WGT: -180,
21593
+ WIB: 420,
21594
+ WIT: 540,
21595
+ WITA: 480,
21596
+ WST: 780,
21597
+ WT: 0,
21598
+ YAKST: 600,
21599
+ YAKT: 600,
21600
+ YAPT: 600,
21601
+ YEKST: 360,
21602
+ YEKT: 360
21603
+ };
21604
+ function getNthWeekdayOfMonth(year, month, weekday, n, hour = 0) {
21605
+ let dayOfMonth = 0;
21606
+ let i = 0;
21607
+ while (i < n) {
21608
+ dayOfMonth++;
21609
+ const date3 = new Date(year, month - 1, dayOfMonth);
21610
+ if (date3.getDay() === weekday)
21611
+ i++;
21612
+ }
21613
+ return new Date(year, month - 1, dayOfMonth, hour);
21614
+ }
21615
+ function getLastWeekdayOfMonth(year, month, weekday, hour = 0) {
21616
+ const oneIndexedWeekday = weekday === 0 ? 7 : weekday;
21617
+ const date3 = new Date(year, month - 1 + 1, 1, 12);
21618
+ const firstWeekdayNextMonth = date3.getDay() === 0 ? 7 : date3.getDay();
21619
+ let dayDiff;
21620
+ if (firstWeekdayNextMonth === oneIndexedWeekday)
21621
+ dayDiff = 7;
21622
+ else if (firstWeekdayNextMonth < oneIndexedWeekday)
21623
+ dayDiff = 7 + firstWeekdayNextMonth - oneIndexedWeekday;
21624
+ else
21625
+ dayDiff = firstWeekdayNextMonth - oneIndexedWeekday;
21626
+ date3.setDate(date3.getDate() - dayDiff);
21627
+ return new Date(year, month - 1, date3.getDate(), hour);
21628
+ }
21629
+ function toTimezoneOffset(timezoneInput, date3, timezoneOverrides = {}) {
21630
+ if (timezoneInput == null) {
21631
+ return null;
21632
+ }
21633
+ if (typeof timezoneInput === "number") {
21634
+ return timezoneInput;
21635
+ }
21636
+ const matchedTimezone = timezoneOverrides[timezoneInput] ?? TIMEZONE_ABBR_MAP[timezoneInput];
21637
+ if (matchedTimezone == null) {
21638
+ return null;
21639
+ }
21640
+ if (typeof matchedTimezone == "number") {
21641
+ return matchedTimezone;
21642
+ }
21643
+ if (date3 == null) {
21644
+ return null;
21645
+ }
21646
+ if (date3 > matchedTimezone.dstStart(date3.getFullYear()) && !(date3 > matchedTimezone.dstEnd(date3.getFullYear()))) {
21647
+ return matchedTimezone.timezoneOffsetDuringDst;
21648
+ }
21649
+ return matchedTimezone.timezoneOffsetNonDst;
21650
+ }
21651
+
21652
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/calculation/duration.js
21653
+ var EmptyDuration = {
21654
+ day: 0,
21655
+ second: 0,
21656
+ millisecond: 0
21657
+ };
21658
+ function addDuration(ref, duration3) {
21659
+ let date3 = new Date(ref);
21660
+ if (duration3["y"]) {
21661
+ duration3["year"] = duration3["y"];
21662
+ delete duration3["y"];
21663
+ }
21664
+ if (duration3["mo"]) {
21665
+ duration3["month"] = duration3["mo"];
21666
+ delete duration3["mo"];
21667
+ }
21668
+ if (duration3["M"]) {
21669
+ duration3["month"] = duration3["M"];
21670
+ delete duration3["M"];
21671
+ }
21672
+ if (duration3["w"]) {
21673
+ duration3["week"] = duration3["w"];
21674
+ delete duration3["w"];
21675
+ }
21676
+ if (duration3["d"]) {
21677
+ duration3["day"] = duration3["d"];
21678
+ delete duration3["d"];
21679
+ }
21680
+ if (duration3["h"]) {
21681
+ duration3["hour"] = duration3["h"];
21682
+ delete duration3["h"];
21683
+ }
21684
+ if (duration3["m"]) {
21685
+ duration3["minute"] = duration3["m"];
21686
+ delete duration3["m"];
21687
+ }
21688
+ if (duration3["s"]) {
21689
+ duration3["second"] = duration3["s"];
21690
+ delete duration3["s"];
21691
+ }
21692
+ if (duration3["ms"]) {
21693
+ duration3["millisecond"] = duration3["ms"];
21694
+ delete duration3["ms"];
21695
+ }
21696
+ if ("year" in duration3) {
21697
+ const floor = Math.floor(duration3["year"]);
21698
+ date3.setFullYear(date3.getFullYear() + floor);
21699
+ const remainingFraction = duration3["year"] - floor;
21700
+ if (remainingFraction > 0) {
21701
+ duration3.month = duration3?.month ?? 0;
21702
+ duration3.month += remainingFraction * 12;
21703
+ }
21704
+ }
21705
+ if ("quarter" in duration3) {
21706
+ const floor = Math.floor(duration3["quarter"]);
21707
+ date3.setMonth(date3.getMonth() + floor * 3);
21708
+ }
21709
+ if ("month" in duration3) {
21710
+ const floor = Math.floor(duration3["month"]);
21711
+ date3.setMonth(date3.getMonth() + floor);
21712
+ const remainingFraction = duration3["month"] - floor;
21713
+ if (remainingFraction > 0) {
21714
+ duration3.week = duration3?.week ?? 0;
21715
+ duration3.week += remainingFraction * 4;
21716
+ }
21717
+ }
21718
+ if ("week" in duration3) {
21719
+ const floor = Math.floor(duration3["week"]);
21720
+ date3.setDate(date3.getDate() + floor * 7);
21721
+ const remainingFraction = duration3["week"] - floor;
21722
+ if (remainingFraction > 0) {
21723
+ duration3.day = duration3?.day ?? 0;
21724
+ duration3.day += Math.round(remainingFraction * 7);
21725
+ }
21726
+ }
21727
+ if ("day" in duration3) {
21728
+ const floor = Math.floor(duration3["day"]);
21729
+ date3.setDate(date3.getDate() + floor);
21730
+ const remainingFraction = duration3["day"] - floor;
21731
+ if (remainingFraction > 0) {
21732
+ duration3.hour = duration3?.hour ?? 0;
21733
+ duration3.hour += Math.round(remainingFraction * 24);
21734
+ }
21735
+ }
21736
+ if ("hour" in duration3) {
21737
+ const floor = Math.floor(duration3["hour"]);
21738
+ date3.setHours(date3.getHours() + floor);
21739
+ const remainingFraction = duration3["hour"] - floor;
21740
+ if (remainingFraction > 0) {
21741
+ duration3.minute = duration3?.minute ?? 0;
21742
+ duration3.minute += Math.round(remainingFraction * 60);
21743
+ }
21744
+ }
21745
+ if ("minute" in duration3) {
21746
+ const floor = Math.floor(duration3["minute"]);
21747
+ date3.setMinutes(date3.getMinutes() + floor);
21748
+ const remainingFraction = duration3["minute"] - floor;
21749
+ if (remainingFraction > 0) {
21750
+ duration3.second = duration3?.second ?? 0;
21751
+ duration3.second += Math.round(remainingFraction * 60);
21752
+ }
21753
+ }
21754
+ if ("second" in duration3) {
21755
+ const floor = Math.floor(duration3["second"]);
21756
+ date3.setSeconds(date3.getSeconds() + floor);
21757
+ const remainingFraction = duration3["second"] - floor;
21758
+ if (remainingFraction > 0) {
21759
+ duration3.millisecond = duration3?.millisecond ?? 0;
21760
+ duration3.millisecond += Math.round(remainingFraction * 1e3);
21761
+ }
21762
+ }
21763
+ if ("millisecond" in duration3) {
21764
+ const floor = Math.floor(duration3["millisecond"]);
21765
+ date3.setMilliseconds(date3.getMilliseconds() + floor);
21766
+ }
21767
+ return date3;
21768
+ }
21769
+ function reverseDuration(duration3) {
21770
+ const reversed = {};
21771
+ for (const key in duration3) {
21772
+ reversed[key] = -duration3[key];
21773
+ }
21774
+ return reversed;
21775
+ }
21776
+
21777
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/results.js
21778
+ var ReferenceWithTimezone = class _ReferenceWithTimezone {
21779
+ instant;
21780
+ timezoneOffset;
21781
+ constructor(instant, timezoneOffset) {
21782
+ this.instant = instant ?? /* @__PURE__ */ new Date();
21783
+ this.timezoneOffset = timezoneOffset ?? null;
21784
+ }
21785
+ static fromDate(date3) {
21786
+ return new _ReferenceWithTimezone(date3);
21787
+ }
21788
+ static fromInput(input, timezoneOverrides) {
21789
+ if (input instanceof Date) {
21790
+ return _ReferenceWithTimezone.fromDate(input);
21791
+ }
21792
+ const instant = input?.instant ?? /* @__PURE__ */ new Date();
21793
+ const timezoneOffset = toTimezoneOffset(input?.timezone, instant, timezoneOverrides);
21794
+ return new _ReferenceWithTimezone(instant, timezoneOffset);
21795
+ }
21796
+ getDateWithAdjustedTimezone() {
21797
+ const date3 = new Date(this.instant);
21798
+ if (this.timezoneOffset !== null) {
21799
+ date3.setMinutes(date3.getMinutes() - this.getSystemTimezoneAdjustmentMinute(this.instant));
21800
+ }
21801
+ return date3;
21802
+ }
21803
+ getSystemTimezoneAdjustmentMinute(date3, overrideTimezoneOffset) {
21804
+ if (!date3) {
21805
+ date3 = /* @__PURE__ */ new Date();
21806
+ }
21807
+ const currentTimezoneOffset = -date3.getTimezoneOffset();
21808
+ const targetTimezoneOffset = overrideTimezoneOffset ?? this.timezoneOffset ?? currentTimezoneOffset;
21809
+ return currentTimezoneOffset - targetTimezoneOffset;
21810
+ }
21811
+ getTimezoneOffset() {
21812
+ return this.timezoneOffset ?? -this.instant.getTimezoneOffset();
21813
+ }
21814
+ };
21815
+ var ParsingComponents = class _ParsingComponents {
21816
+ knownValues;
21817
+ impliedValues;
21818
+ reference;
21819
+ _tags = /* @__PURE__ */ new Set();
21820
+ constructor(reference, knownComponents) {
21821
+ this.reference = reference;
21822
+ this.knownValues = {};
21823
+ this.impliedValues = {};
21824
+ if (knownComponents) {
21825
+ for (const key in knownComponents) {
21826
+ this.knownValues[key] = knownComponents[key];
21827
+ }
21828
+ }
21829
+ const date3 = reference.getDateWithAdjustedTimezone();
21830
+ this.imply("day", date3.getDate());
21831
+ this.imply("month", date3.getMonth() + 1);
21832
+ this.imply("year", date3.getFullYear());
21833
+ this.imply("hour", 12);
21834
+ this.imply("minute", 0);
21835
+ this.imply("second", 0);
21836
+ this.imply("millisecond", 0);
21837
+ }
21838
+ static createRelativeFromReference(reference, duration3 = EmptyDuration) {
21839
+ let date3 = addDuration(reference.getDateWithAdjustedTimezone(), duration3);
21840
+ const components = new _ParsingComponents(reference);
21841
+ components.addTag("result/relativeDate");
21842
+ if ("hour" in duration3 || "minute" in duration3 || "second" in duration3 || "millisecond" in duration3) {
21843
+ components.addTag("result/relativeDateAndTime");
21844
+ assignSimilarTime(components, date3);
21845
+ assignSimilarDate(components, date3);
21846
+ components.assign("timezoneOffset", reference.getTimezoneOffset());
21847
+ } else {
21848
+ implySimilarTime(components, date3);
21849
+ components.imply("timezoneOffset", reference.getTimezoneOffset());
21850
+ if ("day" in duration3) {
21851
+ components.assign("day", date3.getDate());
21852
+ components.assign("month", date3.getMonth() + 1);
21853
+ components.assign("year", date3.getFullYear());
21854
+ components.assign("weekday", date3.getDay());
21855
+ } else if ("week" in duration3) {
21856
+ components.assign("day", date3.getDate());
21857
+ components.assign("month", date3.getMonth() + 1);
21858
+ components.assign("year", date3.getFullYear());
21859
+ components.imply("weekday", date3.getDay());
21860
+ } else {
21861
+ components.imply("day", date3.getDate());
21862
+ if ("month" in duration3) {
21863
+ components.assign("month", date3.getMonth() + 1);
21864
+ components.assign("year", date3.getFullYear());
21865
+ } else {
21866
+ components.imply("month", date3.getMonth() + 1);
21867
+ if ("year" in duration3) {
21868
+ components.assign("year", date3.getFullYear());
21869
+ } else {
21870
+ components.imply("year", date3.getFullYear());
21871
+ }
21872
+ }
21873
+ }
21874
+ }
21875
+ return components;
21876
+ }
21877
+ get(component) {
21878
+ if (component in this.knownValues) {
21879
+ return this.knownValues[component];
21880
+ }
21881
+ if (component in this.impliedValues) {
21882
+ return this.impliedValues[component];
21883
+ }
21884
+ return null;
21885
+ }
21886
+ isCertain(component) {
21887
+ return component in this.knownValues;
21888
+ }
21889
+ getCertainComponents() {
21890
+ return Object.keys(this.knownValues);
21891
+ }
21892
+ imply(component, value) {
21893
+ if (component in this.knownValues) {
21894
+ return this;
21895
+ }
21896
+ this.impliedValues[component] = value;
21897
+ return this;
21898
+ }
21899
+ assign(component, value) {
21900
+ this.knownValues[component] = value;
21901
+ delete this.impliedValues[component];
21902
+ return this;
21903
+ }
21904
+ addDurationAsImplied(duration3) {
21905
+ const currentDate = this.dateWithoutTimezoneAdjustment();
21906
+ const date3 = addDuration(currentDate, duration3);
21907
+ if ("day" in duration3 || "week" in duration3 || "month" in duration3 || "year" in duration3) {
21908
+ this.delete(["day", "weekday", "month", "year"]);
21909
+ this.imply("day", date3.getDate());
21910
+ this.imply("weekday", date3.getDay());
21911
+ this.imply("month", date3.getMonth() + 1);
21912
+ this.imply("year", date3.getFullYear());
21913
+ }
21914
+ if ("second" in duration3 || "minute" in duration3 || "hour" in duration3) {
21915
+ this.delete(["second", "minute", "hour"]);
21916
+ this.imply("second", date3.getSeconds());
21917
+ this.imply("minute", date3.getMinutes());
21918
+ this.imply("hour", date3.getHours());
21919
+ }
21920
+ return this;
21921
+ }
21922
+ delete(components) {
21923
+ if (typeof components === "string") {
21924
+ components = [components];
21925
+ }
21926
+ for (const component of components) {
21927
+ delete this.knownValues[component];
21928
+ delete this.impliedValues[component];
21929
+ }
21930
+ }
21931
+ clone() {
21932
+ const component = new _ParsingComponents(this.reference);
21933
+ component.knownValues = {};
21934
+ component.impliedValues = {};
21935
+ for (const key in this.knownValues) {
21936
+ component.knownValues[key] = this.knownValues[key];
21937
+ }
21938
+ for (const key in this.impliedValues) {
21939
+ component.impliedValues[key] = this.impliedValues[key];
21940
+ }
21941
+ return component;
21942
+ }
21943
+ isOnlyDate() {
21944
+ return !this.isCertain("hour") && !this.isCertain("minute") && !this.isCertain("second");
21945
+ }
21946
+ isOnlyTime() {
21947
+ return !this.isCertain("weekday") && !this.isCertain("day") && !this.isCertain("month") && !this.isCertain("year");
21948
+ }
21949
+ isOnlyWeekdayComponent() {
21950
+ return this.isCertain("weekday") && !this.isCertain("day") && !this.isCertain("month");
21951
+ }
21952
+ isDateWithUnknownYear() {
21953
+ return this.isCertain("month") && !this.isCertain("year");
21954
+ }
21955
+ isValidDate() {
21956
+ const date3 = new Date(Date.UTC(this.get("year"), this.get("month") - 1, this.get("day"), this.get("hour"), this.get("minute"), this.get("second"), this.get("millisecond")));
21957
+ date3.setUTCFullYear(this.get("year"));
21958
+ if (date3.getUTCFullYear() !== this.get("year"))
21959
+ return false;
21960
+ if (date3.getUTCMonth() !== this.get("month") - 1)
21961
+ return false;
21962
+ if (date3.getUTCDate() !== this.get("day"))
21963
+ return false;
21964
+ if (this.get("hour") != null && date3.getUTCHours() != this.get("hour"))
21965
+ return false;
21966
+ if (this.get("minute") != null && date3.getUTCMinutes() != this.get("minute"))
21967
+ return false;
21968
+ return true;
21969
+ }
21970
+ toString() {
21971
+ return `[ParsingComponents {
21972
+ tags: ${JSON.stringify(Array.from(this._tags).sort())},
21973
+ knownValues: ${JSON.stringify(this.knownValues)},
21974
+ impliedValues: ${JSON.stringify(this.impliedValues)}},
21975
+ reference: ${JSON.stringify(this.reference)}]`;
21976
+ }
21977
+ date() {
21978
+ const timezoneOffset = this.get("timezoneOffset") ?? this.reference.timezoneOffset;
21979
+ if (timezoneOffset === null || timezoneOffset === void 0) {
21980
+ return this.dateWithoutTimezoneAdjustment();
21981
+ }
21982
+ const date3 = new Date(Date.UTC(this.get("year"), this.get("month") - 1, this.get("day"), this.get("hour"), this.get("minute"), this.get("second"), this.get("millisecond")));
21983
+ date3.setUTCFullYear(this.get("year"));
21984
+ return new Date(date3.getTime() - timezoneOffset * 6e4);
21985
+ }
21986
+ addTag(tag) {
21987
+ this._tags.add(tag);
21988
+ return this;
21989
+ }
21990
+ addTags(tags) {
21991
+ for (const tag of tags) {
21992
+ this._tags.add(tag);
21993
+ }
21994
+ return this;
21995
+ }
21996
+ tags() {
21997
+ return new Set(this._tags);
21998
+ }
21999
+ dateWithoutTimezoneAdjustment() {
22000
+ const date3 = new Date(this.get("year"), this.get("month") - 1, this.get("day"), this.get("hour"), this.get("minute"), this.get("second"), this.get("millisecond"));
22001
+ date3.setFullYear(this.get("year"));
22002
+ return date3;
22003
+ }
22004
+ };
22005
+ var ParsingResult = class _ParsingResult {
22006
+ refDate;
22007
+ index;
22008
+ text;
22009
+ reference;
22010
+ start;
22011
+ end;
22012
+ constructor(reference, index, text2, start, end) {
22013
+ this.reference = reference;
22014
+ this.refDate = reference.instant;
22015
+ this.index = index;
22016
+ this.text = text2;
22017
+ this.start = start || new ParsingComponents(reference);
22018
+ this.end = end;
22019
+ }
22020
+ clone() {
22021
+ const result = new _ParsingResult(this.reference, this.index, this.text);
22022
+ result.start = this.start ? this.start.clone() : null;
22023
+ result.end = this.end ? this.end.clone() : null;
22024
+ return result;
22025
+ }
22026
+ date() {
22027
+ return this.start.date();
22028
+ }
22029
+ addTag(tag) {
22030
+ this.start.addTag(tag);
22031
+ if (this.end) {
22032
+ this.end.addTag(tag);
22033
+ }
22034
+ return this;
22035
+ }
22036
+ addTags(tags) {
22037
+ this.start.addTags(tags);
22038
+ if (this.end) {
22039
+ this.end.addTags(tags);
22040
+ }
22041
+ return this;
22042
+ }
22043
+ tags() {
22044
+ const combinedTags = new Set(this.start.tags());
22045
+ if (this.end) {
22046
+ for (const tag of this.end.tags()) {
22047
+ combinedTags.add(tag);
22048
+ }
22049
+ }
22050
+ return combinedTags;
22051
+ }
22052
+ toString() {
22053
+ const tags = Array.from(this.tags()).sort();
22054
+ return `[ParsingResult {index: ${this.index}, text: '${this.text}', tags: ${JSON.stringify(tags)} ...}]`;
22055
+ }
22056
+ };
22057
+
22058
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/utils/pattern.js
22059
+ function repeatedTimeunitPattern(prefix, singleTimeunitPattern, connectorPattern = "\\s{0,5},?\\s{0,5}") {
22060
+ const singleTimeunitPatternNoCapture = singleTimeunitPattern.replace(/\((?!\?)/g, "(?:");
22061
+ return `${prefix}${singleTimeunitPatternNoCapture}(?:${connectorPattern}${singleTimeunitPatternNoCapture}){0,10}`;
22062
+ }
22063
+ function extractTerms(dictionary) {
22064
+ let keys;
22065
+ if (dictionary instanceof Array) {
22066
+ keys = [...dictionary];
22067
+ } else if (dictionary instanceof Map) {
22068
+ keys = Array.from(dictionary.keys());
22069
+ } else {
22070
+ keys = Object.keys(dictionary);
22071
+ }
22072
+ return keys;
22073
+ }
22074
+ function matchAnyPattern(dictionary) {
22075
+ const joinedTerms = extractTerms(dictionary).sort((a, b) => b.length - a.length).join("|").replace(/\./g, "\\.");
22076
+ return `(?:${joinedTerms})`;
22077
+ }
22078
+
22079
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/calculation/years.js
22080
+ function findMostLikelyADYear(yearNumber) {
22081
+ if (yearNumber < 100) {
22082
+ if (yearNumber > 50) {
22083
+ yearNumber = yearNumber + 1900;
22084
+ } else {
22085
+ yearNumber = yearNumber + 2e3;
22086
+ }
22087
+ }
22088
+ return yearNumber;
22089
+ }
22090
+ function findYearClosestToRef(refDate, day, month) {
22091
+ let date3 = new Date(refDate);
22092
+ date3.setMonth(month - 1);
22093
+ date3.setDate(day);
22094
+ const nextYear = addDuration(date3, { "year": 1 });
22095
+ const lastYear = addDuration(date3, { "year": -1 });
22096
+ if (Math.abs(nextYear.getTime() - refDate.getTime()) < Math.abs(date3.getTime() - refDate.getTime())) {
22097
+ date3 = nextYear;
22098
+ } else if (Math.abs(lastYear.getTime() - refDate.getTime()) < Math.abs(date3.getTime() - refDate.getTime())) {
22099
+ date3 = lastYear;
22100
+ }
22101
+ return date3.getFullYear();
22102
+ }
22103
+
22104
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/constants.js
22105
+ var WEEKDAY_DICTIONARY = {
22106
+ sunday: 0,
22107
+ sun: 0,
22108
+ "sun.": 0,
22109
+ monday: 1,
22110
+ mon: 1,
22111
+ "mon.": 1,
22112
+ tuesday: 2,
22113
+ tue: 2,
22114
+ "tue.": 2,
22115
+ wednesday: 3,
22116
+ wed: 3,
22117
+ "wed.": 3,
22118
+ thursday: 4,
22119
+ thurs: 4,
22120
+ "thurs.": 4,
22121
+ thur: 4,
22122
+ "thur.": 4,
22123
+ thu: 4,
22124
+ "thu.": 4,
22125
+ friday: 5,
22126
+ fri: 5,
22127
+ "fri.": 5,
22128
+ saturday: 6,
22129
+ sat: 6,
22130
+ "sat.": 6
22131
+ };
22132
+ var FULL_MONTH_NAME_DICTIONARY = {
22133
+ january: 1,
22134
+ february: 2,
22135
+ march: 3,
22136
+ april: 4,
22137
+ may: 5,
22138
+ june: 6,
22139
+ july: 7,
22140
+ august: 8,
22141
+ september: 9,
22142
+ october: 10,
22143
+ november: 11,
22144
+ december: 12
22145
+ };
22146
+ var MONTH_DICTIONARY = {
22147
+ ...FULL_MONTH_NAME_DICTIONARY,
22148
+ jan: 1,
22149
+ "jan.": 1,
22150
+ feb: 2,
22151
+ "feb.": 2,
22152
+ mar: 3,
22153
+ "mar.": 3,
22154
+ apr: 4,
22155
+ "apr.": 4,
22156
+ jun: 6,
22157
+ "jun.": 6,
22158
+ jul: 7,
22159
+ "jul.": 7,
22160
+ aug: 8,
22161
+ "aug.": 8,
22162
+ sep: 9,
22163
+ "sep.": 9,
22164
+ sept: 9,
22165
+ "sept.": 9,
22166
+ oct: 10,
22167
+ "oct.": 10,
22168
+ nov: 11,
22169
+ "nov.": 11,
22170
+ dec: 12,
22171
+ "dec.": 12
22172
+ };
22173
+ var INTEGER_WORD_DICTIONARY = {
22174
+ one: 1,
22175
+ two: 2,
22176
+ three: 3,
22177
+ four: 4,
22178
+ five: 5,
22179
+ six: 6,
22180
+ seven: 7,
22181
+ eight: 8,
22182
+ nine: 9,
22183
+ ten: 10,
22184
+ eleven: 11,
22185
+ twelve: 12
22186
+ };
22187
+ var ORDINAL_WORD_DICTIONARY = {
22188
+ first: 1,
22189
+ second: 2,
22190
+ third: 3,
22191
+ fourth: 4,
22192
+ fifth: 5,
22193
+ sixth: 6,
22194
+ seventh: 7,
22195
+ eighth: 8,
22196
+ ninth: 9,
22197
+ tenth: 10,
22198
+ eleventh: 11,
22199
+ twelfth: 12,
22200
+ thirteenth: 13,
22201
+ fourteenth: 14,
22202
+ fifteenth: 15,
22203
+ sixteenth: 16,
22204
+ seventeenth: 17,
22205
+ eighteenth: 18,
22206
+ nineteenth: 19,
22207
+ twentieth: 20,
22208
+ "twenty first": 21,
22209
+ "twenty-first": 21,
22210
+ "twenty second": 22,
22211
+ "twenty-second": 22,
22212
+ "twenty third": 23,
22213
+ "twenty-third": 23,
22214
+ "twenty fourth": 24,
22215
+ "twenty-fourth": 24,
22216
+ "twenty fifth": 25,
22217
+ "twenty-fifth": 25,
22218
+ "twenty sixth": 26,
22219
+ "twenty-sixth": 26,
22220
+ "twenty seventh": 27,
22221
+ "twenty-seventh": 27,
22222
+ "twenty eighth": 28,
22223
+ "twenty-eighth": 28,
22224
+ "twenty ninth": 29,
22225
+ "twenty-ninth": 29,
22226
+ "thirtieth": 30,
22227
+ "thirty first": 31,
22228
+ "thirty-first": 31
22229
+ };
22230
+ var TIME_UNIT_DICTIONARY_NO_ABBR = {
22231
+ second: "second",
22232
+ seconds: "second",
22233
+ minute: "minute",
22234
+ minutes: "minute",
22235
+ hour: "hour",
22236
+ hours: "hour",
22237
+ day: "day",
22238
+ days: "day",
22239
+ week: "week",
22240
+ weeks: "week",
22241
+ month: "month",
22242
+ months: "month",
22243
+ quarter: "quarter",
22244
+ quarters: "quarter",
22245
+ year: "year",
22246
+ years: "year"
22247
+ };
22248
+ var TIME_UNIT_DICTIONARY = {
22249
+ s: "second",
22250
+ sec: "second",
22251
+ second: "second",
22252
+ seconds: "second",
22253
+ m: "minute",
22254
+ min: "minute",
22255
+ mins: "minute",
22256
+ minute: "minute",
22257
+ minutes: "minute",
22258
+ h: "hour",
22259
+ hr: "hour",
22260
+ hrs: "hour",
22261
+ hour: "hour",
22262
+ hours: "hour",
22263
+ d: "day",
22264
+ day: "day",
22265
+ days: "day",
22266
+ w: "week",
22267
+ week: "week",
22268
+ weeks: "week",
22269
+ mo: "month",
22270
+ mon: "month",
22271
+ mos: "month",
22272
+ month: "month",
22273
+ months: "month",
22274
+ qtr: "quarter",
22275
+ quarter: "quarter",
22276
+ quarters: "quarter",
22277
+ y: "year",
22278
+ yr: "year",
22279
+ year: "year",
22280
+ years: "year",
22281
+ ...TIME_UNIT_DICTIONARY_NO_ABBR
22282
+ };
22283
+ var NUMBER_PATTERN = `(?:${matchAnyPattern(INTEGER_WORD_DICTIONARY)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s{0,2}an?)?|an?\\b(?:\\s{0,2}few)?|few|several|the|a?\\s{0,2}couple\\s{0,2}(?:of)?)`;
22284
+ function parseNumberPattern(match) {
22285
+ const num = match.toLowerCase();
22286
+ if (INTEGER_WORD_DICTIONARY[num] !== void 0) {
22287
+ return INTEGER_WORD_DICTIONARY[num];
22288
+ } else if (num === "a" || num === "an" || num == "the") {
22289
+ return 1;
22290
+ } else if (num.match(/few/)) {
22291
+ return 3;
22292
+ } else if (num.match(/half/)) {
22293
+ return 0.5;
22294
+ } else if (num.match(/couple/)) {
22295
+ return 2;
22296
+ } else if (num.match(/several/)) {
22297
+ return 7;
22298
+ }
22299
+ return parseFloat(num);
22300
+ }
22301
+ var ORDINAL_NUMBER_PATTERN = `(?:${matchAnyPattern(ORDINAL_WORD_DICTIONARY)}|[0-9]{1,2}(?:st|nd|rd|th)?)`;
22302
+ function parseOrdinalNumberPattern(match) {
22303
+ let num = match.toLowerCase();
22304
+ if (ORDINAL_WORD_DICTIONARY[num] !== void 0) {
22305
+ return ORDINAL_WORD_DICTIONARY[num];
22306
+ }
22307
+ num = num.replace(/(?:st|nd|rd|th)$/i, "");
22308
+ return parseInt(num);
22309
+ }
22310
+ var YEAR_PATTERN = `(?:[1-9][0-9]{0,3}\\s{0,2}(?:BE|AD|BC|BCE|CE)|[1-9][0-9]{3}|[0-9]{2}(?!\\w|:\\d|\\s+(?:am|pm|o\\s*clock|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)))`;
22311
+ function parseYear(match) {
22312
+ if (/BE/i.test(match)) {
22313
+ match = match.replace(/BE/i, "");
22314
+ return parseInt(match) - 543;
22315
+ }
22316
+ if (/BCE?/i.test(match)) {
22317
+ match = match.replace(/BCE?/i, "");
22318
+ return -parseInt(match);
22319
+ }
22320
+ if (/(AD|CE)/i.test(match)) {
22321
+ match = match.replace(/(AD|CE)/i, "");
22322
+ return parseInt(match);
22323
+ }
22324
+ const rawYearNumber = parseInt(match);
22325
+ return findMostLikelyADYear(rawYearNumber);
22326
+ }
22327
+ var SINGLE_TIME_UNIT_PATTERN = `(${NUMBER_PATTERN})\\s{0,3}(${matchAnyPattern(TIME_UNIT_DICTIONARY)})`;
22328
+ var SINGLE_TIME_UNIT_REGEX = new RegExp(SINGLE_TIME_UNIT_PATTERN, "i");
22329
+ var SINGLE_TIME_UNIT_NO_ABBR_PATTERN = `(${NUMBER_PATTERN})\\s{0,3}(${matchAnyPattern(TIME_UNIT_DICTIONARY_NO_ABBR)})`;
22330
+ var TIME_UNIT_CONNECTOR_PATTERN = `\\s{0,5},?(?:\\s*and)?\\s{0,5}`;
22331
+ var TIME_UNITS_PATTERN = repeatedTimeunitPattern(`(?:(?:about|around)\\s{0,3})?`, SINGLE_TIME_UNIT_PATTERN, TIME_UNIT_CONNECTOR_PATTERN);
22332
+ var TIME_UNITS_NO_ABBR_PATTERN = repeatedTimeunitPattern(`(?:(?:about|around)\\s{0,3})?`, SINGLE_TIME_UNIT_NO_ABBR_PATTERN, TIME_UNIT_CONNECTOR_PATTERN);
22333
+ function parseDuration(timeunitText) {
22334
+ const fragments = {};
22335
+ let remainingText = timeunitText;
22336
+ let match = SINGLE_TIME_UNIT_REGEX.exec(remainingText);
22337
+ while (match) {
22338
+ collectDateTimeFragment(fragments, match);
22339
+ remainingText = remainingText.substring(match[0].length).trim();
22340
+ match = SINGLE_TIME_UNIT_REGEX.exec(remainingText);
22341
+ }
22342
+ if (Object.keys(fragments).length == 0) {
22343
+ return null;
22344
+ }
22345
+ return fragments;
22346
+ }
22347
+ function collectDateTimeFragment(fragments, match) {
22348
+ if (match[0].match(/^[a-zA-Z]+$/)) {
22349
+ return;
22350
+ }
22351
+ const num = parseNumberPattern(match[1]);
22352
+ const unit = TIME_UNIT_DICTIONARY[match[2].toLowerCase()];
22353
+ fragments[unit] = num;
22354
+ }
22355
+
22356
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/parsers/AbstractParserWithWordBoundary.js
22357
+ var AbstractParserWithWordBoundaryChecking = class {
22358
+ innerPatternHasChange(context, currentInnerPattern) {
22359
+ return this.innerPattern(context) !== currentInnerPattern;
22360
+ }
22361
+ patternLeftBoundary() {
22362
+ return `(\\W|^)`;
22363
+ }
22364
+ cachedInnerPattern = null;
22365
+ cachedPattern = null;
22366
+ pattern(context) {
22367
+ if (this.cachedInnerPattern) {
22368
+ if (!this.innerPatternHasChange(context, this.cachedInnerPattern)) {
22369
+ return this.cachedPattern;
22370
+ }
22371
+ }
22372
+ this.cachedInnerPattern = this.innerPattern(context);
22373
+ this.cachedPattern = new RegExp(`${this.patternLeftBoundary()}${this.cachedInnerPattern.source}`, this.cachedInnerPattern.flags);
22374
+ return this.cachedPattern;
22375
+ }
22376
+ extract(context, match) {
22377
+ const header = match[1] ?? "";
22378
+ match.index = match.index + header.length;
22379
+ match[0] = match[0].substring(header.length);
22380
+ for (let i = 2; i < match.length; i++) {
22381
+ match[i - 1] = match[i];
22382
+ }
22383
+ return this.innerExtract(context, match);
22384
+ }
22385
+ };
22386
+
22387
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENTimeUnitWithinFormatParser.js
22388
+ var PATTERN_WITH_OPTIONAL_PREFIX = new RegExp(`(?:(?:within|in|for)\\s*)?(?:(?:about|around|roughly|approximately|just)\\s*(?:~\\s*)?)?(${TIME_UNITS_PATTERN})(?=\\W|$)`, "i");
22389
+ var PATTERN_WITH_PREFIX = new RegExp(`(?:within|in|for)\\s*(?:(?:about|around|roughly|approximately|just)\\s*(?:~\\s*)?)?(${TIME_UNITS_PATTERN})(?=\\W|$)`, "i");
22390
+ var PATTERN_WITH_PREFIX_STRICT = new RegExp(`(?:within|in|for)\\s*(?:(?:about|around|roughly|approximately|just)\\s*(?:~\\s*)?)?(${TIME_UNITS_NO_ABBR_PATTERN})(?=\\W|$)`, "i");
22391
+ var ENTimeUnitWithinFormatParser = class extends AbstractParserWithWordBoundaryChecking {
22392
+ strictMode;
22393
+ constructor(strictMode) {
22394
+ super();
22395
+ this.strictMode = strictMode;
22396
+ }
22397
+ innerPattern(context) {
22398
+ if (this.strictMode) {
22399
+ return PATTERN_WITH_PREFIX_STRICT;
22400
+ }
22401
+ return context.option.forwardDate ? PATTERN_WITH_OPTIONAL_PREFIX : PATTERN_WITH_PREFIX;
22402
+ }
22403
+ innerExtract(context, match) {
22404
+ if (match[0].match(/^for\s*the\s*\w+/)) {
22405
+ return null;
22406
+ }
22407
+ const timeUnits = parseDuration(match[1]);
22408
+ if (!timeUnits) {
22409
+ return null;
22410
+ }
22411
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
22412
+ }
22413
+ };
22414
+
22415
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENMonthNameLittleEndianParser.js
22416
+ var PATTERN = new RegExp(`(?:on\\s{0,3})?(${ORDINAL_NUMBER_PATTERN})(?:\\s{0,3}(?:to|\\-|\\\u2013|until|through|till)\\s{0,3}(${ORDINAL_NUMBER_PATTERN}))?(?:-|/|\\s{0,3}(?:of)?\\s{0,3})(${matchAnyPattern(MONTH_DICTIONARY)})(?:(?:-|/|,?\\s{0,3})(${YEAR_PATTERN}(?!\\w)))?(?=\\W|$)`, "i");
22417
+ var DATE_GROUP = 1;
22418
+ var DATE_TO_GROUP = 2;
22419
+ var MONTH_NAME_GROUP = 3;
22420
+ var YEAR_GROUP = 4;
22421
+ var ENMonthNameLittleEndianParser = class extends AbstractParserWithWordBoundaryChecking {
22422
+ innerPattern() {
22423
+ return PATTERN;
22424
+ }
22425
+ innerExtract(context, match) {
22426
+ const result = context.createParsingResult(match.index, match[0]);
22427
+ const month = MONTH_DICTIONARY[match[MONTH_NAME_GROUP].toLowerCase()];
22428
+ const day = parseOrdinalNumberPattern(match[DATE_GROUP]);
22429
+ if (day > 31) {
22430
+ match.index = match.index + match[DATE_GROUP].length;
22431
+ return null;
22432
+ }
22433
+ result.start.assign("month", month);
22434
+ result.start.assign("day", day);
22435
+ if (match[YEAR_GROUP]) {
22436
+ const yearNumber = parseYear(match[YEAR_GROUP]);
22437
+ result.start.assign("year", yearNumber);
22438
+ } else {
22439
+ const year = findYearClosestToRef(context.refDate, day, month);
22440
+ result.start.imply("year", year);
22441
+ }
22442
+ if (match[DATE_TO_GROUP]) {
22443
+ const endDate = parseOrdinalNumberPattern(match[DATE_TO_GROUP]);
22444
+ result.end = result.start.clone();
22445
+ result.end.assign("day", endDate);
22446
+ }
22447
+ return result;
22448
+ }
22449
+ };
22450
+
22451
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENMonthNameMiddleEndianParser.js
22452
+ var PATTERN2 = new RegExp(`(${matchAnyPattern(MONTH_DICTIONARY)})(?:-|/|\\s*,?\\s*)(${ORDINAL_NUMBER_PATTERN})(?!\\s*(?:am|pm))\\s*(?:(?:to|\\-)\\s*(${ORDINAL_NUMBER_PATTERN})\\s*)?(?:(?:-|/|\\s*,\\s*|\\s+)(${YEAR_PATTERN}))?(?=\\W|$)(?!\\:\\d)`, "i");
22453
+ var MONTH_NAME_GROUP2 = 1;
22454
+ var DATE_GROUP2 = 2;
22455
+ var DATE_TO_GROUP2 = 3;
22456
+ var YEAR_GROUP2 = 4;
22457
+ var ENMonthNameMiddleEndianParser = class extends AbstractParserWithWordBoundaryChecking {
22458
+ shouldSkipYearLikeDate;
22459
+ constructor(shouldSkipYearLikeDate) {
22460
+ super();
22461
+ this.shouldSkipYearLikeDate = shouldSkipYearLikeDate;
22462
+ }
22463
+ innerPattern() {
22464
+ return PATTERN2;
22465
+ }
22466
+ innerExtract(context, match) {
22467
+ const month = MONTH_DICTIONARY[match[MONTH_NAME_GROUP2].toLowerCase()];
22468
+ const day = parseOrdinalNumberPattern(match[DATE_GROUP2]);
22469
+ if (day > 31) {
22470
+ return null;
22471
+ }
22472
+ if (this.shouldSkipYearLikeDate) {
22473
+ if (!match[DATE_TO_GROUP2] && !match[YEAR_GROUP2] && match[DATE_GROUP2].match(/^\d{2}$/)) {
22474
+ return null;
22475
+ }
22476
+ }
22477
+ const components = context.createParsingComponents({
22478
+ day,
22479
+ month
22480
+ }).addTag("parser/ENMonthNameMiddleEndianParser");
22481
+ if (match[YEAR_GROUP2]) {
22482
+ const year = parseYear(match[YEAR_GROUP2]);
22483
+ components.assign("year", year);
22484
+ } else {
22485
+ const year = findYearClosestToRef(context.refDate, day, month);
22486
+ components.imply("year", year);
22487
+ }
22488
+ if (!match[DATE_TO_GROUP2]) {
22489
+ return components;
22490
+ }
22491
+ const endDate = parseOrdinalNumberPattern(match[DATE_TO_GROUP2]);
22492
+ const result = context.createParsingResult(match.index, match[0]);
22493
+ result.start = components;
22494
+ result.end = components.clone();
22495
+ result.end.assign("day", endDate);
22496
+ return result;
22497
+ }
22498
+ };
22499
+
22500
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENMonthNameParser.js
22501
+ var PATTERN3 = new RegExp(`((?:in)\\s*)?(${matchAnyPattern(MONTH_DICTIONARY)})\\s*(?:(?:,|-|of)?\\s*(${YEAR_PATTERN})?)?(?=[^\\s\\w]|\\s+[^0-9]|\\s+$|$)`, "i");
22502
+ var PREFIX_GROUP = 1;
22503
+ var MONTH_NAME_GROUP3 = 2;
22504
+ var YEAR_GROUP3 = 3;
22505
+ var ENMonthNameParser = class extends AbstractParserWithWordBoundaryChecking {
22506
+ innerPattern() {
22507
+ return PATTERN3;
22508
+ }
22509
+ innerExtract(context, match) {
22510
+ const monthName = match[MONTH_NAME_GROUP3].toLowerCase();
22511
+ if (match[0].length <= 3 && !FULL_MONTH_NAME_DICTIONARY[monthName]) {
22512
+ return null;
22513
+ }
22514
+ const result = context.createParsingResult(match.index + (match[PREFIX_GROUP] || "").length, match.index + match[0].length);
22515
+ result.start.imply("day", 1);
22516
+ result.start.addTag("parser/ENMonthNameParser");
22517
+ const month = MONTH_DICTIONARY[monthName];
22518
+ result.start.assign("month", month);
22519
+ if (match[YEAR_GROUP3]) {
22520
+ const year = parseYear(match[YEAR_GROUP3]);
22521
+ result.start.assign("year", year);
22522
+ } else {
22523
+ const year = findYearClosestToRef(context.refDate, 1, month);
22524
+ result.start.imply("year", year);
22525
+ }
22526
+ return result;
22527
+ }
22528
+ };
22529
+
22530
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENYearMonthDayParser.js
22531
+ var PATTERN4 = new RegExp(`([0-9]{4})[-\\.\\/\\s](?:(${matchAnyPattern(MONTH_DICTIONARY)})|([0-9]{1,2}))[-\\.\\/\\s]([0-9]{1,2})(?=\\W|$)`, "i");
22532
+ var YEAR_NUMBER_GROUP = 1;
22533
+ var MONTH_NAME_GROUP4 = 2;
22534
+ var MONTH_NUMBER_GROUP = 3;
22535
+ var DATE_NUMBER_GROUP = 4;
22536
+ var ENYearMonthDayParser = class extends AbstractParserWithWordBoundaryChecking {
22537
+ strictMonthDateOrder;
22538
+ constructor(strictMonthDateOrder) {
22539
+ super();
22540
+ this.strictMonthDateOrder = strictMonthDateOrder;
22541
+ }
22542
+ innerPattern() {
22543
+ return PATTERN4;
22544
+ }
22545
+ innerExtract(context, match) {
22546
+ const year = parseInt(match[YEAR_NUMBER_GROUP]);
22547
+ let day = parseInt(match[DATE_NUMBER_GROUP]);
22548
+ let month = match[MONTH_NUMBER_GROUP] ? parseInt(match[MONTH_NUMBER_GROUP]) : MONTH_DICTIONARY[match[MONTH_NAME_GROUP4].toLowerCase()];
22549
+ if (month < 1 || month > 12) {
22550
+ if (this.strictMonthDateOrder) {
22551
+ return null;
22552
+ }
22553
+ if (day >= 1 && day <= 12) {
22554
+ [month, day] = [day, month];
22555
+ }
22556
+ }
22557
+ if (day < 1 || day > 31) {
22558
+ return null;
22559
+ }
22560
+ return {
22561
+ day,
22562
+ month,
22563
+ year
22564
+ };
22565
+ }
22566
+ };
22567
+
22568
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENYearMonthNameParser.js
22569
+ var YEAR_PATTERN2 = `(?:[1-9][0-9]{0,3}\\s{0,2}(?:BE|AD|BC|BCE|CE)|[1-9][0-9]{3})`;
22570
+ var PATTERN5 = new RegExp(`(${YEAR_PATTERN2})(?:\\s*[-.\\/,]?\\s*|\\s+of\\s+)(${matchAnyPattern(MONTH_DICTIONARY)})(?=[^\\s\\w]|\\s+[^0-9]|\\s+$|$)`, "i");
22571
+ var YEAR_GROUP4 = 1;
22572
+ var MONTH_NAME_GROUP5 = 2;
22573
+ var ENYearMonthNameParser = class extends AbstractParserWithWordBoundaryChecking {
22574
+ innerPattern() {
22575
+ return PATTERN5;
22576
+ }
22577
+ innerExtract(context, match) {
22578
+ const year = parseYear(match[YEAR_GROUP4]);
22579
+ const monthName = match[MONTH_NAME_GROUP5].toLowerCase();
22580
+ const month = MONTH_DICTIONARY[monthName];
22581
+ const result = context.createParsingResult(match.index, match[0]);
22582
+ result.start.imply("day", 1);
22583
+ result.start.assign("month", month);
22584
+ result.start.assign("year", year);
22585
+ result.start.addTag("parser/ENYearMonthNameParser");
22586
+ return result;
22587
+ }
22588
+ };
22589
+
22590
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENSlashMonthFormatParser.js
22591
+ var PATTERN6 = new RegExp("([0-9]|0[1-9]|1[012])/([0-9]{4})", "i");
22592
+ var MONTH_GROUP = 1;
22593
+ var YEAR_GROUP5 = 2;
22594
+ var ENSlashMonthFormatParser = class extends AbstractParserWithWordBoundaryChecking {
22595
+ innerPattern() {
22596
+ return PATTERN6;
22597
+ }
22598
+ innerExtract(context, match) {
22599
+ const year = parseInt(match[YEAR_GROUP5]);
22600
+ const month = parseInt(match[MONTH_GROUP]);
22601
+ return context.createParsingComponents().imply("day", 1).assign("month", month).assign("year", year);
22602
+ }
22603
+ };
22604
+
22605
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/parsers/AbstractTimeExpressionParser.js
22606
+ function primaryTimePattern(leftBoundary, primaryPrefix, primarySuffix, flags) {
22607
+ return new RegExp(`${leftBoundary}${primaryPrefix}(\\d{1,4})(?:(?:\\.|:|\uFF1A)(\\d{1,2})(?:(?::|\uFF1A)(\\d{2})(?:\\.(\\d{1,6}))?)?)?(?:\\s*(a\\.m\\.|p\\.m\\.|am?|pm?))?${primarySuffix}`, flags);
22608
+ }
22609
+ function followingTimePatten(followingPhase, followingSuffix) {
22610
+ return new RegExp(`^(${followingPhase})(\\d{1,4})(?:(?:\\.|\\:|\\\uFF1A)(\\d{1,2})(?:(?:\\.|\\:|\\\uFF1A)(\\d{1,2})(?:\\.(\\d{1,6}))?)?)?(?:\\s*(a\\.m\\.|p\\.m\\.|am?|pm?))?${followingSuffix}`, "i");
22611
+ }
22612
+ var HOUR_GROUP = 2;
22613
+ var MINUTE_GROUP = 3;
22614
+ var SECOND_GROUP = 4;
22615
+ var MILLI_SECOND_GROUP = 5;
22616
+ var AM_PM_HOUR_GROUP = 6;
22617
+ var AbstractTimeExpressionParser = class {
22618
+ strictMode;
22619
+ constructor(strictMode = false) {
22620
+ this.strictMode = strictMode;
22621
+ }
22622
+ patternFlags() {
22623
+ return "i";
22624
+ }
22625
+ primaryPatternLeftBoundary() {
22626
+ return `(^|\\s|T|\\b)`;
22627
+ }
22628
+ primarySuffix() {
22629
+ return `(?!/)(?=\\W|$)`;
22630
+ }
22631
+ followingSuffix() {
22632
+ return `(?!/)(?=\\W|$)`;
22633
+ }
22634
+ pattern(context) {
22635
+ return this.getPrimaryTimePatternThroughCache();
22636
+ }
22637
+ extract(context, match) {
22638
+ const startComponents = this.extractPrimaryTimeComponents(context, match);
22639
+ if (!startComponents) {
22640
+ if (match[0].match(/^\d{4}/)) {
22641
+ match.index += 4;
22642
+ return null;
22643
+ }
22644
+ match.index += match[0].length;
22645
+ return null;
22646
+ }
22647
+ const index = match.index + match[1].length;
22648
+ const text2 = match[0].substring(match[1].length);
22649
+ const result = context.createParsingResult(index, text2, startComponents);
22650
+ match.index += match[0].length;
22651
+ const remainingText = context.text.substring(match.index);
22652
+ const followingPattern = this.getFollowingTimePatternThroughCache();
22653
+ const followingMatch = followingPattern.exec(remainingText);
22654
+ if (text2.match(/^\d{3,4}/) && followingMatch) {
22655
+ if (followingMatch[0].match(/^\s*([+-])\s*\d{2,4}$/)) {
22656
+ return null;
22657
+ }
22658
+ if (followingMatch[0].match(/^\s*([+-])\s*\d{2}\W\d{2}/)) {
22659
+ return null;
22660
+ }
22661
+ }
22662
+ if (!followingMatch || followingMatch[0].match(/^\s*([+-])\s*\d{3,4}$/)) {
22663
+ return this.checkAndReturnWithoutFollowingPattern(result);
22664
+ }
22665
+ result.end = this.extractFollowingTimeComponents(context, followingMatch, result);
22666
+ if (result.end) {
22667
+ result.text += followingMatch[0];
22668
+ }
22669
+ return this.checkAndReturnWithFollowingPattern(result);
22670
+ }
22671
+ extractPrimaryTimeComponents(context, match, strict2 = false) {
22672
+ const components = context.createParsingComponents();
22673
+ let minute = 0;
22674
+ let meridiem = null;
22675
+ let hour = parseInt(match[HOUR_GROUP]);
22676
+ if (hour > 100) {
22677
+ if (match[HOUR_GROUP].length == 4 && match[MINUTE_GROUP] == null && !match[AM_PM_HOUR_GROUP]) {
22678
+ return null;
22679
+ }
22680
+ if (this.strictMode || match[MINUTE_GROUP] != null) {
22681
+ return null;
22682
+ }
22683
+ minute = hour % 100;
22684
+ hour = Math.floor(hour / 100);
22685
+ }
22686
+ if (hour > 24) {
22687
+ return null;
22688
+ }
22689
+ if (match[MINUTE_GROUP] != null) {
22690
+ if (match[MINUTE_GROUP].length == 1 && !match[AM_PM_HOUR_GROUP]) {
22691
+ return null;
22692
+ }
22693
+ minute = parseInt(match[MINUTE_GROUP]);
22694
+ }
22695
+ if (minute >= 60) {
22696
+ return null;
22697
+ }
22698
+ if (hour > 12) {
22699
+ meridiem = Meridiem.PM;
22700
+ }
22701
+ if (match[AM_PM_HOUR_GROUP] != null) {
22702
+ if (hour > 12)
22703
+ return null;
22704
+ const ampm = match[AM_PM_HOUR_GROUP][0].toLowerCase();
22705
+ if (ampm == "a") {
22706
+ meridiem = Meridiem.AM;
22707
+ if (hour == 12) {
22708
+ hour = 0;
22709
+ }
22710
+ }
22711
+ if (ampm == "p") {
22712
+ meridiem = Meridiem.PM;
22713
+ if (hour != 12) {
22714
+ hour += 12;
22715
+ }
22716
+ }
22717
+ }
22718
+ components.assign("hour", hour);
22719
+ components.assign("minute", minute);
22720
+ if (meridiem !== null) {
22721
+ components.assign("meridiem", meridiem);
22722
+ } else {
22723
+ if (hour < 12) {
22724
+ components.imply("meridiem", Meridiem.AM);
22725
+ } else {
22726
+ components.imply("meridiem", Meridiem.PM);
22727
+ }
22728
+ }
22729
+ if (match[MILLI_SECOND_GROUP] != null) {
22730
+ const millisecond = parseInt(match[MILLI_SECOND_GROUP].substring(0, 3));
22731
+ if (millisecond >= 1e3)
22732
+ return null;
22733
+ components.assign("millisecond", millisecond);
22734
+ }
22735
+ if (match[SECOND_GROUP] != null) {
22736
+ const second = parseInt(match[SECOND_GROUP]);
22737
+ if (second >= 60)
22738
+ return null;
22739
+ components.assign("second", second);
22740
+ }
22741
+ return components;
22742
+ }
22743
+ extractFollowingTimeComponents(context, match, result) {
22744
+ const components = context.createParsingComponents();
22745
+ if (match[MILLI_SECOND_GROUP] != null) {
22746
+ const millisecond = parseInt(match[MILLI_SECOND_GROUP].substring(0, 3));
22747
+ if (millisecond >= 1e3)
22748
+ return null;
22749
+ components.assign("millisecond", millisecond);
22750
+ }
22751
+ if (match[SECOND_GROUP] != null) {
22752
+ const second = parseInt(match[SECOND_GROUP]);
22753
+ if (second >= 60)
22754
+ return null;
22755
+ components.assign("second", second);
22756
+ }
22757
+ let hour = parseInt(match[HOUR_GROUP]);
22758
+ let minute = 0;
22759
+ let meridiem = -1;
22760
+ if (match[MINUTE_GROUP] != null) {
22761
+ minute = parseInt(match[MINUTE_GROUP]);
22762
+ } else if (hour > 100) {
22763
+ minute = hour % 100;
22764
+ hour = Math.floor(hour / 100);
22765
+ }
22766
+ if (minute >= 60 || hour > 24) {
22767
+ return null;
22768
+ }
22769
+ if (hour >= 12) {
22770
+ meridiem = Meridiem.PM;
22771
+ }
22772
+ if (match[AM_PM_HOUR_GROUP] != null) {
22773
+ if (hour > 12) {
22774
+ return null;
22775
+ }
22776
+ const ampm = match[AM_PM_HOUR_GROUP][0].toLowerCase();
22777
+ if (ampm == "a") {
22778
+ meridiem = Meridiem.AM;
22779
+ if (hour == 12) {
22780
+ hour = 0;
22781
+ if (!components.isCertain("day")) {
22782
+ components.imply("day", components.get("day") + 1);
22783
+ }
22784
+ }
22785
+ }
22786
+ if (ampm == "p") {
22787
+ meridiem = Meridiem.PM;
22788
+ if (hour != 12)
22789
+ hour += 12;
22790
+ }
22791
+ if (!result.start.isCertain("meridiem")) {
22792
+ if (meridiem == Meridiem.AM) {
22793
+ result.start.imply("meridiem", Meridiem.AM);
22794
+ if (result.start.get("hour") == 12) {
22795
+ result.start.assign("hour", 0);
22796
+ }
22797
+ } else {
22798
+ result.start.imply("meridiem", Meridiem.PM);
22799
+ if (result.start.get("hour") != 12) {
22800
+ result.start.assign("hour", result.start.get("hour") + 12);
22801
+ }
22802
+ }
22803
+ }
22804
+ }
22805
+ components.assign("hour", hour);
22806
+ components.assign("minute", minute);
22807
+ if (meridiem >= 0) {
22808
+ components.assign("meridiem", meridiem);
22809
+ } else {
22810
+ const startAtPM = result.start.isCertain("meridiem") && result.start.get("hour") > 12;
22811
+ if (startAtPM) {
22812
+ if (result.start.get("hour") - 12 > hour) {
22813
+ components.imply("meridiem", Meridiem.AM);
22814
+ } else if (hour <= 12) {
22815
+ components.assign("hour", hour + 12);
22816
+ components.assign("meridiem", Meridiem.PM);
22817
+ }
22818
+ } else if (hour > 12) {
22819
+ components.imply("meridiem", Meridiem.PM);
22820
+ } else if (hour <= 12) {
22821
+ components.imply("meridiem", Meridiem.AM);
22822
+ }
22823
+ }
22824
+ if (components.date().getTime() < result.start.date().getTime()) {
22825
+ components.imply("day", components.get("day") + 1);
22826
+ }
22827
+ return components;
22828
+ }
22829
+ checkAndReturnWithoutFollowingPattern(result) {
22830
+ if (result.text.match(/^\d$/)) {
22831
+ return null;
22832
+ }
22833
+ if (result.text.match(/^\d\d\d+$/)) {
22834
+ return null;
22835
+ }
22836
+ if (result.text.match(/\d[apAP]$/)) {
22837
+ return null;
22838
+ }
22839
+ const endingWithNumbers = result.text.match(/[^\d:.](\d[\d.]+)$/);
22840
+ if (endingWithNumbers) {
22841
+ const endingNumbers = endingWithNumbers[1];
22842
+ if (this.strictMode) {
22843
+ return null;
22844
+ }
22845
+ if (endingNumbers.includes(".") && !endingNumbers.match(/\d(\.\d{2})+$/)) {
22846
+ return null;
22847
+ }
22848
+ const endingNumberVal = parseInt(endingNumbers);
22849
+ if (endingNumberVal > 24) {
22850
+ return null;
22851
+ }
22852
+ }
22853
+ return result;
22854
+ }
22855
+ checkAndReturnWithFollowingPattern(result) {
22856
+ if (result.text.match(/^\d+-\d+$/)) {
22857
+ return null;
22858
+ }
22859
+ const endingWithNumbers = result.text.match(/[^\d:.](\d[\d.]+)\s*-\s*(\d[\d.]+)$/);
22860
+ if (endingWithNumbers) {
22861
+ if (this.strictMode) {
22862
+ return null;
22863
+ }
22864
+ const startingNumbers = endingWithNumbers[1];
22865
+ const endingNumbers = endingWithNumbers[2];
22866
+ if (endingNumbers.includes(".") && !endingNumbers.match(/\d(\.\d{2})+$/)) {
22867
+ return null;
22868
+ }
22869
+ const endingNumberVal = parseInt(endingNumbers);
22870
+ const startingNumberVal = parseInt(startingNumbers);
22871
+ if (endingNumberVal > 24 || startingNumberVal > 24) {
22872
+ return null;
22873
+ }
22874
+ }
22875
+ return result;
22876
+ }
22877
+ cachedPrimaryPrefix = null;
22878
+ cachedPrimarySuffix = null;
22879
+ cachedPrimaryTimePattern = null;
22880
+ getPrimaryTimePatternThroughCache() {
22881
+ const primaryPrefix = this.primaryPrefix();
22882
+ const primarySuffix = this.primarySuffix();
22883
+ if (this.cachedPrimaryPrefix === primaryPrefix && this.cachedPrimarySuffix === primarySuffix) {
22884
+ return this.cachedPrimaryTimePattern;
22885
+ }
22886
+ this.cachedPrimaryTimePattern = primaryTimePattern(this.primaryPatternLeftBoundary(), primaryPrefix, primarySuffix, this.patternFlags());
22887
+ this.cachedPrimaryPrefix = primaryPrefix;
22888
+ this.cachedPrimarySuffix = primarySuffix;
22889
+ return this.cachedPrimaryTimePattern;
22890
+ }
22891
+ cachedFollowingPhase = null;
22892
+ cachedFollowingSuffix = null;
22893
+ cachedFollowingTimePatten = null;
22894
+ getFollowingTimePatternThroughCache() {
22895
+ const followingPhase = this.followingPhase();
22896
+ const followingSuffix = this.followingSuffix();
22897
+ if (this.cachedFollowingPhase === followingPhase && this.cachedFollowingSuffix === followingSuffix) {
22898
+ return this.cachedFollowingTimePatten;
22899
+ }
22900
+ this.cachedFollowingTimePatten = followingTimePatten(followingPhase, followingSuffix);
22901
+ this.cachedFollowingPhase = followingPhase;
22902
+ this.cachedFollowingSuffix = followingSuffix;
22903
+ return this.cachedFollowingTimePatten;
22904
+ }
22905
+ };
22906
+
22907
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENTimeExpressionParser.js
22908
+ var ENTimeExpressionParser = class extends AbstractTimeExpressionParser {
22909
+ constructor(strictMode) {
22910
+ super(strictMode);
22911
+ }
22912
+ followingPhase() {
22913
+ return "\\s*(?:\\-|\\\u2013|\\~|\\\u301C|to|until|through|till|\\?)\\s*";
22914
+ }
22915
+ primaryPrefix() {
22916
+ return "(?:(?:at|from)\\s*)??";
22917
+ }
22918
+ primarySuffix() {
22919
+ return "(?:\\s*(?:o\\W*clock|at\\s*night|in\\s*the\\s*(?:morning|afternoon)))?(?!/)(?=\\W|$)";
22920
+ }
22921
+ extractPrimaryTimeComponents(context, match) {
22922
+ const components = super.extractPrimaryTimeComponents(context, match);
22923
+ if (!components) {
22924
+ return components;
22925
+ }
22926
+ if (match[0].endsWith("night")) {
22927
+ const hour = components.get("hour");
22928
+ if (hour >= 6 && hour < 12) {
22929
+ components.assign("hour", components.get("hour") + 12);
22930
+ components.assign("meridiem", Meridiem.PM);
22931
+ } else if (hour < 6) {
22932
+ components.assign("meridiem", Meridiem.AM);
22933
+ }
22934
+ }
22935
+ if (match[0].endsWith("afternoon")) {
22936
+ components.assign("meridiem", Meridiem.PM);
22937
+ const hour = components.get("hour");
22938
+ if (hour >= 0 && hour <= 6) {
22939
+ components.assign("hour", components.get("hour") + 12);
22940
+ }
22941
+ }
22942
+ if (match[0].endsWith("morning")) {
22943
+ components.assign("meridiem", Meridiem.AM);
22944
+ const hour = components.get("hour");
22945
+ if (hour < 12) {
22946
+ components.assign("hour", components.get("hour"));
22947
+ }
22948
+ }
22949
+ return components.addTag("parser/ENTimeExpressionParser");
22950
+ }
22951
+ extractFollowingTimeComponents(context, match, result) {
22952
+ const followingComponents = super.extractFollowingTimeComponents(context, match, result);
22953
+ if (followingComponents) {
22954
+ followingComponents.addTag("parser/ENTimeExpressionParser");
22955
+ }
22956
+ return followingComponents;
22957
+ }
22958
+ };
22959
+
22960
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENTimeUnitAgoFormatParser.js
22961
+ var PATTERN7 = new RegExp(`(${TIME_UNITS_PATTERN})\\s{0,5}(?:ago|before|earlier)(?=\\W|$)`, "i");
22962
+ var STRICT_PATTERN = new RegExp(`(${TIME_UNITS_NO_ABBR_PATTERN})\\s{0,5}(?:ago|before|earlier)(?=\\W|$)`, "i");
22963
+ var ENTimeUnitAgoFormatParser = class extends AbstractParserWithWordBoundaryChecking {
22964
+ strictMode;
22965
+ constructor(strictMode) {
22966
+ super();
22967
+ this.strictMode = strictMode;
22968
+ }
22969
+ innerPattern() {
22970
+ return this.strictMode ? STRICT_PATTERN : PATTERN7;
22971
+ }
22972
+ innerExtract(context, match) {
22973
+ const duration3 = parseDuration(match[1]);
22974
+ if (!duration3) {
22975
+ return null;
22976
+ }
22977
+ return ParsingComponents.createRelativeFromReference(context.reference, reverseDuration(duration3));
22978
+ }
22979
+ };
22980
+
22981
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENTimeUnitLaterFormatParser.js
22982
+ var PATTERN8 = new RegExp(`(${TIME_UNITS_PATTERN})\\s{0,5}(?:later|after|from now|henceforth|forward|out)(?=(?:\\W|$))`, "i");
22983
+ var STRICT_PATTERN2 = new RegExp(`(${TIME_UNITS_NO_ABBR_PATTERN})\\s{0,5}(later|after|from now)(?=\\W|$)`, "i");
22984
+ var GROUP_NUM_TIMEUNITS = 1;
22985
+ var ENTimeUnitLaterFormatParser = class extends AbstractParserWithWordBoundaryChecking {
22986
+ strictMode;
22987
+ constructor(strictMode) {
22988
+ super();
22989
+ this.strictMode = strictMode;
22990
+ }
22991
+ innerPattern() {
22992
+ return this.strictMode ? STRICT_PATTERN2 : PATTERN8;
22993
+ }
22994
+ innerExtract(context, match) {
22995
+ const timeUnits = parseDuration(match[GROUP_NUM_TIMEUNITS]);
22996
+ if (!timeUnits) {
22997
+ return null;
22998
+ }
22999
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
23000
+ }
23001
+ };
23002
+
23003
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/abstractRefiners.js
23004
+ var Filter = class {
23005
+ refine(context, results) {
23006
+ return results.filter((r) => this.isValid(context, r));
23007
+ }
23008
+ };
23009
+ var MergingRefiner = class {
23010
+ refine(context, results) {
23011
+ if (results.length < 2) {
23012
+ return results;
23013
+ }
23014
+ const mergedResults = [];
23015
+ let curResult = results[0];
23016
+ let nextResult = null;
23017
+ for (let i = 1; i < results.length; i++) {
23018
+ nextResult = results[i];
23019
+ const textBetween = context.text.substring(curResult.index + curResult.text.length, nextResult.index);
23020
+ if (!this.shouldMergeResults(textBetween, curResult, nextResult, context)) {
23021
+ mergedResults.push(curResult);
23022
+ curResult = nextResult;
23023
+ } else {
23024
+ const left = curResult;
23025
+ const right = nextResult;
23026
+ const mergedResult = this.mergeResults(textBetween, left, right, context);
23027
+ context.debug(() => {
23028
+ console.log(`${this.constructor.name} merged ${left} and ${right} into ${mergedResult}`);
23029
+ });
23030
+ curResult = mergedResult;
23031
+ }
23032
+ }
23033
+ if (curResult != null) {
23034
+ mergedResults.push(curResult);
23035
+ }
23036
+ return mergedResults;
23037
+ }
23038
+ };
23039
+
23040
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/refiners/AbstractMergeDateRangeRefiner.js
23041
+ var AbstractMergeDateRangeRefiner = class extends MergingRefiner {
23042
+ shouldMergeResults(textBetween, currentResult, nextResult) {
23043
+ return !currentResult.end && !nextResult.end && textBetween.match(this.patternBetween()) != null;
23044
+ }
23045
+ mergeResults(textBetween, fromResult, toResult) {
23046
+ if (!fromResult.start.isOnlyWeekdayComponent() && !toResult.start.isOnlyWeekdayComponent()) {
23047
+ toResult.start.getCertainComponents().forEach((key) => {
23048
+ if (!fromResult.start.isCertain(key)) {
23049
+ fromResult.start.imply(key, toResult.start.get(key));
23050
+ }
23051
+ });
23052
+ fromResult.start.getCertainComponents().forEach((key) => {
23053
+ if (!toResult.start.isCertain(key)) {
23054
+ toResult.start.imply(key, fromResult.start.get(key));
23055
+ }
23056
+ });
23057
+ }
23058
+ if (fromResult.start.date() > toResult.start.date()) {
23059
+ let fromDate = fromResult.start.date();
23060
+ let toDate = toResult.start.date();
23061
+ if (toResult.start.isOnlyWeekdayComponent() && addDuration(toDate, { day: 7 }) > fromDate) {
23062
+ toDate = addDuration(toDate, { day: 7 });
23063
+ toResult.start.imply("day", toDate.getDate());
23064
+ toResult.start.imply("month", toDate.getMonth() + 1);
23065
+ toResult.start.imply("year", toDate.getFullYear());
23066
+ } else if (fromResult.start.isOnlyWeekdayComponent() && addDuration(fromDate, { day: -7 }) < toDate) {
23067
+ fromDate = addDuration(fromDate, { day: -7 });
23068
+ fromResult.start.imply("day", fromDate.getDate());
23069
+ fromResult.start.imply("month", fromDate.getMonth() + 1);
23070
+ fromResult.start.imply("year", fromDate.getFullYear());
23071
+ } else if (toResult.start.isDateWithUnknownYear() && addDuration(toDate, { year: 1 }) > fromDate) {
23072
+ toDate = addDuration(toDate, { year: 1 });
23073
+ toResult.start.imply("year", toDate.getFullYear());
23074
+ } else if (fromResult.start.isDateWithUnknownYear() && addDuration(fromDate, { year: -1 }) < toDate) {
23075
+ fromDate = addDuration(fromDate, { year: -1 });
23076
+ fromResult.start.imply("year", fromDate.getFullYear());
23077
+ } else {
23078
+ [toResult, fromResult] = [fromResult, toResult];
23079
+ }
23080
+ }
23081
+ const result = fromResult.clone();
23082
+ result.start = fromResult.start;
23083
+ result.end = toResult.start;
23084
+ result.index = Math.min(fromResult.index, toResult.index);
23085
+ if (fromResult.index < toResult.index) {
23086
+ result.text = fromResult.text + textBetween + toResult.text;
23087
+ } else {
23088
+ result.text = toResult.text + textBetween + fromResult.text;
23089
+ }
23090
+ return result;
23091
+ }
23092
+ };
23093
+
23094
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/refiners/ENMergeDateRangeRefiner.js
23095
+ var ENMergeDateRangeRefiner = class extends AbstractMergeDateRangeRefiner {
23096
+ patternBetween() {
23097
+ return /^\s*(to|-|–|until|through|till)\s*$/i;
23098
+ }
23099
+ };
23100
+
23101
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/calculation/mergingCalculation.js
23102
+ function mergeDateTimeResult(dateResult, timeResult) {
23103
+ const result = dateResult.clone();
23104
+ const beginDate = dateResult.start;
23105
+ const beginTime = timeResult.start;
23106
+ result.start = mergeDateTimeComponent(beginDate, beginTime);
23107
+ if (dateResult.end != null || timeResult.end != null) {
23108
+ const endDate = dateResult.end == null ? dateResult.start : dateResult.end;
23109
+ const endTime = timeResult.end == null ? timeResult.start : timeResult.end;
23110
+ const endDateTime = mergeDateTimeComponent(endDate, endTime);
23111
+ if (dateResult.end == null && endDateTime.date().getTime() < result.start.date().getTime()) {
23112
+ const nextDay = new Date(endDateTime.date().getTime());
23113
+ nextDay.setDate(nextDay.getDate() + 1);
23114
+ if (endDateTime.isCertain("day")) {
23115
+ assignSimilarDate(endDateTime, nextDay);
23116
+ } else {
23117
+ implySimilarDate(endDateTime, nextDay);
23118
+ }
23119
+ }
23120
+ result.end = endDateTime;
23121
+ }
23122
+ return result;
23123
+ }
23124
+ function mergeDateTimeComponent(dateComponent, timeComponent) {
23125
+ const dateTimeComponent = dateComponent.clone();
23126
+ if (timeComponent.isCertain("hour")) {
23127
+ dateTimeComponent.assign("hour", timeComponent.get("hour"));
23128
+ dateTimeComponent.assign("minute", timeComponent.get("minute"));
23129
+ if (timeComponent.isCertain("second")) {
23130
+ dateTimeComponent.assign("second", timeComponent.get("second"));
23131
+ if (timeComponent.isCertain("millisecond")) {
23132
+ dateTimeComponent.assign("millisecond", timeComponent.get("millisecond"));
23133
+ } else {
23134
+ dateTimeComponent.imply("millisecond", timeComponent.get("millisecond"));
23135
+ }
23136
+ } else {
23137
+ dateTimeComponent.imply("second", timeComponent.get("second"));
23138
+ dateTimeComponent.imply("millisecond", timeComponent.get("millisecond"));
23139
+ }
23140
+ } else {
23141
+ dateTimeComponent.imply("hour", timeComponent.get("hour"));
23142
+ dateTimeComponent.imply("minute", timeComponent.get("minute"));
23143
+ dateTimeComponent.imply("second", timeComponent.get("second"));
23144
+ dateTimeComponent.imply("millisecond", timeComponent.get("millisecond"));
23145
+ }
23146
+ if (timeComponent.isCertain("timezoneOffset")) {
23147
+ dateTimeComponent.assign("timezoneOffset", timeComponent.get("timezoneOffset"));
23148
+ }
23149
+ const dateHasMeaningfulMeridiem = dateComponent.get("meridiem") != null && (dateComponent.isCertain("meridiem") || Array.from(dateComponent.tags()).some((t) => t.startsWith("casualReference/")));
23150
+ if (timeComponent.isCertain("meridiem")) {
23151
+ dateTimeComponent.assign("meridiem", timeComponent.get("meridiem"));
23152
+ } else if (timeComponent.get("meridiem") != null && !dateHasMeaningfulMeridiem) {
23153
+ dateTimeComponent.imply("meridiem", timeComponent.get("meridiem"));
23154
+ }
23155
+ if (dateTimeComponent.get("meridiem") == Meridiem.PM && dateTimeComponent.get("hour") < 12) {
23156
+ if (timeComponent.isCertain("hour")) {
23157
+ dateTimeComponent.assign("hour", dateTimeComponent.get("hour") + 12);
23158
+ } else {
23159
+ dateTimeComponent.imply("hour", dateTimeComponent.get("hour") + 12);
23160
+ }
23161
+ }
23162
+ dateTimeComponent.addTags(dateComponent.tags());
23163
+ dateTimeComponent.addTags(timeComponent.tags());
23164
+ return dateTimeComponent;
23165
+ }
23166
+
23167
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/refiners/AbstractMergeDateTimeRefiner.js
23168
+ var AbstractMergeDateTimeRefiner = class extends MergingRefiner {
23169
+ shouldMergeResults(textBetween, currentResult, nextResult) {
23170
+ return (currentResult.start.isOnlyDate() && nextResult.start.isOnlyTime() || nextResult.start.isOnlyDate() && currentResult.start.isOnlyTime()) && textBetween.match(this.patternBetween()) != null;
23171
+ }
23172
+ mergeResults(textBetween, currentResult, nextResult) {
23173
+ const result = currentResult.start.isOnlyDate() ? mergeDateTimeResult(currentResult, nextResult) : mergeDateTimeResult(nextResult, currentResult);
23174
+ result.index = currentResult.index;
23175
+ result.text = currentResult.text + textBetween + nextResult.text;
23176
+ return result;
23177
+ }
23178
+ };
23179
+
23180
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/refiners/ENMergeDateTimeRefiner.js
23181
+ var ENMergeDateTimeRefiner = class extends AbstractMergeDateTimeRefiner {
23182
+ patternBetween() {
23183
+ return new RegExp("^\\s*(T|at|after|before|on|of|,|-|\\.|\u2219|:)?\\s*$");
23184
+ }
23185
+ };
23186
+
23187
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/refiners/ExtractTimezoneAbbrRefiner.js
23188
+ var TIMEZONE_NAME_PATTERN = new RegExp("^\\s*,?\\s*\\(?([A-Z]{2,4})\\)?(?=\\W|$)", "i");
23189
+ var ExtractTimezoneAbbrRefiner = class {
23190
+ timezoneOverrides;
23191
+ constructor(timezoneOverrides) {
23192
+ this.timezoneOverrides = timezoneOverrides;
23193
+ }
23194
+ refine(context, results) {
23195
+ const timezoneOverrides = context.option.timezones ?? {};
23196
+ results.forEach((result) => {
23197
+ const suffix = context.text.substring(result.index + result.text.length);
23198
+ const match = TIMEZONE_NAME_PATTERN.exec(suffix);
23199
+ if (!match) {
23200
+ return;
23201
+ }
23202
+ const timezoneAbbr = match[1].toUpperCase();
23203
+ const refDate = result.start.date() ?? result.refDate ?? /* @__PURE__ */ new Date();
23204
+ const tzOverrides = { ...this.timezoneOverrides, ...timezoneOverrides };
23205
+ const extractedTimezoneOffset = toTimezoneOffset(timezoneAbbr, refDate, tzOverrides);
23206
+ if (extractedTimezoneOffset == null) {
23207
+ return;
23208
+ }
23209
+ context.debug(() => {
23210
+ console.log(`Extracting timezone: '${timezoneAbbr}' into: ${extractedTimezoneOffset} for: ${result.start}`);
23211
+ });
23212
+ const currentTimezoneOffset = result.start.get("timezoneOffset");
23213
+ if (currentTimezoneOffset !== null && extractedTimezoneOffset != currentTimezoneOffset) {
23214
+ if (result.start.isCertain("timezoneOffset")) {
23215
+ return;
23216
+ }
23217
+ if (timezoneAbbr != match[1]) {
23218
+ return;
23219
+ }
23220
+ }
23221
+ if (result.start.isOnlyDate()) {
23222
+ if (timezoneAbbr != match[1]) {
23223
+ return;
23224
+ }
23225
+ }
23226
+ result.text += match[0];
23227
+ if (!result.start.isCertain("timezoneOffset")) {
23228
+ result.start.assign("timezoneOffset", extractedTimezoneOffset);
23229
+ }
23230
+ if (result.end != null && !result.end.isCertain("timezoneOffset")) {
23231
+ result.end.assign("timezoneOffset", extractedTimezoneOffset);
23232
+ }
23233
+ });
23234
+ return results;
23235
+ }
23236
+ };
23237
+
23238
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/refiners/ExtractTimezoneOffsetRefiner.js
23239
+ var TIMEZONE_OFFSET_PATTERN = new RegExp("^\\s*(?:\\(?(?:GMT|UTC)\\s?)?([+-])(\\d{1,2})(?::?(\\d{2}))?\\)?", "i");
23240
+ var TIMEZONE_OFFSET_SIGN_GROUP = 1;
23241
+ var TIMEZONE_OFFSET_HOUR_OFFSET_GROUP = 2;
23242
+ var TIMEZONE_OFFSET_MINUTE_OFFSET_GROUP = 3;
23243
+ var ExtractTimezoneOffsetRefiner = class {
23244
+ refine(context, results) {
23245
+ results.forEach(function(result) {
23246
+ if (result.start.isCertain("timezoneOffset")) {
23247
+ return;
23248
+ }
23249
+ const suffix = context.text.substring(result.index + result.text.length);
23250
+ const match = TIMEZONE_OFFSET_PATTERN.exec(suffix);
23251
+ if (!match) {
23252
+ return;
23253
+ }
23254
+ context.debug(() => {
23255
+ console.log(`Extracting timezone: '${match[0]}' into : ${result}`);
23256
+ });
23257
+ const hourOffset = parseInt(match[TIMEZONE_OFFSET_HOUR_OFFSET_GROUP]);
23258
+ const minuteOffset = parseInt(match[TIMEZONE_OFFSET_MINUTE_OFFSET_GROUP] || "0");
23259
+ let timezoneOffset = hourOffset * 60 + minuteOffset;
23260
+ if (timezoneOffset > 14 * 60) {
23261
+ return;
23262
+ }
23263
+ if (match[TIMEZONE_OFFSET_SIGN_GROUP] === "-") {
23264
+ timezoneOffset = -timezoneOffset;
23265
+ }
23266
+ if (result.end != null) {
23267
+ result.end.assign("timezoneOffset", timezoneOffset);
23268
+ }
23269
+ result.start.assign("timezoneOffset", timezoneOffset);
23270
+ result.text += match[0];
23271
+ });
23272
+ return results;
23273
+ }
23274
+ };
23275
+
23276
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/refiners/OverlapRemovalRefiner.js
23277
+ var OverlapRemovalRefiner = class {
23278
+ refine(context, results) {
23279
+ if (results.length < 2) {
23280
+ return results;
23281
+ }
23282
+ const filteredResults = [];
23283
+ let prevResult = results[0];
23284
+ for (let i = 1; i < results.length; i++) {
23285
+ const result = results[i];
23286
+ if (result.index >= prevResult.index + prevResult.text.length) {
23287
+ filteredResults.push(prevResult);
23288
+ prevResult = result;
23289
+ continue;
23290
+ }
23291
+ let kept = null;
23292
+ let removed = null;
23293
+ if (result.text.length > prevResult.text.length) {
23294
+ kept = result;
23295
+ removed = prevResult;
23296
+ } else {
23297
+ kept = prevResult;
23298
+ removed = result;
23299
+ }
23300
+ context.debug(() => {
23301
+ console.log(`${this.constructor.name} remove ${removed} by ${kept}`);
23302
+ });
23303
+ prevResult = kept;
23304
+ }
23305
+ if (prevResult != null) {
23306
+ filteredResults.push(prevResult);
23307
+ }
23308
+ return filteredResults;
23309
+ }
23310
+ };
23311
+
23312
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/calculation/weekdays.js
23313
+ function createParsingComponentsAtWeekday(reference, weekday, modifier) {
23314
+ const refDate = reference.getDateWithAdjustedTimezone();
23315
+ const daysToWeekday = getDaysToWeekday(refDate, weekday, modifier);
23316
+ let components = new ParsingComponents(reference);
23317
+ components = components.addDurationAsImplied({ day: daysToWeekday });
23318
+ components.assign("weekday", weekday);
23319
+ return components;
23320
+ }
23321
+ function getDaysToWeekday(refDate, weekday, modifier) {
23322
+ const refWeekday = refDate.getDay();
23323
+ switch (modifier) {
23324
+ case "this":
23325
+ return getDaysForwardToWeekday(refDate, weekday);
23326
+ case "last":
23327
+ return getBackwardDaysToWeekday(refDate, weekday);
23328
+ case "next":
23329
+ if (refWeekday == Weekday.SUNDAY) {
23330
+ return weekday == Weekday.SUNDAY ? 7 : weekday;
23331
+ }
23332
+ if (refWeekday == Weekday.SATURDAY) {
23333
+ if (weekday == Weekday.SATURDAY)
23334
+ return 7;
23335
+ if (weekday == Weekday.SUNDAY)
23336
+ return 8;
23337
+ return 1 + weekday;
23338
+ }
23339
+ if (weekday < refWeekday && weekday != Weekday.SUNDAY) {
23340
+ return getDaysForwardToWeekday(refDate, weekday);
23341
+ } else {
23342
+ return getDaysForwardToWeekday(refDate, weekday) + 7;
23343
+ }
23344
+ }
23345
+ return getDaysToWeekdayClosest(refDate, weekday);
23346
+ }
23347
+ function getDaysToWeekdayClosest(refDate, weekday) {
23348
+ const backward = getBackwardDaysToWeekday(refDate, weekday);
23349
+ const forward = getDaysForwardToWeekday(refDate, weekday);
23350
+ return forward < -backward ? forward : backward;
23351
+ }
23352
+ function getDaysForwardToWeekday(refDate, weekday) {
23353
+ const refWeekday = refDate.getDay();
23354
+ let forwardCount = weekday - refWeekday;
23355
+ if (forwardCount < 0) {
23356
+ forwardCount += 7;
23357
+ }
23358
+ return forwardCount;
23359
+ }
23360
+ function getBackwardDaysToWeekday(refDate, weekday) {
23361
+ const refWeekday = refDate.getDay();
23362
+ let backwardCount = weekday - refWeekday;
23363
+ if (backwardCount >= 0) {
23364
+ backwardCount -= 7;
23365
+ }
23366
+ return backwardCount;
23367
+ }
23368
+
23369
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/refiners/ForwardDateRefiner.js
23370
+ var ForwardDateRefiner = class {
23371
+ refine(context, results) {
23372
+ if (!context.option.forwardDate) {
23373
+ return results;
23374
+ }
23375
+ results.forEach((result) => {
23376
+ let refDate = context.reference.getDateWithAdjustedTimezone();
23377
+ if (result.start.isOnlyTime() && context.reference.instant > result.start.date()) {
23378
+ const refDate2 = context.reference.getDateWithAdjustedTimezone();
23379
+ const refFollowingDay = new Date(refDate2);
23380
+ refFollowingDay.setDate(refFollowingDay.getDate() + 1);
23381
+ implySimilarDate(result.start, refFollowingDay);
23382
+ context.debug(() => {
23383
+ console.log(`${this.constructor.name} adjusted ${result} time from the ref date (${refDate2}) to the following day (${refFollowingDay})`);
23384
+ });
23385
+ if (result.end && result.end.isOnlyTime()) {
23386
+ implySimilarDate(result.end, refFollowingDay);
23387
+ if (result.start.date() > result.end.date()) {
23388
+ refFollowingDay.setDate(refFollowingDay.getDate() + 1);
23389
+ implySimilarDate(result.end, refFollowingDay);
23390
+ }
23391
+ }
23392
+ }
23393
+ if (result.start.isOnlyWeekdayComponent() && refDate > result.start.date()) {
23394
+ let daysToAdd = getDaysForwardToWeekday(refDate, result.start.get("weekday")) || 7;
23395
+ const forwardedWeekday = addDuration(refDate, { day: daysToAdd });
23396
+ implySimilarDate(result.start, forwardedWeekday);
23397
+ context.debug(() => {
23398
+ console.log(`${this.constructor.name} adjusted ${result} weekday (${result.start})`);
23399
+ });
23400
+ if (result.end && result.start.date() > result.end.date()) {
23401
+ let daysToAdd2 = getDaysForwardToWeekday(refDate, result.start.get("weekday")) || 7;
23402
+ const forwardedWeekday2 = addDuration(refDate, { day: daysToAdd2 });
23403
+ implySimilarDate(result.end, forwardedWeekday2);
23404
+ context.debug(() => {
23405
+ console.log(`${this.constructor.name} adjusted ${result} weekday (${result.end})`);
23406
+ });
23407
+ }
23408
+ }
23409
+ if (result.start.isDateWithUnknownYear() && refDate > result.start.date()) {
23410
+ for (let i = 0; i < 3 && refDate > result.start.date(); i++) {
23411
+ result.start.imply("year", result.start.get("year") + 1);
23412
+ context.debug(() => {
23413
+ console.log(`${this.constructor.name} adjusted ${result} year (${result.start})`);
23414
+ });
23415
+ if (result.end && !result.end.isCertain("year")) {
23416
+ result.end.imply("year", result.end.get("year") + 1);
23417
+ context.debug(() => {
23418
+ console.log(`${this.constructor.name} adjusted ${result} month (${result.start})`);
23419
+ });
23420
+ }
23421
+ }
23422
+ }
23423
+ });
23424
+ return results;
23425
+ }
23426
+ };
23427
+
23428
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/refiners/UnlikelyFormatFilter.js
23429
+ var UnlikelyFormatFilter = class extends Filter {
23430
+ strictMode;
23431
+ constructor(strictMode) {
23432
+ super();
23433
+ this.strictMode = strictMode;
23434
+ }
23435
+ isValid(context, result) {
23436
+ if (result.text.replace(" ", "").match(/^\d*(\.\d*)?$/)) {
23437
+ context.debug(() => {
23438
+ console.log(`Removing unlikely result '${result.text}'`);
23439
+ });
23440
+ return false;
23441
+ }
23442
+ if (!result.start.isValidDate()) {
23443
+ context.debug(() => {
23444
+ console.log(`Removing invalid result: ${result} (${result.start})`);
23445
+ });
23446
+ return false;
23447
+ }
23448
+ if (result.end && !result.end.isValidDate()) {
23449
+ context.debug(() => {
23450
+ console.log(`Removing invalid result: ${result} (${result.end})`);
23451
+ });
23452
+ return false;
23453
+ }
23454
+ if (this.strictMode) {
23455
+ return this.isStrictModeValid(context, result);
23456
+ }
23457
+ return true;
23458
+ }
23459
+ isStrictModeValid(context, result) {
23460
+ if (result.start.isOnlyWeekdayComponent()) {
23461
+ context.debug(() => {
23462
+ console.log(`(Strict) Removing weekday only component: ${result} (${result.end})`);
23463
+ });
23464
+ return false;
23465
+ }
23466
+ return true;
23467
+ }
23468
+ };
23469
+
23470
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/parsers/ISOFormatParser.js
23471
+ var PATTERN9 = new RegExp("([0-9]{4})\\-([0-9]{1,2})\\-([0-9]{1,2})(?:T([0-9]{1,2}):([0-9]{1,2})(?::([0-9]{1,2})(?:\\.(\\d{1,4}))?)?(Z|([+-]\\d{2}):?(\\d{2})?)?)?(?=\\W|$)", "i");
23472
+ var YEAR_NUMBER_GROUP2 = 1;
23473
+ var MONTH_NUMBER_GROUP2 = 2;
23474
+ var DATE_NUMBER_GROUP2 = 3;
23475
+ var HOUR_NUMBER_GROUP = 4;
23476
+ var MINUTE_NUMBER_GROUP = 5;
23477
+ var SECOND_NUMBER_GROUP = 6;
23478
+ var MILLISECOND_NUMBER_GROUP = 7;
23479
+ var TZD_GROUP = 8;
23480
+ var TZD_HOUR_OFFSET_GROUP = 9;
23481
+ var TZD_MINUTE_OFFSET_GROUP = 10;
23482
+ var ISOFormatParser = class extends AbstractParserWithWordBoundaryChecking {
23483
+ innerPattern() {
23484
+ return PATTERN9;
23485
+ }
23486
+ innerExtract(context, match) {
23487
+ const components = context.createParsingComponents({
23488
+ "year": parseInt(match[YEAR_NUMBER_GROUP2]),
23489
+ "month": parseInt(match[MONTH_NUMBER_GROUP2]),
23490
+ "day": parseInt(match[DATE_NUMBER_GROUP2])
23491
+ });
23492
+ if (match[HOUR_NUMBER_GROUP] != null) {
23493
+ components.assign("hour", parseInt(match[HOUR_NUMBER_GROUP]));
23494
+ components.assign("minute", parseInt(match[MINUTE_NUMBER_GROUP]));
23495
+ if (match[SECOND_NUMBER_GROUP] != null) {
23496
+ components.assign("second", parseInt(match[SECOND_NUMBER_GROUP]));
23497
+ }
23498
+ if (match[MILLISECOND_NUMBER_GROUP] != null) {
23499
+ components.assign("millisecond", parseInt(match[MILLISECOND_NUMBER_GROUP]));
23500
+ }
23501
+ if (match[TZD_GROUP] != null) {
23502
+ let offset = 0;
23503
+ if (match[TZD_HOUR_OFFSET_GROUP]) {
23504
+ const hourOffset = parseInt(match[TZD_HOUR_OFFSET_GROUP]);
23505
+ let minuteOffset = 0;
23506
+ if (match[TZD_MINUTE_OFFSET_GROUP] != null) {
23507
+ minuteOffset = parseInt(match[TZD_MINUTE_OFFSET_GROUP]);
23508
+ }
23509
+ offset = hourOffset * 60;
23510
+ if (offset < 0) {
23511
+ offset -= minuteOffset;
23512
+ } else {
23513
+ offset += minuteOffset;
23514
+ }
23515
+ }
23516
+ components.assign("timezoneOffset", offset);
23517
+ }
23518
+ }
23519
+ return components.addTag("parser/ISOFormatParser");
23520
+ }
23521
+ };
23522
+
23523
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/refiners/MergeWeekdayComponentRefiner.js
23524
+ var MergeWeekdayComponentRefiner = class extends MergingRefiner {
23525
+ mergeResults(textBetween, currentResult, nextResult) {
23526
+ const newResult = nextResult.clone();
23527
+ newResult.index = currentResult.index;
23528
+ newResult.text = currentResult.text + textBetween + newResult.text;
23529
+ newResult.start.assign("weekday", currentResult.start.get("weekday"));
23530
+ if (newResult.end) {
23531
+ newResult.end.assign("weekday", currentResult.start.get("weekday"));
23532
+ }
23533
+ return newResult;
23534
+ }
23535
+ shouldMergeResults(textBetween, currentResult, nextResult) {
23536
+ const weekdayThenNormalDate = currentResult.start.isOnlyWeekdayComponent() && !currentResult.start.isCertain("hour") && nextResult.start.isCertain("day");
23537
+ return weekdayThenNormalDate && textBetween.match(/^,?\s*$/) != null;
23538
+ }
23539
+ };
23540
+
23541
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/configurations.js
23542
+ function includeCommonConfiguration(configuration2, strictMode = false) {
23543
+ configuration2.parsers.unshift(new ISOFormatParser());
23544
+ configuration2.refiners.unshift(new MergeWeekdayComponentRefiner());
23545
+ configuration2.refiners.unshift(new ExtractTimezoneOffsetRefiner());
23546
+ configuration2.refiners.unshift(new OverlapRemovalRefiner());
23547
+ configuration2.refiners.push(new ExtractTimezoneAbbrRefiner());
23548
+ configuration2.refiners.push(new OverlapRemovalRefiner());
23549
+ configuration2.refiners.push(new ForwardDateRefiner());
23550
+ configuration2.refiners.push(new UnlikelyFormatFilter(strictMode));
23551
+ return configuration2;
23552
+ }
23553
+
23554
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/casualReferences.js
23555
+ function now(reference) {
23556
+ const targetDate = reference.getDateWithAdjustedTimezone();
23557
+ const component = new ParsingComponents(reference, {});
23558
+ assignSimilarDate(component, targetDate);
23559
+ assignSimilarTime(component, targetDate);
23560
+ component.assign("timezoneOffset", reference.getTimezoneOffset());
23561
+ component.addTag("casualReference/now");
23562
+ return component;
23563
+ }
23564
+ function today(reference) {
23565
+ const targetDate = reference.getDateWithAdjustedTimezone();
23566
+ const component = new ParsingComponents(reference, {});
23567
+ assignSimilarDate(component, targetDate);
23568
+ implySimilarTime(component, targetDate);
23569
+ component.delete("meridiem");
23570
+ component.addTag("casualReference/today");
23571
+ return component;
23572
+ }
23573
+ function yesterday(reference) {
23574
+ return theDayBefore(reference, 1).addTag("casualReference/yesterday");
23575
+ }
23576
+ function tomorrow(reference) {
23577
+ return theDayAfter(reference, 1).addTag("casualReference/tomorrow");
23578
+ }
23579
+ function theDayBefore(reference, numDay) {
23580
+ return theDayAfter(reference, -numDay);
23581
+ }
23582
+ function theDayAfter(reference, nDays) {
23583
+ const targetDate = reference.getDateWithAdjustedTimezone();
23584
+ const component = new ParsingComponents(reference, {});
23585
+ const newDate = new Date(targetDate.getTime());
23586
+ newDate.setDate(newDate.getDate() + nDays);
23587
+ assignSimilarDate(component, newDate);
23588
+ implySimilarTime(component, newDate);
23589
+ component.delete("meridiem");
23590
+ return component;
23591
+ }
23592
+ function tonight(reference, implyHour = 22) {
23593
+ const targetDate = reference.getDateWithAdjustedTimezone();
23594
+ const component = new ParsingComponents(reference, {});
23595
+ assignSimilarDate(component, targetDate);
23596
+ component.imply("hour", implyHour);
23597
+ component.imply("meridiem", Meridiem.PM);
23598
+ component.addTag("casualReference/tonight");
23599
+ return component;
23600
+ }
23601
+ function evening(reference, implyHour = 20) {
23602
+ const component = new ParsingComponents(reference, {});
23603
+ component.imply("meridiem", Meridiem.PM);
23604
+ component.imply("hour", implyHour);
23605
+ component.addTag("casualReference/evening");
23606
+ return component;
23607
+ }
23608
+ function midnight(reference) {
23609
+ const component = new ParsingComponents(reference, {});
23610
+ if (reference.getDateWithAdjustedTimezone().getHours() > 2) {
23611
+ component.addDurationAsImplied({ day: 1 });
23612
+ }
23613
+ component.assign("hour", 0);
23614
+ component.imply("minute", 0);
23615
+ component.imply("second", 0);
23616
+ component.imply("millisecond", 0);
23617
+ component.addTag("casualReference/midnight");
23618
+ return component;
23619
+ }
23620
+ function morning(reference, implyHour = 6) {
23621
+ const component = new ParsingComponents(reference, {});
23622
+ component.imply("meridiem", Meridiem.AM);
23623
+ component.imply("hour", implyHour);
23624
+ component.imply("minute", 0);
23625
+ component.imply("second", 0);
23626
+ component.imply("millisecond", 0);
23627
+ component.addTag("casualReference/morning");
23628
+ return component;
23629
+ }
23630
+ function afternoon(reference, implyHour = 15) {
23631
+ const component = new ParsingComponents(reference, {});
23632
+ component.imply("meridiem", Meridiem.PM);
23633
+ component.imply("hour", implyHour);
23634
+ component.imply("minute", 0);
23635
+ component.imply("second", 0);
23636
+ component.imply("millisecond", 0);
23637
+ component.addTag("casualReference/afternoon");
23638
+ return component;
23639
+ }
23640
+ function noon(reference) {
23641
+ const component = new ParsingComponents(reference, {});
23642
+ component.imply("meridiem", Meridiem.AM);
23643
+ component.assign("hour", 12);
23644
+ component.imply("minute", 0);
23645
+ component.imply("second", 0);
23646
+ component.imply("millisecond", 0);
23647
+ component.addTag("casualReference/noon");
23648
+ return component;
23649
+ }
23650
+
23651
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENCasualDateParser.js
23652
+ var PATTERN10 = /(now|today|tonight|tomorrow|overmorrow|tmr|tmrw|yesterday|last\s*night)(?=\W|$)/i;
23653
+ var ENCasualDateParser = class extends AbstractParserWithWordBoundaryChecking {
23654
+ innerPattern(context) {
23655
+ return PATTERN10;
23656
+ }
23657
+ innerExtract(context, match) {
23658
+ let targetDate = context.refDate;
23659
+ const lowerText = match[0].toLowerCase();
23660
+ let component = context.createParsingComponents();
23661
+ switch (lowerText) {
23662
+ case "now":
23663
+ component = now(context.reference);
23664
+ break;
23665
+ case "today":
23666
+ component = today(context.reference);
23667
+ break;
23668
+ case "yesterday":
23669
+ component = yesterday(context.reference);
23670
+ break;
23671
+ case "tomorrow":
23672
+ case "tmr":
23673
+ case "tmrw":
23674
+ component = tomorrow(context.reference);
23675
+ break;
23676
+ case "tonight":
23677
+ component = tonight(context.reference);
23678
+ break;
23679
+ case "overmorrow":
23680
+ component = theDayAfter(context.reference, 2);
23681
+ break;
23682
+ default:
23683
+ if (lowerText.match(/last\s*night/)) {
23684
+ if (targetDate.getHours() > 6) {
23685
+ const previousDay = new Date(targetDate.getTime());
23686
+ previousDay.setDate(previousDay.getDate() - 1);
23687
+ targetDate = previousDay;
23688
+ }
23689
+ assignSimilarDate(component, targetDate);
23690
+ component.imply("hour", 0);
23691
+ }
23692
+ break;
23693
+ }
23694
+ component.addTag("parser/ENCasualDateParser");
23695
+ return component;
23696
+ }
23697
+ };
23698
+
23699
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENCasualTimeParser.js
23700
+ var PATTERN11 = /(?:this)?\s{0,3}(morning|afternoon|evening|night|midnight|midday|noon)(?=\W|$)/i;
23701
+ var ENCasualTimeParser = class extends AbstractParserWithWordBoundaryChecking {
23702
+ innerPattern() {
23703
+ return PATTERN11;
23704
+ }
23705
+ innerExtract(context, match) {
23706
+ let component = null;
23707
+ switch (match[1].toLowerCase()) {
23708
+ case "afternoon":
23709
+ component = afternoon(context.reference);
23710
+ break;
23711
+ case "evening":
23712
+ case "night":
23713
+ component = evening(context.reference);
23714
+ break;
23715
+ case "midnight":
23716
+ component = midnight(context.reference);
23717
+ break;
23718
+ case "morning":
23719
+ component = morning(context.reference);
23720
+ break;
23721
+ case "noon":
23722
+ case "midday":
23723
+ component = noon(context.reference);
23724
+ break;
23725
+ }
23726
+ if (component) {
23727
+ component.addTag("parser/ENCasualTimeParser");
23728
+ }
23729
+ return component;
23730
+ }
23731
+ };
23732
+
23733
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENWeekdayParser.js
23734
+ var PATTERN12 = new RegExp(`(?:(?:\\,|\\(|\\\uFF08)\\s*)?(?:on\\s*?)?(?:(this|last|past|next)\\s*)?(${matchAnyPattern(WEEKDAY_DICTIONARY)}|weekend|weekday)(?:\\s*(?:\\,|\\)|\\\uFF09))?(?:\\s*(?:of\\s*)?(this|last|past|next)\\s*week)?(?=\\W|$)`, "i");
23735
+ var PREFIX_GROUP2 = 1;
23736
+ var WEEKDAY_GROUP = 2;
23737
+ var POSTFIX_GROUP = 3;
23738
+ var ENWeekdayParser = class extends AbstractParserWithWordBoundaryChecking {
23739
+ innerPattern() {
23740
+ return PATTERN12;
23741
+ }
23742
+ innerExtract(context, match) {
23743
+ const prefix = match[PREFIX_GROUP2];
23744
+ const postfix = match[POSTFIX_GROUP];
23745
+ let modifierWord = prefix || postfix;
23746
+ modifierWord = modifierWord || "";
23747
+ modifierWord = modifierWord.toLowerCase();
23748
+ let modifier = null;
23749
+ if (modifierWord == "last" || modifierWord == "past") {
23750
+ modifier = "last";
23751
+ } else if (modifierWord == "next") {
23752
+ modifier = "next";
23753
+ } else if (modifierWord == "this") {
23754
+ modifier = "this";
23755
+ }
23756
+ const weekday_word = match[WEEKDAY_GROUP].toLowerCase();
23757
+ let weekday;
23758
+ if (WEEKDAY_DICTIONARY[weekday_word] !== void 0) {
23759
+ weekday = WEEKDAY_DICTIONARY[weekday_word];
23760
+ } else if (weekday_word == "weekend") {
23761
+ weekday = modifier == "last" ? Weekday.SUNDAY : Weekday.SATURDAY;
23762
+ } else if (weekday_word == "weekday") {
23763
+ const refWeekday = context.reference.getDateWithAdjustedTimezone().getDay();
23764
+ if (refWeekday == Weekday.SUNDAY || refWeekday == Weekday.SATURDAY) {
23765
+ weekday = modifier == "last" ? Weekday.FRIDAY : Weekday.MONDAY;
23766
+ } else {
23767
+ weekday = refWeekday - 1;
23768
+ weekday = modifier == "last" ? weekday - 1 : weekday + 1;
23769
+ weekday = weekday % 5 + 1;
23770
+ }
23771
+ } else {
23772
+ return null;
23773
+ }
23774
+ return createParsingComponentsAtWeekday(context.reference, weekday, modifier);
23775
+ }
23776
+ };
23777
+
23778
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENRelativeDateFormatParser.js
23779
+ var PATTERN13 = new RegExp(`(this|last|past|next|after\\s*this)\\s*(${matchAnyPattern(TIME_UNIT_DICTIONARY)})(?=\\s*)(?=\\W|$)`, "i");
23780
+ var MODIFIER_WORD_GROUP = 1;
23781
+ var RELATIVE_WORD_GROUP = 2;
23782
+ var ENRelativeDateFormatParser = class extends AbstractParserWithWordBoundaryChecking {
23783
+ innerPattern() {
23784
+ return PATTERN13;
23785
+ }
23786
+ innerExtract(context, match) {
23787
+ const modifier = match[MODIFIER_WORD_GROUP].toLowerCase();
23788
+ const unitWord = match[RELATIVE_WORD_GROUP].toLowerCase();
23789
+ const timeunit = TIME_UNIT_DICTIONARY[unitWord];
23790
+ if (modifier == "next" || modifier.startsWith("after")) {
23791
+ const timeUnits = {};
23792
+ timeUnits[timeunit] = 1;
23793
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
23794
+ }
23795
+ if (modifier == "last" || modifier == "past") {
23796
+ const timeUnits = {};
23797
+ timeUnits[timeunit] = -1;
23798
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
23799
+ }
23800
+ const components = context.createParsingComponents();
23801
+ let date3 = new Date(context.reference.instant.getTime());
23802
+ if (unitWord.match(/week/i)) {
23803
+ date3.setDate(date3.getDate() - date3.getDay());
23804
+ components.imply("day", date3.getDate());
23805
+ components.imply("month", date3.getMonth() + 1);
23806
+ components.imply("year", date3.getFullYear());
23807
+ } else if (unitWord.match(/month/i)) {
23808
+ date3.setDate(1);
23809
+ components.imply("day", date3.getDate());
23810
+ components.assign("year", date3.getFullYear());
23811
+ components.assign("month", date3.getMonth() + 1);
23812
+ } else if (unitWord.match(/year/i)) {
23813
+ date3.setDate(1);
23814
+ date3.setMonth(0);
23815
+ components.imply("day", date3.getDate());
23816
+ components.imply("month", date3.getMonth() + 1);
23817
+ components.assign("year", date3.getFullYear());
23818
+ }
23819
+ return components;
23820
+ }
23821
+ };
23822
+
23823
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/common/parsers/SlashDateFormatParser.js
23824
+ var PATTERN14 = new RegExp("([^\\d]|^)([0-3]{0,1}[0-9]{1})[\\/\\.\\-]([0-3]{0,1}[0-9]{1})(?:[\\/\\.\\-]([0-9]{4}|[0-9]{2}))?(\\W|$)", "i");
23825
+ var OPENING_GROUP = 1;
23826
+ var ENDING_GROUP = 5;
23827
+ var FIRST_NUMBERS_GROUP = 2;
23828
+ var SECOND_NUMBERS_GROUP = 3;
23829
+ var YEAR_GROUP6 = 4;
23830
+ var SlashDateFormatParser = class {
23831
+ groupNumberMonth;
23832
+ groupNumberDay;
23833
+ constructor(littleEndian) {
23834
+ this.groupNumberMonth = littleEndian ? SECOND_NUMBERS_GROUP : FIRST_NUMBERS_GROUP;
23835
+ this.groupNumberDay = littleEndian ? FIRST_NUMBERS_GROUP : SECOND_NUMBERS_GROUP;
23836
+ }
23837
+ pattern() {
23838
+ return PATTERN14;
23839
+ }
23840
+ extract(context, match) {
23841
+ const index = match.index + match[OPENING_GROUP].length;
23842
+ const indexEnd = match.index + match[0].length - match[ENDING_GROUP].length;
23843
+ if (index > 0) {
23844
+ const textBefore = context.text.substring(0, index);
23845
+ if (textBefore.match("\\d/?$")) {
23846
+ return;
23847
+ }
23848
+ }
23849
+ if (indexEnd < context.text.length) {
23850
+ const textAfter = context.text.substring(indexEnd);
23851
+ if (textAfter.match("^/?\\d")) {
23852
+ return;
23853
+ }
23854
+ }
23855
+ const text2 = context.text.substring(index, indexEnd);
23856
+ if (text2.match(/^\d\.\d$/) || text2.match(/^\d\.\d{1,2}\.\d{1,2}\s*$/)) {
23857
+ return;
23858
+ }
23859
+ if (!match[YEAR_GROUP6] && text2.indexOf("/") < 0) {
23860
+ return;
23861
+ }
23862
+ const result = context.createParsingResult(index, text2);
23863
+ let month = parseInt(match[this.groupNumberMonth]);
23864
+ let day = parseInt(match[this.groupNumberDay]);
23865
+ if (month < 1 || month > 12) {
23866
+ if (month > 12) {
23867
+ if (day >= 1 && day <= 12 && month <= 31) {
23868
+ [day, month] = [month, day];
23869
+ } else {
23870
+ return null;
23871
+ }
23872
+ }
23873
+ }
23874
+ if (day < 1 || day > 31) {
23875
+ return null;
23876
+ }
23877
+ result.start.assign("day", day);
23878
+ result.start.assign("month", month);
23879
+ if (match[YEAR_GROUP6]) {
23880
+ const rawYearNumber = parseInt(match[YEAR_GROUP6]);
23881
+ const year = findMostLikelyADYear(rawYearNumber);
23882
+ result.start.assign("year", year);
23883
+ } else {
23884
+ const year = findYearClosestToRef(context.refDate, day, month);
23885
+ result.start.imply("year", year);
23886
+ }
23887
+ return result.addTag("parser/SlashDateFormatParser");
23888
+ }
23889
+ };
23890
+
23891
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.js
23892
+ var PATTERN15 = new RegExp(`(this|last|past|next|after|\\+|-)\\s*(${TIME_UNITS_PATTERN})(?=\\W|$)`, "i");
23893
+ var PATTERN_NO_ABBR = new RegExp(`(this|last|past|next|after|\\+|-)\\s*(${TIME_UNITS_NO_ABBR_PATTERN})(?=\\W|$)`, "i");
23894
+ var ENTimeUnitCasualRelativeFormatParser = class extends AbstractParserWithWordBoundaryChecking {
23895
+ allowAbbreviations;
23896
+ constructor(allowAbbreviations = true) {
23897
+ super();
23898
+ this.allowAbbreviations = allowAbbreviations;
23899
+ }
23900
+ innerPattern() {
23901
+ return this.allowAbbreviations ? PATTERN15 : PATTERN_NO_ABBR;
23902
+ }
23903
+ innerExtract(context, match) {
23904
+ const prefix = match[1].toLowerCase();
23905
+ let duration3 = parseDuration(match[2]);
23906
+ if (!duration3) {
23907
+ return null;
23908
+ }
23909
+ switch (prefix) {
23910
+ case "last":
23911
+ case "past":
23912
+ case "-":
23913
+ duration3 = reverseDuration(duration3);
23914
+ break;
23915
+ }
23916
+ return ParsingComponents.createRelativeFromReference(context.reference, duration3);
23917
+ }
23918
+ };
23919
+
23920
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/refiners/ENMergeRelativeAfterDateRefiner.js
23921
+ function IsPositiveFollowingReference(result) {
23922
+ return result.text.match(/^[+-]/i) != null;
23923
+ }
23924
+ function IsNegativeFollowingReference(result) {
23925
+ return result.text.match(/^-/i) != null;
23926
+ }
23927
+ var ENMergeRelativeAfterDateRefiner = class extends MergingRefiner {
23928
+ shouldMergeResults(textBetween, currentResult, nextResult) {
23929
+ if (!textBetween.match(/^\s*$/i)) {
23930
+ return false;
23931
+ }
23932
+ return IsPositiveFollowingReference(nextResult) || IsNegativeFollowingReference(nextResult);
23933
+ }
23934
+ mergeResults(textBetween, currentResult, nextResult, context) {
23935
+ let timeUnits = parseDuration(nextResult.text);
23936
+ if (IsNegativeFollowingReference(nextResult)) {
23937
+ timeUnits = reverseDuration(timeUnits);
23938
+ }
23939
+ const components = ParsingComponents.createRelativeFromReference(ReferenceWithTimezone.fromDate(currentResult.start.date()), timeUnits);
23940
+ return new ParsingResult(currentResult.reference, currentResult.index, `${currentResult.text}${textBetween}${nextResult.text}`, components);
23941
+ }
23942
+ };
23943
+
23944
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/refiners/ENMergeRelativeFollowByDateRefiner.js
23945
+ function hasImpliedEarlierReferenceDate(result) {
23946
+ return result.text.match(/\s+(before|from)$/i) != null;
23947
+ }
23948
+ function hasImpliedLaterReferenceDate(result) {
23949
+ return result.text.match(/\s+(after|since)$/i) != null;
23950
+ }
23951
+ var ENMergeRelativeFollowByDateRefiner = class extends MergingRefiner {
23952
+ patternBetween() {
23953
+ return /^\s*$/i;
23954
+ }
23955
+ shouldMergeResults(textBetween, currentResult, nextResult) {
23956
+ if (!textBetween.match(this.patternBetween())) {
23957
+ return false;
23958
+ }
23959
+ if (!hasImpliedEarlierReferenceDate(currentResult) && !hasImpliedLaterReferenceDate(currentResult)) {
23960
+ return false;
23961
+ }
23962
+ return !!nextResult.start.get("day") && !!nextResult.start.get("month") && !!nextResult.start.get("year");
23963
+ }
23964
+ mergeResults(textBetween, currentResult, nextResult) {
23965
+ let duration3 = parseDuration(currentResult.text);
23966
+ if (hasImpliedEarlierReferenceDate(currentResult)) {
23967
+ duration3 = reverseDuration(duration3);
23968
+ }
23969
+ const components = ParsingComponents.createRelativeFromReference(ReferenceWithTimezone.fromDate(nextResult.start.date()), duration3);
23970
+ return new ParsingResult(nextResult.reference, currentResult.index, `${currentResult.text}${textBetween}${nextResult.text}`, components);
23971
+ }
23972
+ };
23973
+
23974
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/refiners/ENExtractYearSuffixRefiner.js
23975
+ var YEAR_SUFFIX_PATTERN = new RegExp(`^\\s*(${YEAR_PATTERN})`, "i");
23976
+ var YEAR_GROUP7 = 1;
23977
+ var ENExtractYearSuffixRefiner = class {
23978
+ refine(context, results) {
23979
+ results.forEach(function(result) {
23980
+ if (!result.start.isDateWithUnknownYear()) {
23981
+ return;
23982
+ }
23983
+ const suffix = context.text.substring(result.index + result.text.length);
23984
+ const match = YEAR_SUFFIX_PATTERN.exec(suffix);
23985
+ if (!match) {
23986
+ return;
23987
+ }
23988
+ if (match[0].trim().length <= 3) {
23989
+ return;
23990
+ }
23991
+ context.debug(() => {
23992
+ console.log(`Extracting year: '${match[0]}' into : ${result}`);
23993
+ });
23994
+ const year = parseYear(match[YEAR_GROUP7]);
23995
+ if (result.end != null) {
23996
+ result.end.assign("year", year);
23997
+ }
23998
+ result.start.assign("year", year);
23999
+ result.text += match[0];
24000
+ });
24001
+ return results;
24002
+ }
24003
+ };
24004
+
24005
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/refiners/ENUnlikelyFormatFilter.js
24006
+ var ENUnlikelyFormatFilter = class extends Filter {
24007
+ constructor() {
24008
+ super();
24009
+ }
24010
+ isValid(context, result) {
24011
+ const text2 = result.text.trim();
24012
+ if (text2 === context.text.trim()) {
24013
+ return true;
24014
+ }
24015
+ if (text2.toLowerCase() === "may") {
24016
+ const textBefore = context.text.substring(0, result.index).trim();
24017
+ if (!textBefore.match(/\b(in)$/i)) {
24018
+ context.debug(() => {
24019
+ console.log(`Removing unlikely result: ${result}`);
24020
+ });
24021
+ return false;
24022
+ }
24023
+ }
24024
+ if (text2.toLowerCase().endsWith("the second")) {
24025
+ const textAfter = context.text.substring(result.index + result.text.length).trim();
24026
+ if (textAfter.length > 0) {
24027
+ context.debug(() => {
24028
+ console.log(`Removing unlikely result: ${result}`);
24029
+ });
24030
+ }
24031
+ return false;
24032
+ }
24033
+ return true;
24034
+ }
24035
+ };
24036
+
24037
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/configuration.js
24038
+ var ENDefaultConfiguration = class {
24039
+ createCasualConfiguration(littleEndian = false) {
24040
+ const option = this.createConfiguration(false, littleEndian);
24041
+ option.parsers.push(new ENCasualDateParser());
24042
+ option.parsers.push(new ENCasualTimeParser());
24043
+ option.parsers.push(new ENMonthNameParser());
24044
+ option.parsers.push(new ENRelativeDateFormatParser());
24045
+ option.parsers.push(new ENTimeUnitCasualRelativeFormatParser());
24046
+ option.refiners.push(new ENUnlikelyFormatFilter());
24047
+ return option;
24048
+ }
24049
+ createConfiguration(strictMode = true, littleEndian = false) {
24050
+ const options = includeCommonConfiguration({
24051
+ parsers: [
24052
+ new SlashDateFormatParser(littleEndian),
24053
+ new ENTimeUnitWithinFormatParser(strictMode),
24054
+ new ENMonthNameLittleEndianParser(),
24055
+ new ENMonthNameMiddleEndianParser(littleEndian),
24056
+ new ENWeekdayParser(),
24057
+ new ENSlashMonthFormatParser(),
24058
+ new ENTimeExpressionParser(strictMode),
24059
+ new ENTimeUnitAgoFormatParser(strictMode),
24060
+ new ENTimeUnitLaterFormatParser(strictMode),
24061
+ new ENYearMonthNameParser()
24062
+ ],
24063
+ refiners: [new ENMergeDateTimeRefiner()]
24064
+ }, strictMode);
24065
+ options.parsers.unshift(new ENYearMonthDayParser(strictMode));
24066
+ options.refiners.unshift(new ENMergeRelativeFollowByDateRefiner());
24067
+ options.refiners.unshift(new ENMergeRelativeAfterDateRefiner());
24068
+ options.refiners.unshift(new OverlapRemovalRefiner());
24069
+ options.refiners.push(new ENMergeDateTimeRefiner());
24070
+ options.refiners.push(new ENExtractYearSuffixRefiner());
24071
+ options.refiners.push(new ENMergeDateRangeRefiner());
24072
+ return options;
24073
+ }
24074
+ };
21057
24075
 
21058
- CREATE TABLE IF NOT EXISTS task_events (
21059
- id INTEGER PRIMARY KEY AUTOINCREMENT,
21060
- event_uuid TEXT NOT NULL UNIQUE,
21061
- task_uuid TEXT NOT NULL,
21062
- op TEXT NOT NULL CHECK (op IN ('create','complete','uncomplete','edit','delete')),
21063
- payload TEXT,
21064
- device_id TEXT NOT NULL,
21065
- ts TEXT NOT NULL DEFAULT (datetime('now')),
21066
- lamport INTEGER NOT NULL DEFAULT 0
21067
- );
21068
- CREATE INDEX IF NOT EXISTS idx_task_events_task ON task_events(task_uuid);
21069
- CREATE INDEX IF NOT EXISTS idx_task_events_lamport ON task_events(device_id, lamport);
21070
- `);
21071
- {
21072
- const cols = db.prepare(`PRAGMA table_info(tasks)`).all();
21073
- if (!cols.some((c) => c.name === "fingerprint")) {
21074
- db.exec(`ALTER TABLE tasks ADD COLUMN fingerprint TEXT`);
24076
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/chrono.js
24077
+ var Chrono = class _Chrono {
24078
+ parsers;
24079
+ refiners;
24080
+ defaultConfig = new ENDefaultConfiguration();
24081
+ constructor(configuration2) {
24082
+ configuration2 = configuration2 || this.defaultConfig.createCasualConfiguration();
24083
+ this.parsers = [...configuration2.parsers];
24084
+ this.refiners = [...configuration2.refiners];
24085
+ }
24086
+ clone() {
24087
+ return new _Chrono({
24088
+ parsers: [...this.parsers],
24089
+ refiners: [...this.refiners]
24090
+ });
21075
24091
  }
21076
- if (!cols.some((c) => c.name === "uuid")) {
21077
- db.exec(`ALTER TABLE tasks ADD COLUMN uuid TEXT`);
24092
+ parseDate(text2, referenceDate, option) {
24093
+ const results = this.parse(text2, referenceDate, option);
24094
+ return results.length > 0 ? results[0].start.date() : null;
21078
24095
  }
21079
- const pending = db.prepare(`SELECT id FROM tasks WHERE uuid IS NULL`).all();
21080
- if (pending.length > 0) {
21081
- const setUuid = db.prepare(`UPDATE tasks SET uuid = ? WHERE id = ?`);
21082
- inTransaction(() => {
21083
- for (const row of pending) setUuid.run(randomUUID(), row.id);
24096
+ parse(text2, referenceDate, option) {
24097
+ const context = new ParsingContext(text2, referenceDate, option);
24098
+ let results = [];
24099
+ this.parsers.forEach((parser) => {
24100
+ const parsedResults = _Chrono.executeParser(context, parser);
24101
+ results = results.concat(parsedResults);
24102
+ });
24103
+ results.sort((a, b) => {
24104
+ return a.index - b.index;
21084
24105
  });
24106
+ this.refiners.forEach(function(refiner) {
24107
+ results = refiner.refine(context, results);
24108
+ });
24109
+ return results;
21085
24110
  }
21086
- }
21087
- db.exec(`
21088
- CREATE INDEX IF NOT EXISTS idx_tasks_fingerprint ON tasks(fingerprint);
21089
- CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_uuid ON tasks(uuid);
21090
- `);
21091
- function ensureDeviceId() {
21092
- const row = db.prepare(`SELECT value FROM meta WHERE key = 'device_id'`).get();
21093
- if (row) return row.value;
21094
- const id = randomUUID();
21095
- db.prepare(
21096
- `INSERT OR IGNORE INTO meta (key, value) VALUES ('device_id', ?)`
21097
- ).run(id);
21098
- const final = db.prepare(`SELECT value FROM meta WHERE key = 'device_id'`).get();
21099
- return final.value;
21100
- }
21101
- var DEVICE_ID = ensureDeviceId();
21102
- function nextLamport() {
21103
- const row = db.prepare(`SELECT MAX(lamport) as m FROM task_events WHERE device_id = ?`).get(DEVICE_ID);
21104
- return (row.m ?? 0) + 1;
21105
- }
21106
- var insertEventStmt = db.prepare(
21107
- `INSERT INTO task_events (event_uuid, task_uuid, op, payload, device_id, lamport)
21108
- VALUES (?, ?, ?, ?, ?, ?)`
21109
- );
21110
- function recordEvent(op, taskUuid, payload) {
21111
- insertEventStmt.run(
21112
- randomUUID(),
21113
- taskUuid,
21114
- op,
21115
- payload === null ? null : JSON.stringify(payload),
21116
- DEVICE_ID,
21117
- nextLamport()
21118
- );
21119
- }
21120
- var insertTaskStmt = db.prepare(
21121
- `INSERT INTO tasks (uuid, text, due_at, source, fingerprint) VALUES (?, ?, ?, ?, ?) RETURNING *`
21122
- );
21123
- var findOpenByFingerprintStmt = db.prepare(
21124
- `SELECT * FROM tasks WHERE fingerprint = ? AND completed_at IS NULL LIMIT 1`
21125
- );
21126
- var countDoneTodayStmt = db.prepare(
21127
- `SELECT COUNT(*) as n FROM tasks WHERE completed_at IS NOT NULL
21128
- AND date(completed_at, 'localtime') = date('now', 'localtime')`
21129
- );
21130
- var selectOpenStmt = db.prepare(
21131
- `SELECT * FROM tasks WHERE completed_at IS NULL ORDER BY
21132
- CASE WHEN due_at IS NULL THEN 1 ELSE 0 END, due_at ASC, created_at ASC`
21133
- );
21134
- var selectAllStmt = db.prepare(
21135
- `SELECT * FROM tasks ORDER BY created_at DESC LIMIT ?`
21136
- );
21137
- var selectRecentDoneStmt = db.prepare(
21138
- `SELECT * FROM tasks
21139
- WHERE completed_at IS NOT NULL
21140
- AND completed_at >= datetime('now', ?)
21141
- ORDER BY completed_at DESC`
21142
- );
21143
- var selectArchivedStmt = db.prepare(
21144
- `SELECT * FROM tasks
21145
- WHERE completed_at IS NOT NULL
21146
- AND completed_at < datetime('now', ?)
21147
- ORDER BY completed_at DESC
21148
- LIMIT ?`
21149
- );
21150
- var completeTaskFindStmt = db.prepare(
21151
- `SELECT uuid, completed_at FROM tasks WHERE id = ?`
21152
- );
21153
- var completeTaskUpdateStmt = db.prepare(
21154
- `UPDATE tasks SET completed_at = datetime('now') WHERE id = ? AND completed_at IS NULL`
21155
- );
21156
- var getTaskStmt = db.prepare(`SELECT * FROM tasks WHERE id = ?`);
21157
- function fingerprint(text) {
21158
- return createHash("sha256").update(text.toLowerCase().replace(/\s+/g, " ").trim()).digest("hex").slice(0, 16);
21159
- }
21160
- function addTask(text, dueAt = null, source = "claude") {
21161
- const taskUuid = randomUUID();
21162
- const fp = fingerprint(text);
21163
- return inTransaction(() => {
21164
- const task = insertTaskStmt.get(taskUuid, text, dueAt, source, fp);
21165
- recordEvent("create", taskUuid, { text, due_at: dueAt, source });
21166
- return task;
21167
- });
21168
- }
21169
- function countDoneToday() {
21170
- return countDoneTodayStmt.get().n;
21171
- }
21172
- function listOpenTasks() {
21173
- return selectOpenStmt.all();
21174
- }
21175
- function listAllTasks(limit = 50) {
21176
- return selectAllStmt.all(limit);
21177
- }
21178
- function listRecentlyCompleted(hoursAgo = 24) {
21179
- return selectRecentDoneStmt.all(`-${hoursAgo} hours`);
21180
- }
21181
- function listArchived(hoursAgo = 24, limit = 100) {
21182
- return selectArchivedStmt.all(`-${hoursAgo} hours`, limit);
21183
- }
21184
- function completeTask(id) {
21185
- return inTransaction(() => {
21186
- const prior = completeTaskFindStmt.get(id);
21187
- if (!prior) return null;
21188
- const completed = prior.completed_at === null;
21189
- if (completed) {
21190
- completeTaskUpdateStmt.run(id);
21191
- recordEvent("complete", prior.uuid, null);
24111
+ static executeParser(context, parser) {
24112
+ const results = [];
24113
+ const pattern = parser.pattern(context);
24114
+ const originalText = context.text;
24115
+ let remainingText = context.text;
24116
+ let match = pattern.exec(remainingText);
24117
+ while (match) {
24118
+ const index = match.index + originalText.length - remainingText.length;
24119
+ match.index = index;
24120
+ const result = parser.extract(context, match);
24121
+ if (!result) {
24122
+ remainingText = originalText.substring(match.index + 1);
24123
+ match = pattern.exec(remainingText);
24124
+ continue;
24125
+ }
24126
+ let parsedResult = null;
24127
+ if (result instanceof ParsingResult) {
24128
+ parsedResult = result;
24129
+ } else if (result instanceof ParsingComponents) {
24130
+ parsedResult = context.createParsingResult(match.index, match[0]);
24131
+ parsedResult.start = result;
24132
+ } else {
24133
+ parsedResult = context.createParsingResult(match.index, match[0], result);
24134
+ }
24135
+ const parsedIndex = parsedResult.index;
24136
+ const parsedText = parsedResult.text;
24137
+ context.debug(() => console.log(`${parser.constructor.name} extracted (at index=${parsedIndex}) '${parsedText}'`));
24138
+ results.push(parsedResult);
24139
+ remainingText = originalText.substring(parsedIndex + parsedText.length);
24140
+ match = pattern.exec(remainingText);
21192
24141
  }
21193
- return { task: getTaskStmt.get(id), completed };
21194
- });
24142
+ return results;
24143
+ }
24144
+ };
24145
+ var ParsingContext = class {
24146
+ text;
24147
+ option;
24148
+ reference;
24149
+ refDate;
24150
+ constructor(text2, refDate, option) {
24151
+ this.text = text2;
24152
+ this.option = option ?? {};
24153
+ this.reference = ReferenceWithTimezone.fromInput(refDate, this.option.timezones);
24154
+ this.refDate = this.reference.instant;
24155
+ }
24156
+ createParsingComponents(components) {
24157
+ if (components instanceof ParsingComponents) {
24158
+ return components;
24159
+ }
24160
+ return new ParsingComponents(this.reference, components);
24161
+ }
24162
+ createParsingResult(index, textOrEndIndex, startComponents, endComponents) {
24163
+ const text2 = typeof textOrEndIndex === "string" ? textOrEndIndex : this.text.substring(index, textOrEndIndex);
24164
+ const start = startComponents ? this.createParsingComponents(startComponents) : null;
24165
+ const end = endComponents ? this.createParsingComponents(endComponents) : null;
24166
+ return new ParsingResult(this.reference, index, text2, start, end);
24167
+ }
24168
+ debug(block) {
24169
+ if (this.option.debug) {
24170
+ if (this.option.debug instanceof Function) {
24171
+ this.option.debug(block);
24172
+ } else {
24173
+ const handler = this.option.debug;
24174
+ handler.debug(block);
24175
+ }
24176
+ }
24177
+ }
24178
+ };
24179
+
24180
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/locales/en/index.js
24181
+ var configuration = new ENDefaultConfiguration();
24182
+ var casual = new Chrono(configuration.createCasualConfiguration(false));
24183
+ var strict = new Chrono(configuration.createConfiguration(true, false));
24184
+ var GB = new Chrono(configuration.createCasualConfiguration(true));
24185
+
24186
+ // node_modules/.pnpm/chrono-node@2.10.1/node_modules/chrono-node/dist/esm/index.js
24187
+ var casual2 = casual;
24188
+ function parse3(text2, ref, option) {
24189
+ return casual2.parse(text2, ref, option);
21195
24190
  }
21196
24191
 
21197
24192
  // src/dates.ts
24193
+ var ISO_DATE = /^\d{4}-\d{2}-\d{2}(?:[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?)?$/i;
24194
+ var PART_OF_DAY = /\b(?:morning|afternoon|evening|night|tonight|noon|midday|midnight)\b/i;
24195
+ function stamp(d) {
24196
+ return d.toISOString().replace(/\.\d{3}Z$/, "Z");
24197
+ }
21198
24198
  function toStoredDue(input) {
21199
24199
  const s = input.trim();
21200
24200
  const d = /^\d{4}-\d{2}-\d{2}$/.test(s) ? /* @__PURE__ */ new Date(`${s}T09:00:00`) : new Date(s);
21201
24201
  if (Number.isNaN(d.getTime())) return null;
21202
- return d.toISOString().replace(/\.\d{3}Z$/, "Z");
21203
- }
21204
- function timeContext(now = /* @__PURE__ */ new Date()) {
21205
- const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
21206
- const weekday = (d) => d.toLocaleDateString("en-US", { weekday: "long" });
21207
- const ymd = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
21208
- const hm = `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`;
21209
- const week = Array.from({ length: 7 }, (_, i) => {
21210
- const d = new Date(now.getFullYear(), now.getMonth(), now.getDate() + i + 1, 12);
21211
- return `${weekday(d)} ${ymd(d)}`;
24202
+ return stamp(d);
24203
+ }
24204
+ function resolveDue(phrase, ref = /* @__PURE__ */ new Date()) {
24205
+ const s = phrase.trim();
24206
+ const base = { phrase: s, ref: stamp(ref) };
24207
+ if (ISO_DATE.test(s)) return { ...base, at: toStoredDue(s) };
24208
+ const [result] = parse3(s, ref, { forwardDate: true });
24209
+ if (!result) return { ...base, at: null };
24210
+ let d = result.start.date();
24211
+ if (!result.start.isCertain("hour") && !PART_OF_DAY.test(result.text)) {
24212
+ d = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 9);
24213
+ if (d < ref && d.toDateString() === ref.toDateString()) d.setHours(23, 59);
24214
+ }
24215
+ return { ...base, at: stamp(d) };
24216
+ }
24217
+ function resolveSince(phrase, ref = /* @__PURE__ */ new Date()) {
24218
+ const s = phrase.trim();
24219
+ if (ISO_DATE.test(s)) {
24220
+ const d2 = /^\d{4}-\d{2}-\d{2}$/.test(s) ? /* @__PURE__ */ new Date(`${s}T00:00:00`) : new Date(s);
24221
+ return Number.isNaN(d2.getTime()) ? null : stamp(d2);
24222
+ }
24223
+ const [result] = parse3(s, ref);
24224
+ if (!result) return null;
24225
+ const start = result.start;
24226
+ const d = start.date();
24227
+ if (!start.isCertain("hour")) d.setHours(0, 0, 0, 0);
24228
+ if (d > ref && start.isCertain("weekday") && !start.isCertain("day")) d.setDate(d.getDate() - 7);
24229
+ else if (d > ref && !start.isCertain("year")) d.setFullYear(d.getFullYear() - 1);
24230
+ return stamp(d);
24231
+ }
24232
+ function describeDue(due2) {
24233
+ if (!due2.at) return `couldn't read "${due2.phrase}" as a date, so no due date`;
24234
+ const local = new Date(due2.at).toLocaleString("en-US", {
24235
+ weekday: "short",
24236
+ month: "short",
24237
+ day: "numeric",
24238
+ hour: "2-digit",
24239
+ minute: "2-digit",
24240
+ hourCycle: "h23",
24241
+ timeZoneName: "short"
21212
24242
  });
21213
- return `Now (user's local time, ${tz}): ${weekday(now)} ${ymd(now)} ${hm}.
21214
- The next 7 days: ${week.join(", ")}.`;
24243
+ return `due ${local} (${due2.at})` + (due2.phrase === due2.at ? "" : ` from "${due2.phrase}"`);
24244
+ }
24245
+
24246
+ // src/provenance.ts
24247
+ var EXCERPT_MAX = 200;
24248
+ var REF_MAX = 500;
24249
+ var contextSchema = external_exports.object({
24250
+ excerpt: external_exports.string().optional().describe(
24251
+ `The user's words this task came from, quoted exactly as they said them, e.g. 'I really need to call the dentist before Friday'. The pane shows it when they hover over the task, so they can see why it's there. Kept to ${EXCERPT_MAX} characters.`
24252
+ ),
24253
+ ref: external_exports.string().optional().describe("Where it came from, if there's a pointer to it: a file path, URL, ticket, or email subject.")
24254
+ }).optional().describe("Where this task came from. Include it whenever you can: tasks nobody recognizes get deleted.");
24255
+ function cap(s, max) {
24256
+ const flat = (s ?? "").replace(/\s+/g, " ").trim();
24257
+ if (!flat) return null;
24258
+ const chars = Array.from(flat);
24259
+ return chars.length <= max ? flat : chars.slice(0, max - 1).join("").trimEnd() + "\u2026";
24260
+ }
24261
+ var CLIENT_NAMES = {
24262
+ "claude-ai": "Claude Desktop",
24263
+ "cursor-vscode": "Cursor"
24264
+ };
24265
+ function clientLabel(info) {
24266
+ if (!info) return null;
24267
+ return info.title || CLIENT_NAMES[info.name] || info.name;
24268
+ }
24269
+ function fromTool(client2, context) {
24270
+ return {
24271
+ client: client2,
24272
+ ref: cap(context?.ref, REF_MAX),
24273
+ excerpt: cap(context?.excerpt, EXCERPT_MAX)
24274
+ };
24275
+ }
24276
+
24277
+ // src/tools/duplicate.ts
24278
+ function alreadyListed(task) {
24279
+ const due2 = task.due_at ? `, ${describeDue({ at: task.due_at, phrase: task.due_phrase ?? task.due_at, ref: "" })}` : "";
24280
+ return `Already on the list as #${task.id}: ${task.text}${due2}. Not added again.`;
21215
24281
  }
21216
24282
 
21217
24283
  // src/tools/add_task.ts
21218
24284
  var addTaskSchema = {
21219
24285
  text: external_exports.string().min(1).describe("The task text, e.g. 'Call the dentist'"),
21220
24286
  due_at: external_exports.string().optional().describe(
21221
- "Optional due date/time, ISO 8601. With Z or an offset it's exact ('2026-04-24T15:00:00Z'); without one it's the user's local time ('2026-04-24T15:00'); a date alone means 09:00 local."
21222
- )
24287
+ "Optional: when it's due, in the user's own words ('tomorrow', 'Friday 3pm', 'in 2 hours', 'next week'). Don't work out the date yourself; StickyInc does, in the user's time zone. Add am/pm to a bare hour. ISO 8601 works too: with Z or an offset it's exact, without one it's local time. No time of day means 09:00 local."
24288
+ ),
24289
+ context: contextSchema
21223
24290
  };
21224
- async function handleAddTask(args) {
21225
- const dueAt = args.due_at ? toStoredDue(args.due_at) : null;
21226
- if (args.due_at && !dueAt) {
24291
+ async function handleAddTask(args, client2) {
24292
+ const due2 = args.due_at ? resolveDue(args.due_at) : null;
24293
+ if (due2 && !due2.at) {
21227
24294
  return {
21228
24295
  content: [
21229
24296
  {
21230
24297
  type: "text",
21231
- text: `due_at "${args.due_at}" isn't a date/time. Use ISO 8601, e.g. 2026-04-24T15:00:00Z.`
24298
+ text: `due_at "${args.due_at}" isn't a date StickyInc can read. Try words like "Friday 5pm" or "in 3 days", or ISO 8601 (2026-04-24T17:00).`
21232
24299
  }
21233
24300
  ],
21234
24301
  isError: true
21235
24302
  };
21236
24303
  }
21237
- const task = addTask(args.text, dueAt);
21238
- const due = task.due_at ? ` (due ${task.due_at})` : "";
24304
+ const { task, inserted } = addTaskUnique({ text: args.text, due: due2, from: fromTool(client2, args.context) });
24305
+ if (!inserted) return { content: [{ type: "text", text: alreadyListed(task) }] };
24306
+ const dueText = due2 ? `, ${describeDue(due2)}` : "";
21239
24307
  return {
21240
24308
  content: [
21241
24309
  {
21242
24310
  type: "text",
21243
- text: `Added task #${task.id}: ${task.text}${due}`
24311
+ text: `Added task #${task.id}: ${task.text}${dueText}`
21244
24312
  }
21245
24313
  ]
21246
24314
  };
@@ -21287,9 +24355,9 @@ var AnthropicProvider = class {
21287
24355
  throw new Error(`Anthropic API error: ${res.status} ${await res.text()}`);
21288
24356
  }
21289
24357
  const data = await res.json();
21290
- const text = data.content.filter((b) => b.type === "text").map((b) => b.text ?? "").join("");
24358
+ const text2 = data.content.filter((b) => b.type === "text").map((b) => b.text ?? "").join("");
21291
24359
  return {
21292
- content: text,
24360
+ content: text2,
21293
24361
  model: data.model,
21294
24362
  provider: this.name,
21295
24363
  usage: { input: data.usage.input_tokens, output: data.usage.output_tokens }
@@ -21819,22 +24887,21 @@ async function resolveInternal() {
21819
24887
  var addTaskNaturalSchema = {
21820
24888
  input: external_exports.string().min(1).describe(
21821
24889
  "Free-text phrase like 'call dentist Friday 3pm' or 'buy bread'. Will be parsed by the configured LLM."
21822
- )
24890
+ ),
24891
+ context: contextSchema
21823
24892
  };
21824
24893
  var SYSTEM_PROMPT = `You convert a user phrase into a JSON task description.
21825
24894
 
21826
24895
  Output ONLY a single JSON object, no prose, no code fences. Schema:
21827
24896
  {
21828
24897
  "text": "<the thing to do, concise, no date>",
21829
- "due_at": "<local date-time YYYY-MM-DDTHH:MM, or null>"
24898
+ "due": "<the words that say when, copied from the phrase, or null>"
21830
24899
  }
21831
24900
 
21832
24901
  Rules:
21833
24902
  - "text" is the action, cleaned of date/time phrasing.
21834
- - "due_at" is the user's local time, with no offset or Z, or null if no time is implied. Take weekdays and "tomorrow" from the dates listed below.
21835
- - A weekday means its next occurrence; if that is today and the time has already passed, the one a week later.
21836
- - If a date is given without a time, use 09:00.
21837
- - If only a time is given, use today (or tomorrow if that time has passed).`;
24903
+ - "due" copies the date/time words as written ("Friday 3pm", "tomorrow", "in 2 hours", "next week"), or null if the phrase doesn't say when.
24904
+ - Don't work out a date; copy the words. If an hour has no am/pm, add the one the user means.`;
21838
24905
  function stripFences(s) {
21839
24906
  return s.replace(/^\s*```(?:json)?\s*/i, "").replace(/\s*```\s*$/, "").trim();
21840
24907
  }
@@ -21858,9 +24925,7 @@ async function parseTask(input) {
21858
24925
  const res = await provider.chat({
21859
24926
  system: SYSTEM_PROMPT,
21860
24927
  messages: [
21861
- { role: "user", content: `${timeContext()}
21862
-
21863
- Phrase: ${input}` }
24928
+ { role: "user", content: `Phrase: ${input}` }
21864
24929
  ],
21865
24930
  response_format: "json",
21866
24931
  max_tokens: 200,
@@ -21872,19 +24937,24 @@ Phrase: ${input}` }
21872
24937
  }
21873
24938
  return {
21874
24939
  text: parsed.text,
21875
- due_at: typeof parsed.due_at === "string" ? toStoredDue(parsed.due_at) : null
24940
+ due: typeof parsed.due === "string" && parsed.due.trim() ? resolveDue(parsed.due) : null
21876
24941
  };
21877
24942
  }
21878
- async function handleAddTaskNatural(args) {
24943
+ async function handleAddTaskNatural(args, client2) {
21879
24944
  try {
21880
24945
  const parsed = await parseTask(args.input);
21881
- const task = addTask(parsed.text, parsed.due_at);
21882
- const due = task.due_at ? ` (due ${task.due_at})` : "";
24946
+ const { task, inserted } = addTaskUnique({
24947
+ text: parsed.text,
24948
+ due: parsed.due,
24949
+ from: fromTool(client2, args.context)
24950
+ });
24951
+ if (!inserted) return { content: [{ type: "text", text: alreadyListed(task) }] };
24952
+ const due2 = parsed.due ? `, ${describeDue(parsed.due)}` : "";
21883
24953
  return {
21884
24954
  content: [
21885
24955
  {
21886
24956
  type: "text",
21887
- text: `Parsed & added task #${task.id}: ${task.text}${due}`
24957
+ text: `Parsed & added task #${task.id}: ${task.text}${due2}`
21888
24958
  }
21889
24959
  ]
21890
24960
  };
@@ -21911,8 +24981,8 @@ async function handleListTasks(args) {
21911
24981
  }
21912
24982
  const lines = tasks.map((t) => {
21913
24983
  const mark = t.completed_at ? "[x]" : "[ ]";
21914
- const due = t.due_at ? ` \u2014 due ${t.due_at}` : "";
21915
- return `${mark} #${t.id} ${t.text}${due}`;
24984
+ const due2 = t.due_at ? ` \u2014 due ${t.due_at}` : "";
24985
+ return `${mark} #${t.id} ${t.text}${due2}`;
21916
24986
  });
21917
24987
  const doneToday = countDoneToday();
21918
24988
  if (doneToday > 0) {
@@ -21949,31 +25019,38 @@ async function handleCompleteTask(args) {
21949
25019
  var scheduleEventSchema = {
21950
25020
  title: external_exports.string().min(1).describe("Event title"),
21951
25021
  start: external_exports.string().describe(
21952
- "Start, ISO 8601. With Z or an offset it's exact ('2026-04-24T15:00:00Z'); without one it's the user's local time."
25022
+ "When it starts, in the user's own words ('Friday 3pm', 'tomorrow at 10am'); StickyInc works out the date in their time zone. Or ISO 8601: with Z or an offset it's exact, without one local."
21953
25023
  ),
21954
25024
  end: external_exports.string().optional().describe("Optional end, ISO 8601. Echoed back, not stored."),
21955
- notes: external_exports.string().optional().describe("Optional notes/description")
25025
+ notes: external_exports.string().optional().describe("Optional notes/description"),
25026
+ context: contextSchema
21956
25027
  };
21957
- async function handleScheduleEvent(args) {
21958
- const start = toStoredDue(args.start);
21959
- if (!start) {
25028
+ async function handleScheduleEvent(args, client2) {
25029
+ const start = resolveDue(args.start);
25030
+ if (!start.at) {
21960
25031
  return {
21961
25032
  content: [
21962
25033
  {
21963
25034
  type: "text",
21964
- text: `start "${args.start}" isn't a date/time. Use ISO 8601, e.g. 2026-04-24T15:00:00Z.`
25035
+ text: `start "${args.start}" isn't a date StickyInc can read. Try words like "Friday 3pm", or ISO 8601 (2026-04-24T15:00).`
21965
25036
  }
21966
25037
  ],
21967
25038
  isError: true
21968
25039
  };
21969
25040
  }
21970
- const text = args.notes ? `${args.title} \u2014 ${args.notes}` : args.title;
21971
- const task = addTask(text, start, "calendar");
25041
+ const text2 = args.notes ? `${args.title} \u2014 ${args.notes}` : args.title;
25042
+ const { task, inserted } = addTaskUnique({
25043
+ text: text2,
25044
+ due: start,
25045
+ source: "calendar",
25046
+ from: fromTool(client2, args.context)
25047
+ });
25048
+ if (!inserted) return { content: [{ type: "text", text: alreadyListed(task) }] };
21972
25049
  return {
21973
25050
  content: [
21974
25051
  {
21975
25052
  type: "text",
21976
- text: `Scheduled task #${task.id}: ${args.title} @ ${start}` + (args.end ? ` \u2192 ${args.end}` : "") + `
25053
+ text: `Scheduled task #${task.id}: ${args.title}, ${describeDue(start)}` + (args.end ? ` \u2192 ${args.end}` : "") + `
21977
25054
  (If you want this on your Google Calendar too, ask me in the same turn \u2014 I'll use my Google Calendar connector. StickyInc only stores it locally.)`
21978
25055
  }
21979
25056
  ]
@@ -22009,19 +25086,285 @@ async function handleListDone(args) {
22009
25086
  return { content: [{ type: "text", text: lines.join("\n") }] };
22010
25087
  }
22011
25088
 
25089
+ // src/format.ts
25090
+ function sqliteUtcMs(s) {
25091
+ return Date.parse(s.replace(" ", "T") + "Z");
25092
+ }
25093
+ function addedOn(sqliteUtc) {
25094
+ return new Date(sqliteUtcMs(sqliteUtc)).toLocaleDateString("en-US", {
25095
+ weekday: "short",
25096
+ month: "short",
25097
+ day: "numeric"
25098
+ });
25099
+ }
25100
+ function ago(sqliteUtc, now2 = Date.now()) {
25101
+ const days = Math.floor((now2 - sqliteUtcMs(sqliteUtc)) / 864e5);
25102
+ if (days < 1) return "today";
25103
+ if (days === 1) return "yesterday";
25104
+ if (days < 14) return `${days} days ago`;
25105
+ if (days < 60) return `${Math.round(days / 7)} weeks ago`;
25106
+ return `${Math.round(days / 30)} months ago`;
25107
+ }
25108
+ function describeTask(t, now2 = Date.now()) {
25109
+ const mark = t.completed_at ? "[x]" : "[ ]";
25110
+ const from = t.source_client ? ` from ${t.source_client}` : "";
25111
+ const due2 = t.due_at ? ` \u2014 ${describeDue({ at: t.due_at, phrase: t.due_phrase ?? t.due_at, ref: "" })}` : "";
25112
+ const page = t.source_ref?.startsWith("http") ? ` \u2014 ${t.source_ref}` : "";
25113
+ const line = `${mark} #${t.id} ${t.text} \u2014 added ${addedOn(t.created_at)} (${ago(t.created_at, now2)})${from}${due2}${page}`;
25114
+ return t.source_excerpt ? `${line}
25115
+ \u201C${t.source_excerpt}\u201D` : line;
25116
+ }
25117
+
25118
+ // src/tools/sticky_search.ts
25119
+ var MAX_RESULTS = 20;
25120
+ var stickySearchSchema = {
25121
+ query: external_exports.string().optional().describe(
25122
+ "Words to look for in the task or in what the user said when it was added, e.g. 'dentist'. Leave out to list by status and date alone."
25123
+ ),
25124
+ status: external_exports.enum(["open", "done", "all"]).optional().describe("open (not done yet), done, or all. Default: all."),
25125
+ since: external_exports.string().optional().describe(
25126
+ "Only tasks added since then: the user's words ('3 weeks ago', 'last month', 'September 1') or ISO 8601."
25127
+ )
25128
+ };
25129
+ async function handleStickySearch(args) {
25130
+ const since = args.since ? resolveSince(args.since) : void 0;
25131
+ if (args.since && !since) {
25132
+ return {
25133
+ content: [
25134
+ {
25135
+ type: "text",
25136
+ text: `since "${args.since}" isn't a date StickyInc can read. Try "3 weeks ago", "last month", or 2026-09-01.`
25137
+ }
25138
+ ],
25139
+ isError: true
25140
+ };
25141
+ }
25142
+ const rows = searchTasks({ query: args.query, status: args.status, since: since ?? void 0, limit: MAX_RESULTS + 1 });
25143
+ const what = [
25144
+ args.query ? `matching "${args.query}"` : null,
25145
+ args.status && args.status !== "all" ? `${args.status}` : null,
25146
+ args.since ? `added since ${args.since}` : null
25147
+ ].filter(Boolean).join(", ");
25148
+ if (rows.length === 0) {
25149
+ return { content: [{ type: "text", text: `No tasks${what ? ` ${what}` : ""}.` }] };
25150
+ }
25151
+ const shown = rows.slice(0, MAX_RESULTS);
25152
+ const more = rows.length > MAX_RESULTS ? `
25153
+
25154
+ (More than ${MAX_RESULTS} match; narrow the search to see the rest.)` : "";
25155
+ return {
25156
+ content: [
25157
+ {
25158
+ type: "text",
25159
+ text: `${shown.length} task${shown.length === 1 ? "" : "s"}${what ? ` ${what}` : ""}:
25160
+
25161
+ ${shown.map((t) => describeTask(t)).join("\n")}${more}`
25162
+ }
25163
+ ]
25164
+ };
25165
+ }
25166
+
25167
+ // src/prompts.ts
25168
+ var DAY = 864e5;
25169
+ function actionList(scope, max) {
25170
+ return `End with an **Action list**: at most ${max} concrete next steps ${scope}, most important first, numbered, each naming its task number, e.g. "1. Call the dentist (#12) before 10am". If I agree something is done or should be dropped, mark it with complete_task.`;
25171
+ }
25172
+ function section(title, tasks, now2) {
25173
+ if (tasks.length === 0) return "";
25174
+ return `## ${title} (${tasks.length})
25175
+ ${tasks.map((t) => describeTask(t, now2)).join("\n")}
25176
+ `;
25177
+ }
25178
+ var due = (t) => t.due_at ? Date.parse(t.due_at) : Infinity;
25179
+ var byDue = (a, b) => due(a) - due(b);
25180
+ var byAdded = (a, b) => sqliteUtcMs(a.created_at) - sqliteUtcMs(b.created_at);
25181
+ function endOfDay(now2) {
25182
+ return new Date(now2.getFullYear(), now2.getMonth(), now2.getDate() + 1).getTime();
25183
+ }
25184
+ function today2(now2) {
25185
+ return now2.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" });
25186
+ }
25187
+ function morningReview(open, now2 = /* @__PURE__ */ new Date()) {
25188
+ const t = now2.getTime();
25189
+ const eod = endOfDay(now2);
25190
+ const dated = open.filter((x) => x.due_at).sort(byDue);
25191
+ const overdue = dated.filter((x) => due(x) < t);
25192
+ const dueToday = dated.filter((x) => due(x) >= t && due(x) < eod);
25193
+ const thisWeek = dated.filter((x) => due(x) >= eod && due(x) < t + 7 * DAY);
25194
+ const undated = open.filter((x) => !x.due_at).sort(byAdded).slice(0, 10);
25195
+ const body = section("Overdue", overdue, t) + section("Due today", dueToday, t) + section("Due in the next 7 days", thisWeek, t) + section("No due date (oldest first)", undated, t);
25196
+ return [
25197
+ `Morning review for ${today2(now2)}. Here's what's on my StickyInc list:`,
25198
+ body || "Nothing is open.",
25199
+ "Go through it with me: what matters most today, what's slipping, and what I should reschedule or drop. Point out anything I've been carrying for a long time.",
25200
+ actionList("for today", 5)
25201
+ ].join("\n\n");
25202
+ }
25203
+ function overdueReview(open, now2 = /* @__PURE__ */ new Date()) {
25204
+ const t = now2.getTime();
25205
+ const overdue = open.filter((x) => x.due_at && due(x) < t).sort(byDue);
25206
+ if (overdue.length === 0) {
25207
+ const upcoming = open.filter((x) => x.due_at && due(x) < t + 7 * DAY).sort(byDue);
25208
+ return [
25209
+ `Nothing on my StickyInc list is overdue as of ${today2(now2)}.`,
25210
+ section("Due in the next 7 days", upcoming, t) || "Nothing is due in the next 7 days either.",
25211
+ "Tell me I'm clear, then suggest what to get ahead on.",
25212
+ actionList("to get ahead", 3)
25213
+ ].join("\n\n");
25214
+ }
25215
+ return [
25216
+ `These StickyInc tasks are overdue as of ${today2(now2)}, with when I added them and the words they came from:`,
25217
+ section("Overdue", overdue, t),
25218
+ "For each one, say whether I should do it now, reschedule it (to when), or drop it, and why, going by what I said when I added it.",
25219
+ actionList("to clear the backlog", 7)
25220
+ ].join("\n\n");
25221
+ }
25222
+ function weeklyCloseout(open, doneThisWeek, now2 = /* @__PURE__ */ new Date()) {
25223
+ const t = now2.getTime();
25224
+ const weekAgo = t - 7 * DAY;
25225
+ const addedThisWeek = open.filter((x) => sqliteUtcMs(x.created_at) >= weekAgo).sort(byAdded);
25226
+ const dated = open.filter((x) => x.due_at).sort(byDue);
25227
+ const overdue = dated.filter((x) => due(x) < t);
25228
+ const nextWeek = dated.filter((x) => due(x) >= t && due(x) < t + 7 * DAY);
25229
+ const body = section("Done in the last 7 days", doneThisWeek, t) + section("Added this week and still open", addedThisWeek, t) + section("Overdue", overdue, t) + section("Due in the next 7 days", nextWeek, t);
25230
+ return [
25231
+ `Weekly close-out, ${today2(now2)}. Here's my week in StickyInc:`,
25232
+ body || "Nothing was done or added this week, and nothing is due.",
25233
+ "Close out the week with me: what got done, what slipped and why it might have, and what to carry into next week versus drop.",
25234
+ actionList("for next week", 7)
25235
+ ].join("\n\n");
25236
+ }
25237
+
25238
+ // src/routines.ts
25239
+ var BUILT_IN_PROMPTS = ["morning_review", "overdue", "weekly_closeout"];
25240
+ var PROMPT_MAX = 4e3;
25241
+ var SCHEDULE_MAX = 100;
25242
+ function routineName(name) {
25243
+ const slug = name.normalize("NFKD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 40).replace(/_+$/, "");
25244
+ return /^[a-z0-9]/.test(slug) ? slug : null;
25245
+ }
25246
+ function checkRoutine(input) {
25247
+ if (!input || typeof input !== "object") return { error: "a routine is an object with a name and a prompt" };
25248
+ const { name, prompt, schedule } = input;
25249
+ if (typeof name !== "string" || !routineName(name)) return { error: "it needs a name with letters or digits in it" };
25250
+ const slug = routineName(name);
25251
+ if (BUILT_IN_PROMPTS.includes(slug)) return { error: `"${slug}" is a built-in prompt; pick another name` };
25252
+ if (typeof prompt !== "string" || !prompt.trim()) return { error: `"${slug}" needs a prompt` };
25253
+ if (prompt.length > PROMPT_MAX) return { error: `"${slug}": the prompt is over ${PROMPT_MAX} characters` };
25254
+ if (schedule != null && (typeof schedule !== "string" || schedule.length > SCHEDULE_MAX)) {
25255
+ return { error: `"${slug}": the schedule should be a short phrase like "weekdays at 8:30"` };
25256
+ }
25257
+ return { routine: { name: slug, prompt: prompt.trim(), schedule: schedule ? String(schedule).trim() : null } };
25258
+ }
25259
+ function parseRoutines(json) {
25260
+ let data;
25261
+ try {
25262
+ data = JSON.parse(json);
25263
+ } catch (e) {
25264
+ return { error: `that isn't JSON (${e instanceof Error ? e.message : e})` };
25265
+ }
25266
+ const items = Array.isArray(data) ? data : [data];
25267
+ if (items.length === 0) return { error: "there are no routines in it" };
25268
+ const routines = [];
25269
+ for (const [i, item] of items.entries()) {
25270
+ const checked = checkRoutine(item);
25271
+ if ("error" in checked) return { error: items.length > 1 ? `routine ${i + 1}: ${checked.error}` : checked.error };
25272
+ routines.push(checked.routine);
25273
+ }
25274
+ const names = routines.map((r) => r.name);
25275
+ const dup = names.find((n, i) => names.indexOf(n) !== i);
25276
+ if (dup) return { error: `"${dup}" appears twice` };
25277
+ return { routines };
25278
+ }
25279
+ function exportRoutines(routines) {
25280
+ return JSON.stringify(
25281
+ routines.map(({ name, prompt, schedule }) => ({ name, prompt, schedule: schedule ?? null })),
25282
+ null,
25283
+ 2
25284
+ );
25285
+ }
25286
+ function routinePromptText(r) {
25287
+ return `${r.prompt}
25288
+
25289
+ (This is my StickyInc routine "${r.name}". Look up what it needs with sticky_search.)`;
25290
+ }
25291
+
25292
+ // src/tools/routines.ts
25293
+ var text = (t, isError = false) => ({
25294
+ content: [{ type: "text", text: t }],
25295
+ ...isError && { isError: true }
25296
+ });
25297
+ var howToRun = (name) => `Run it from the prompt menu, or in Claude Code as /mcp__stickyinc__${name}.`;
25298
+ var routineListSchema = {
25299
+ format: external_exports.enum(["text", "json"]).optional().describe("text (default) to read them, or json to export them for sharing or backup.")
25300
+ };
25301
+ async function handleRoutineList(args) {
25302
+ const routines = listRoutines();
25303
+ if (args.format === "json") return text(exportRoutines(routines));
25304
+ if (routines.length === 0) {
25305
+ return text("No routines yet. Save one with sticky_routine_save, or import some with sticky_routine_import.");
25306
+ }
25307
+ const lines = routines.map(
25308
+ (r) => `\u2022 ${r.name}${r.schedule ? ` (${r.schedule})` : ""}
25309
+ ${r.prompt.replace(/\s+/g, " ").slice(0, 160)}`
25310
+ );
25311
+ return text(`${routines.length} routine${routines.length === 1 ? "" : "s"}:
25312
+
25313
+ ${lines.join("\n")}
25314
+
25315
+ ${howToRun("<name>")}`);
25316
+ }
25317
+ var routineSaveSchema = {
25318
+ name: external_exports.string().min(1).describe("Short name, e.g. 'waiting on others'; stored as waiting_on_others."),
25319
+ prompt: external_exports.string().min(1).max(PROMPT_MAX).describe("What to ask when it runs, e.g. 'What am I waiting on from other people? Who should I chase?'"),
25320
+ schedule: external_exports.string().optional().describe("When it's meant to run, in words ('weekdays at 8:30', 'Fridays at 4pm'). A hint for whatever runs it.")
25321
+ };
25322
+ async function handleRoutineSave(args, onChange) {
25323
+ const checked = checkRoutine(args);
25324
+ if ("error" in checked) return text(`Can't save that routine: ${checked.error}.`, true);
25325
+ const isNew = saveRoutine(checked.routine);
25326
+ onChange();
25327
+ return text(`${isNew ? "Saved" : "Updated"} routine "${checked.routine.name}". ${howToRun(checked.routine.name)}`);
25328
+ }
25329
+ var routineDeleteSchema = {
25330
+ name: external_exports.string().min(1).describe("The routine's name.")
25331
+ };
25332
+ async function handleRoutineDelete(args, onChange) {
25333
+ const name = routineName(args.name) ?? args.name;
25334
+ if (!deleteRoutine(name)) return text(`There's no routine called "${name}".`, true);
25335
+ onChange();
25336
+ return text(`Deleted routine "${name}".`);
25337
+ }
25338
+ var routineImportSchema = {
25339
+ json: external_exports.string().min(1).describe(
25340
+ 'Routines as JSON: one {"name", "prompt", "schedule"} object or an array of them, as sticky_routine_list exports. Routines with the same name are replaced.'
25341
+ )
25342
+ };
25343
+ async function handleRoutineImport(args, onChange) {
25344
+ const parsed = parseRoutines(args.json);
25345
+ if ("error" in parsed) return text(`Nothing imported: ${parsed.error}.`, true);
25346
+ const added = parsed.routines.filter((r) => saveRoutine(r)).length;
25347
+ onChange();
25348
+ const replaced = parsed.routines.length - added;
25349
+ return text(
25350
+ `Imported ${parsed.routines.map((r) => r.name).join(", ")} (${added} new${replaced ? `, ${replaced} replaced` : ""}). ${howToRun("<name>")}`
25351
+ );
25352
+ }
25353
+
22012
25354
  // src/index.ts
22013
25355
  var server = new McpServer({
22014
25356
  name: "stickyinc",
22015
- version: "0.5.2"
25357
+ version: "0.6.0"
22016
25358
  });
25359
+ var client = () => clientLabel(server.server.getClientVersion());
22017
25360
  server.registerTool(
22018
25361
  "add_task",
22019
25362
  {
22020
25363
  title: "Add Task",
22021
- description: "Add a todo to StickyInc. The user sees it appear in their floating pane.",
25364
+ description: "Add a todo to StickyInc. The user sees it appear in their floating pane, and hovering over it shows context.excerpt: quote their words so they can tell where it came from.",
22022
25365
  inputSchema: addTaskSchema
22023
25366
  },
22024
- handleAddTask
25367
+ (args) => handleAddTask(args, client())
22025
25368
  );
22026
25369
  server.registerTool(
22027
25370
  "add_task_natural",
@@ -22030,7 +25373,7 @@ server.registerTool(
22030
25373
  description: "Parse a free-text phrase like 'call dentist Friday 3pm' into a task with optional due date, using the configured LLM (Anthropic/OpenRouter/OpenAI).",
22031
25374
  inputSchema: addTaskNaturalSchema
22032
25375
  },
22033
- handleAddTaskNatural
25376
+ (args) => handleAddTaskNatural(args, client())
22034
25377
  );
22035
25378
  server.registerTool(
22036
25379
  "list_tasks",
@@ -22066,7 +25409,113 @@ server.registerTool(
22066
25409
  description: "Save an event as a StickyInc task due at its start time. StickyInc doesn't sync calendars; use a calendar connector for that.",
22067
25410
  inputSchema: scheduleEventSchema
22068
25411
  },
22069
- handleScheduleEvent
25412
+ (args) => handleScheduleEvent(args, client())
25413
+ );
25414
+ server.registerTool(
25415
+ "sticky_search",
25416
+ {
25417
+ title: "Search Tasks",
25418
+ description: `Search everything the user has put in StickyInc, open and done, by words in the task or in what they said when it was added, optionally only since a date. Use it to remind them what they committed to and when, e.g. "you said you'd call the dentist three weeks ago". Returns up to 20 tasks, best match first.`,
25419
+ inputSchema: stickySearchSchema
25420
+ },
25421
+ handleStickySearch
25422
+ );
25423
+ var openTasks = () => searchTasks({ status: "open", limit: 500 });
25424
+ var asPrompt = (text2) => ({
25425
+ messages: [{ role: "user", content: { type: "text", text: text2 } }]
25426
+ });
25427
+ server.registerPrompt(
25428
+ "morning_review",
25429
+ {
25430
+ title: "Morning review",
25431
+ description: "Go through today's StickyInc list (overdue, due today, this week) and end with an action list for today."
25432
+ },
25433
+ () => asPrompt(morningReview(openTasks()))
25434
+ );
25435
+ server.registerPrompt(
25436
+ "overdue",
25437
+ {
25438
+ title: "Overdue",
25439
+ description: "Decide what to do about each overdue StickyInc task (do now, reschedule, or drop), ending with an action list."
25440
+ },
25441
+ () => asPrompt(overdueReview(openTasks()))
25442
+ );
25443
+ server.registerPrompt(
25444
+ "weekly_closeout",
25445
+ {
25446
+ title: "Weekly close-out",
25447
+ description: "Review the week in StickyInc (done, slipped, due next) and end with an action list for next week."
25448
+ },
25449
+ () => {
25450
+ const weekAgo = new Date(Date.now() - 7 * 864e5).toISOString();
25451
+ const done = searchTasks({ status: "done", completedSince: weekAgo, limit: 200 });
25452
+ return asPrompt(weeklyCloseout(openTasks(), done));
25453
+ }
25454
+ );
25455
+ var routinePrompts = /* @__PURE__ */ new Map();
25456
+ var describeRoutine = (prompt, schedule) => `Your routine${schedule ? ` (${schedule})` : ""}: ${prompt.replace(/\s+/g, " ").slice(0, 120)}`;
25457
+ function syncRoutinePrompts() {
25458
+ const routines = listRoutines();
25459
+ const names = new Set(routines.map((r) => r.name));
25460
+ for (const [name, registered] of routinePrompts) {
25461
+ if (!names.has(name)) {
25462
+ registered.remove();
25463
+ routinePrompts.delete(name);
25464
+ }
25465
+ }
25466
+ for (const r of routines) {
25467
+ const description = describeRoutine(r.prompt, r.schedule);
25468
+ const registered = routinePrompts.get(r.name);
25469
+ if (!registered) {
25470
+ routinePrompts.set(
25471
+ r.name,
25472
+ server.registerPrompt(r.name, { title: r.name.replace(/_/g, " "), description }, () => {
25473
+ const current = listRoutines().find((x) => x.name === r.name) ?? r;
25474
+ return asPrompt(routinePromptText(current));
25475
+ })
25476
+ );
25477
+ } else if (registered.description !== description) {
25478
+ registered.update({ description });
25479
+ }
25480
+ }
25481
+ }
25482
+ server.registerTool(
25483
+ "sticky_routine_list",
25484
+ {
25485
+ title: "List Routines",
25486
+ description: "List the user's StickyInc routines (saved prompts they run on a schedule or by hand), or export them as JSON.",
25487
+ inputSchema: routineListSchema
25488
+ },
25489
+ handleRoutineList
25490
+ );
25491
+ server.registerTool(
25492
+ "sticky_routine_save",
25493
+ {
25494
+ title: "Save Routine",
25495
+ description: "Save a routine: a named prompt the user wants to run regularly, like a Friday check on what they're waiting on from others. Replaces one with the same name. It shows up as a prompt they can run.",
25496
+ inputSchema: routineSaveSchema
25497
+ },
25498
+ (args) => handleRoutineSave(args, syncRoutinePrompts)
25499
+ );
25500
+ server.registerTool(
25501
+ "sticky_routine_delete",
25502
+ {
25503
+ title: "Delete Routine",
25504
+ description: "Delete one of the user's StickyInc routines by name.",
25505
+ inputSchema: routineDeleteSchema
25506
+ },
25507
+ (args) => handleRoutineDelete(args, syncRoutinePrompts)
25508
+ );
25509
+ server.registerTool(
25510
+ "sticky_routine_import",
25511
+ {
25512
+ title: "Import Routines",
25513
+ description: "Import routines from JSON (one routine or an array, as sticky_routine_list exports), e.g. ones someone shared.",
25514
+ inputSchema: routineImportSchema
25515
+ },
25516
+ (args) => handleRoutineImport(args, syncRoutinePrompts)
22070
25517
  );
25518
+ syncRoutinePrompts();
25519
+ setInterval(syncRoutinePrompts, 3e4).unref();
22071
25520
  var transport = new StdioServerTransport();
22072
25521
  await server.connect(transport);