patent-query-shortcuts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # patent-query-shortcuts
2
+
3
+ Shortcut expansion + template system for patent search queries.
4
+
5
+ ## Install
6
+ npm i patent-query-shortcuts
7
+
8
+ ## Usage
9
+ ```ts
10
+ import { createRegistry, patsnapTemplate } from "patent-query-shortcuts";
11
+
12
+ const reg = createRegistry([patsnapTemplate]);
13
+
14
+ // Suggest in UI
15
+ console.log(reg.suggest("TA", "patsnap"));
16
+
17
+ // Expand user query
18
+ const expanded = reg.expand(`TAC:(stent) AND MCPC:(A61K)`, { templateId: "patsnap" });
19
+ console.log(expanded);
20
+ // => TAC_ALL:(stent) AND MCPC:(A61K)
21
+
22
+ // Build a clause (UI query builder)
23
+ console.log(reg.build("TAC", "(stent)", { templateId: "patsnap" }));
24
+ // => TAC_ALL:(stent)
package/dist/index.cjs ADDED
@@ -0,0 +1,368 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
+
22
+ // src/index.ts
23
+ var index_exports = {};
24
+ __export(index_exports, {
25
+ ShortcutRegistry: () => ShortcutRegistry,
26
+ createRegistry: () => createRegistry,
27
+ patsnapTemplate: () => patsnapTemplate
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/templates/patsnap.ts
32
+ var patsnapTemplate = {
33
+ id: "patsnap",
34
+ name: "Patsnap",
35
+ normalizeKey: "upper",
36
+ shortcuts: [
37
+ // --- Text fields (from your 1st screenshot) ---
38
+ { key: "TA", kind: "field", field: "TA_ALL", label: "Title + Abstract", description: "Search in title and abstract", aliases: ["TA_ALL"] },
39
+ { key: "TTL", kind: "field", field: "TTL_ALL", label: "Title", description: "Search in title", aliases: ["TTL_ALL"] },
40
+ { key: "TAC", kind: "field", field: "TAC_ALL", label: "Title+Abstract+Claims", description: "Search in title, abstract, and claims", aliases: ["TAC_ALL"] },
41
+ { key: "TACD", kind: "field", field: "TACD_ALL", label: "Title+Abstract+Claims+Description", description: "Search in title/abstract/claims/description", aliases: ["TACD_ALL"] },
42
+ { key: "ABST", kind: "field", field: "ABST_ALL", label: "Abstract", description: "Search in abstract", aliases: ["ABST_ALL"] },
43
+ { key: "CLMS", kind: "field", field: "CLMS_ALL", label: "Claims", description: "Search in claims", aliases: ["CLMS_ALL"] },
44
+ { key: "DESC", kind: "field", field: "DESC_ALL", label: "Description", description: "Search in description", aliases: ["DESC_ALL"] },
45
+ { key: "DESC_F", kind: "field", field: "DESC_F", label: "Technical Field", description: "Description: technical field" },
46
+ { key: "DESC_B", kind: "field", field: "DESC_B", label: "Background Art", description: "Description: background art" },
47
+ { key: "DESC_S", kind: "field", field: "DESC_S", label: "Summary of Invention", description: "Description: summary" },
48
+ { key: "DESC_D", kind: "field", field: "DESC_D", label: "Brief Description of Drawings", description: "Description: drawings" },
49
+ { key: "DESC_E", kind: "field", field: "DESC_E", label: "Description of Embodiments", description: "Description: embodiments" },
50
+ { key: "ICLMS", kind: "field", field: "ICLMS_ALL", label: "Independent Claims", description: "Search in independent claims", aliases: ["ICLMS_ALL"] },
51
+ { key: "PROBLEM_SUM", kind: "field", field: "PROBLEM_SUM", label: "Technical Problem", description: "Problem summary" },
52
+ { key: "METHOD_SUM", kind: "field", field: "METHOD_SUM", label: "Technical Method", description: "Method summary" },
53
+ { key: "BENEFIT_SUM", kind: "field", field: "BENEFIT_SUM", label: "Technical Benefit", description: "Benefit summary" },
54
+ // --- Classification (2nd screenshot) ---
55
+ { key: "MCPC", kind: "field", field: "MCPC", label: "Main CPC" },
56
+ { key: "CPC_SUB_GROUP", kind: "field", field: "CPC_SUB_GROUP", label: "CPC Sub Group" },
57
+ { key: "IPC_CPC", kind: "field", field: "IPC_CPC", label: "IPC & CPC" },
58
+ { key: "UPC", kind: "field", field: "UPC", label: "UPC" },
59
+ { key: "LOC", kind: "field", field: "LOC", label: "LOC" },
60
+ { key: "FI", kind: "field", field: "FI", label: "FI" },
61
+ { key: "FTERM", kind: "field", field: "FTERM", label: "F-TERM" },
62
+ { key: "ADC", kind: "field", field: "ADC", label: "Application Domain" },
63
+ { key: "TTC", kind: "field", field: "TTC", label: "Technology Topic" },
64
+ { key: "SEIC", kind: "field", field: "SEIC", label: "Main SEIC" },
65
+ { key: "SEIC_ALL", kind: "field", field: "SEIC_ALL", label: "SEIC (All)" },
66
+ { key: "GBC", kind: "field", field: "GBC", label: "GBC" },
67
+ // --- Assignees / Inventors (3rd screenshot) ---
68
+ { key: "ALL_AN", kind: "field", field: "ALL_AN", label: "All Assignees" },
69
+ { key: "ANCS", kind: "field", field: "ANCS", label: "Std. Current Assignee" },
70
+ { key: "ANC", kind: "field", field: "ANC", label: "Current Assignee" },
71
+ { key: "GNAME", kind: "field", field: "GNAME", label: "Grouped Assignee" },
72
+ { key: "ANS", kind: "field", field: "ANS", label: "Std. Original Assignee" },
73
+ { key: "AN", kind: "field", field: "AN", label: "Original Assignee" },
74
+ { key: "F_AN", kind: "field", field: "F_AN", label: "First Original Assignee" },
75
+ { key: "F_ANC", kind: "field", field: "F_ANC", label: "First Current Assignee" },
76
+ { key: "IN", kind: "field", field: "IN", label: "Inventor Name" },
77
+ { key: "F_IN", kind: "field", field: "F_IN", label: "First Inventor" },
78
+ { key: "ATC", kind: "field", field: "ATC", label: "Agency" },
79
+ { key: "ATCS", kind: "field", field: "ATCS", label: "Std. Agency" },
80
+ { key: "AT", kind: "field", field: "AT", label: "Attorney Name" },
81
+ { key: "PE", kind: "field", field: "PE", label: "Primary Examiner" },
82
+ { key: "AE", kind: "field", field: "AE", label: "Assistant Examiner" },
83
+ // --- Dates (4th screenshot) ---
84
+ { key: "APD", kind: "field", field: "APD", label: "Application Date" },
85
+ { key: "PBD", kind: "field", field: "PBD", label: "Publication Date" },
86
+ { key: "PRIORITY_DATE", kind: "field", field: "PRIORITY_DATE", label: "Priority Date" },
87
+ { key: "EXDT", kind: "field", field: "EXDT", label: "Estimated Expiry Date" },
88
+ { key: "ISD", kind: "field", field: "ISD", label: "Issue Date" },
89
+ { key: "EXPD", kind: "field", field: "EXPD", label: "Expiry Date" },
90
+ { key: "EXAMINE_DATE", kind: "field", field: "EXAMINE_DATE", label: "Substantive Examination Date" },
91
+ { key: "PCTENTRY_DATE", kind: "field", field: "PCTENTRY_DATE", label: "PCT Entry Date" },
92
+ { key: "LEGAL_STATUS_DATE", kind: "field", field: "LEGAL_STATUS_DATE", label: "Legal Status Date" },
93
+ // --- Numbers (5th screenshot) ---
94
+ { key: "PN", kind: "field", field: "PN", label: "Publication Number" },
95
+ { key: "APNO", kind: "field", field: "APNO", label: "Application Number" },
96
+ { key: "PRNO", kind: "field", field: "PRNO", label: "Priority Number" },
97
+ { key: "KD", kind: "field", field: "KD", label: "Kind Code" },
98
+ { key: "PCT_APNO", kind: "field", field: "PCT_APNO", label: "PCT Application Number" },
99
+ { key: "PCT_PN", kind: "field", field: "PCT_PN", label: "PCT Publication Number" },
100
+ // --- Addresses / Regions (6th screenshot) ---
101
+ { key: "AN_ADD", kind: "field", field: "AN_ADD", label: "Original Assignee Address" },
102
+ { key: "ANC_ADD", kind: "field", field: "ANC_ADD", label: "Current Assignee Address" },
103
+ { key: "IN_ADDRESS", kind: "field", field: "IN_ADDRESS", label: "Inventor Address" },
104
+ { key: "PRIORITY_COUNTRY", kind: "field", field: "PRIORITY_COUNTRY", label: "Priority Country/Region" },
105
+ { key: "AUTHORITY", kind: "field", field: "AUTHORITY", label: "Authority" },
106
+ { key: "EPDS", kind: "field", field: "EPDS", label: "EP Designated State" },
107
+ { key: "ENTRY_COUNTRY", kind: "field", field: "ENTRY_COUNTRY", label: "Entry Country/Region" },
108
+ // --- Citations / Family (7th screenshot) ---
109
+ { key: "B_CITES", kind: "field", field: "B_CITES", label: "Backward Citations" },
110
+ { key: "F_CITES", kind: "field", field: "F_CITES", label: "Forward Citations" },
111
+ { key: "BF_CITES", kind: "field", field: "BF_CITES", label: "Backward Or Forward Citations" },
112
+ { key: "B_CITES_COUNT", kind: "field", field: "B_CITES_COUNT", label: "Count Of Backward Citations" },
113
+ { key: "F_CITES_COUNT", kind: "field", field: "F_CITES_COUNT", label: "Count Of Forward Citations" },
114
+ { key: "F_CITES_ANC", kind: "field", field: "F_CITES_ANC", label: "Assignee Forward Citations (Current)" },
115
+ { key: "B_CITES_ANC", kind: "field", field: "B_CITES_ANC", label: "Assignee Backward Citations (Current)" },
116
+ { key: "CITE_CATEGORY", kind: "field", field: "CITE_CATEGORY", label: "Citation/Rejection Category" },
117
+ { key: "FAM", kind: "field", field: "FAM", label: "Simple Family" },
118
+ { key: "EFAM", kind: "field", field: "EFAM", label: "PatSnap Family" },
119
+ { key: "FAM_COUNT", kind: "field", field: "FAM_COUNT", label: "Simple Family Application Count" },
120
+ { key: "IFAM_COUNT", kind: "field", field: "IFAM_COUNT", label: "INPADOC Family Application Count" },
121
+ { key: "EFAM_COUNT", kind: "field", field: "EFAM_COUNT", label: "PatSnap Family Application Count" },
122
+ { key: "FAM_COUNTRY_COUNT", kind: "field", field: "FAM_COUNTRY_COUNT", label: "Simple Family Jurisdiction Count" },
123
+ { key: "IFAM_COUNTRY_COUNT", kind: "field", field: "IFAM_COUNTRY_COUNT", label: "INPADOC Family Jurisdiction Count" },
124
+ { key: "EFAM_COUNTRY_COUNT", kind: "field", field: "EFAM_COUNTRY_COUNT", label: "PatSnap Family Jurisdiction Count" },
125
+ // --- Legal status / metrics (8th screenshot) ---
126
+ { key: "LEGAL_STATUS", kind: "field", field: "LEGAL_STATUS", label: "Legal Status" },
127
+ { key: "LEGAL_EVENT", kind: "field", field: "LEGAL_EVENT", label: "Legal Event" },
128
+ { key: "SIMPLE_LEGAL_STATUS", kind: "field", field: "SIMPLE_LEGAL_STATUS", label: "Simple Legal Status" },
129
+ { key: "UP_STATUS", kind: "field", field: "UP_STATUS", label: "Status of Unified Patent Court" },
130
+ { key: "ENTRY_COUNTRY_LS", kind: "field", field: "ENTRY_COUNTRY_LS", label: "Legal Status of Entry Country/Region" },
131
+ { key: "ENTRY_COUNTRY_SLS", kind: "field", field: "ENTRY_COUNTRY_SLS", label: "Simple Legal Status of Entry Country/Region" },
132
+ { key: "PV", kind: "field", field: "PV", label: "Patent Value" },
133
+ { key: "PAGE_COUNT", kind: "field", field: "PAGE_COUNT", label: "Page Count" },
134
+ { key: "CLAIM_COUNT", kind: "field", field: "CLAIM_COUNT", label: "Claim Count" },
135
+ { key: "FCLMS_WORDCOUNT", kind: "field", field: "FCLMS_WORDCOUNT", label: "Word count of first claim" },
136
+ { key: "AN_COUNT", kind: "field", field: "AN_COUNT", label: "Count of Original Assignees" },
137
+ { key: "ANC_COUNT", kind: "field", field: "ANC_COUNT", label: "Count of Current Assignees" },
138
+ { key: "IN_COUNT", kind: "field", field: "IN_COUNT", label: "Count of Inventors" },
139
+ { key: "GOV", kind: "field", field: "GOV", label: "Government Interest" }
140
+ ]
141
+ };
142
+
143
+ // src/index.ts
144
+ function normalizeKey(t, key) {
145
+ return t.normalizeKey === "upper" ? key.toUpperCase() : key;
146
+ }
147
+ function isBareValue(v) {
148
+ const s = v.trim();
149
+ return !(s.startsWith("(") || s.startsWith("[") || s.startsWith('"'));
150
+ }
151
+ function maybeWrapValue(v, wrapBareValues) {
152
+ const s = v.trim();
153
+ if (!wrapBareValues) return s;
154
+ if (!isBareValue(s)) return s;
155
+ return `(${s})`;
156
+ }
157
+ function readValue(input, start) {
158
+ let i = start;
159
+ while (i < input.length && /\s/.test(input[i])) i++;
160
+ const ch = input[i];
161
+ if (!ch) return ["", i];
162
+ const readBalanced = (open, close) => {
163
+ let depth = 0;
164
+ let j2 = i;
165
+ while (j2 < input.length) {
166
+ const c = input[j2];
167
+ if (c === open) depth++;
168
+ else if (c === close) {
169
+ depth--;
170
+ if (depth === 0) {
171
+ j2++;
172
+ return [input.slice(i, j2), j2];
173
+ }
174
+ } else if (c === '"') {
175
+ j2++;
176
+ while (j2 < input.length) {
177
+ if (input[j2] === "\\" && j2 + 1 < input.length) {
178
+ j2 += 2;
179
+ continue;
180
+ }
181
+ if (input[j2] === '"') {
182
+ j2++;
183
+ break;
184
+ }
185
+ j2++;
186
+ }
187
+ continue;
188
+ }
189
+ j2++;
190
+ }
191
+ return [input.slice(i), input.length];
192
+ };
193
+ if (ch === "(") return readBalanced("(", ")");
194
+ if (ch === "[") return readBalanced("[", "]");
195
+ if (ch === '"') {
196
+ let j2 = i + 1;
197
+ while (j2 < input.length) {
198
+ if (input[j2] === "\\" && j2 + 1 < input.length) {
199
+ j2 += 2;
200
+ continue;
201
+ }
202
+ if (input[j2] === '"') {
203
+ j2++;
204
+ break;
205
+ }
206
+ j2++;
207
+ }
208
+ return [input.slice(i, j2), j2];
209
+ }
210
+ let j = i;
211
+ while (j < input.length && !/\s/.test(input[j])) j++;
212
+ return [input.slice(i, j), j];
213
+ }
214
+ function getTokenRange(text, cursor) {
215
+ const isWord = (c) => /[A-Za-z0-9_]/.test(c);
216
+ let start = Math.max(0, cursor);
217
+ while (start > 0 && isWord(text[start - 1])) start--;
218
+ let end = Math.max(0, cursor);
219
+ while (end < text.length && isWord(text[end])) end++;
220
+ const prefix = text.slice(start, cursor);
221
+ return { start, end, prefix };
222
+ }
223
+ function renderSnippet(snippet) {
224
+ const idx = snippet.indexOf("|");
225
+ if (idx === -1) return { insertText: snippet, cursorIndex: snippet.length };
226
+ const insertText = snippet.replace("|", "");
227
+ return { insertText, cursorIndex: idx };
228
+ }
229
+ var ShortcutRegistry = class {
230
+ constructor(templates) {
231
+ __publicField(this, "templates", /* @__PURE__ */ new Map());
232
+ __publicField(this, "lookup", /* @__PURE__ */ new Map());
233
+ for (const t of templates) this.registerTemplate(t);
234
+ }
235
+ registerTemplate(t) {
236
+ this.templates.set(t.id, t);
237
+ const map = /* @__PURE__ */ new Map();
238
+ for (const sc of t.shortcuts) {
239
+ map.set(normalizeKey(t, sc.key), sc);
240
+ for (const a of sc.aliases ?? []) map.set(normalizeKey(t, a), sc);
241
+ }
242
+ this.lookup.set(t.id, map);
243
+ }
244
+ listTemplates() {
245
+ return [...this.templates.values()].map((t) => ({ id: t.id, name: t.name }));
246
+ }
247
+ suggest(prefix, templateId, limit = 10) {
248
+ const t = this.templates.get(templateId);
249
+ if (!t) return [];
250
+ const p = normalizeKey(t, prefix);
251
+ const out = [];
252
+ for (const sc of t.shortcuts) {
253
+ const k = normalizeKey(t, sc.key);
254
+ if (k.startsWith(p)) {
255
+ const item = { key: sc.key };
256
+ if (sc.label !== void 0) item.label = sc.label;
257
+ if (sc.description !== void 0) item.description = sc.description;
258
+ out.push(item);
259
+ if (out.length >= limit) break;
260
+ }
261
+ }
262
+ return out;
263
+ }
264
+ build(alias, value, opts) {
265
+ const t = this.templates.get(opts.templateId);
266
+ const m = this.lookup.get(opts.templateId);
267
+ if (!t || !m) return `${alias}:${value}`;
268
+ const key = normalizeKey(t, alias);
269
+ const sc = m.get(key);
270
+ if (!sc) return `${alias}:${value}`;
271
+ const v = maybeWrapValue(value, opts.wrapBareValues ?? true);
272
+ if (sc.kind === "field" && sc.field) return `${sc.field}:${v}`;
273
+ if (sc.kind === "macro" && sc.macro) return sc.macro.replaceAll("{{value}}", v);
274
+ return `${alias}:${v}`;
275
+ }
276
+ expand(query, opts) {
277
+ const t = this.templates.get(opts.templateId);
278
+ const m = this.lookup.get(opts.templateId);
279
+ if (!t || !m) return query;
280
+ let i = 0;
281
+ let out = "";
282
+ while (i < query.length) {
283
+ if (!/[A-Za-z0-9_]/.test(query[i])) {
284
+ out += query[i];
285
+ i++;
286
+ continue;
287
+ }
288
+ let j = i;
289
+ while (j < query.length && /[A-Za-z0-9_]/.test(query[j])) j++;
290
+ const keyRaw = query.slice(i, j);
291
+ let k = j;
292
+ while (k < query.length && /\s/.test(query[k])) k++;
293
+ if (query[k] !== ":") {
294
+ out += query[i];
295
+ i++;
296
+ continue;
297
+ }
298
+ const keyNorm = normalizeKey(t, keyRaw);
299
+ const sc = m.get(keyNorm);
300
+ out += sc ? "" : query.slice(i, k + 1);
301
+ k++;
302
+ const [valueRaw, nextIdx] = readValue(query, k);
303
+ const valueNorm = maybeWrapValue(valueRaw, opts.wrapBareValues ?? true);
304
+ if (!sc) out += valueRaw;
305
+ else if (sc.kind === "field" && sc.field) out += `${sc.field}:${valueNorm}`;
306
+ else if (sc.kind === "macro" && sc.macro) out += sc.macro.replaceAll("{{value}}", valueNorm);
307
+ else out += `${keyRaw}:${valueNorm}`;
308
+ i = nextIdx;
309
+ }
310
+ return out;
311
+ }
312
+ /**
313
+ * NEW: Autocomplete shortcuts.
314
+ * Given current text and cursor position, return completion items like:
315
+ * - label: "TAC:()"
316
+ * - insertText: "TAC:()"
317
+ * - newCursor: places cursor inside ()
318
+ */
319
+ complete(text, cursor, opts) {
320
+ const t = this.templates.get(opts.templateId);
321
+ if (!t) return [];
322
+ if (cursor > 0 && text[cursor - 1] === ":") return [];
323
+ const { start, end, prefix } = getTokenRange(text, cursor);
324
+ if (!prefix) return [];
325
+ const suggestions = this.suggest(prefix, opts.templateId, opts.limit ?? 10);
326
+ const items = [];
327
+ for (const s of suggestions) {
328
+ const sc = t.shortcuts.find((x) => normalizeKey(t, x.key) === normalizeKey(t, s.key));
329
+ const rawSnippet = sc?.snippet ?? `${s.key}:(|)`;
330
+ const { insertText, cursorIndex } = renderSnippet(rawSnippet);
331
+ const replaceFrom = start;
332
+ const replaceTo = end;
333
+ const newTextLengthDelta = insertText.length - (replaceTo - replaceFrom);
334
+ const newCursor = replaceFrom + cursorIndex;
335
+ const desc = sc?.description;
336
+ const item = {
337
+ key: s.key,
338
+ label: insertText,
339
+ replaceFrom,
340
+ replaceTo,
341
+ insertText,
342
+ newCursor
343
+ };
344
+ if (desc !== void 0) item.description = desc;
345
+ items.push(item);
346
+ void newTextLengthDelta;
347
+ }
348
+ return items;
349
+ }
350
+ /**
351
+ * NEW: Apply a chosen completion to (text, cursor) and return updated (text, cursor).
352
+ * UI can then call input.setSelectionRange(cursor, cursor).
353
+ */
354
+ applyCompletion(text, item) {
355
+ const next = text.slice(0, item.replaceFrom) + item.insertText + text.slice(item.replaceTo);
356
+ return { text: next, cursor: item.newCursor };
357
+ }
358
+ };
359
+ function createRegistry(templates) {
360
+ return new ShortcutRegistry(templates);
361
+ }
362
+ // Annotate the CommonJS export names for ESM import in node:
363
+ 0 && (module.exports = {
364
+ ShortcutRegistry,
365
+ createRegistry,
366
+ patsnapTemplate
367
+ });
368
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/templates/patsnap.ts"],"sourcesContent":["// src/index.ts\n\nexport type ShortcutKind = \"field\" | \"macro\";\n\nexport type Suggestion = {\n key: string;\n label?: string;\n description?: string;\n};\n\nexport type Shortcut = {\n key: string; // what user types, e.g. \"TAC\"\n kind: ShortcutKind; // \"field\" or \"macro\"\n field?: string; // if kind=\"field\": actual field, e.g. \"TAC_ALL\"\n macro?: string; // if kind=\"macro\": string with {{value}} placeholder\n label?: string;\n description?: string;\n aliases?: string[];\n\n /**\n * Optional autocomplete snippet.\n * Use `|` to mark cursor position after insertion.\n * Example: \"TAC:(|)\" -> inserts \"TAC:()\" and cursor is inside parentheses.\n *\n * If omitted, defaults to `${key}:(|)`.\n */\n snippet?: string;\n};\n\nexport type Template = {\n id: string;\n name: string;\n shortcuts: Shortcut[];\n normalizeKey?: \"upper\" | \"none\";\n};\n\nexport type ExpandOptions = {\n templateId: string;\n wrapBareValues?: boolean;\n};\n\n/**\n * Completion item returned by registry.complete().\n * - replaceFrom/replaceTo tells UI what range to replace\n * - insertText is what to insert\n * - newCursor is absolute cursor position in the final string\n */\nexport type CompletionItem = {\n key: string; // \"TAC\"\n label: string; // what you show in dropdown (e.g. \"TAC:()\")\n description?: string;\n\n replaceFrom: number;\n replaceTo: number;\n\n insertText: string; // e.g. \"TAC:()\"\n newCursor: number; // absolute cursor pos in final string\n};\n\nfunction normalizeKey(t: Template, key: string): string {\n return t.normalizeKey === \"upper\" ? key.toUpperCase() : key;\n}\n\nfunction isBareValue(v: string): boolean {\n const s = v.trim();\n return !(s.startsWith(\"(\") || s.startsWith(\"[\") || s.startsWith(\"\\\"\"));\n}\n\nfunction maybeWrapValue(v: string, wrapBareValues: boolean): string {\n const s = v.trim();\n if (!wrapBareValues) return s;\n if (!isBareValue(s)) return s;\n return `(${s})`;\n}\n\n// Reads a value after \":\" supporting (), [], \"\" and bare tokens.\n// Returns [value, nextIndex]\nfunction readValue(input: string, start: number): [string, number] {\n let i = start;\n while (i < input.length && /\\s/.test(input[i]!)) i++;\n\n const ch = input[i];\n if (!ch) return [\"\", i];\n\n const readBalanced = (open: string, close: string): [string, number] => {\n let depth = 0;\n let j = i;\n while (j < input.length) {\n const c = input[j]!;\n if (c === open) depth++;\n else if (c === close) {\n depth--;\n if (depth === 0) {\n j++;\n return [input.slice(i, j), j];\n }\n } else if (c === \"\\\"\") {\n j++;\n while (j < input.length) {\n if (input[j] === \"\\\\\" && j + 1 < input.length) { j += 2; continue; }\n if (input[j] === \"\\\"\") { j++; break; }\n j++;\n }\n continue;\n }\n j++;\n }\n return [input.slice(i), input.length];\n };\n\n if (ch === \"(\") return readBalanced(\"(\", \")\");\n if (ch === \"[\") return readBalanced(\"[\", \"]\");\n\n if (ch === \"\\\"\") {\n let j = i + 1;\n while (j < input.length) {\n if (input[j] === \"\\\\\" && j + 1 < input.length) { j += 2; continue; }\n if (input[j] === \"\\\"\") { j++; break; }\n j++;\n }\n return [input.slice(i, j), j];\n }\n\n let j = i;\n while (j < input.length && !/\\s/.test(input[j]!)) j++;\n return [input.slice(i, j), j];\n}\n\n/**\n * Find the \"word\" under/left of cursor for shortcut completion.\n * We treat a shortcut token as [A-Za-z0-9_]+\n */\nfunction getTokenRange(text: string, cursor: number): { start: number; end: number; prefix: string } {\n const isWord = (c: string) => /[A-Za-z0-9_]/.test(c);\n\n let start = Math.max(0, cursor);\n while (start > 0 && isWord(text[start - 1]!)) start--;\n\n let end = Math.max(0, cursor);\n while (end < text.length && isWord(text[end]!)) end++;\n\n const prefix = text.slice(start, cursor);\n return { start, end, prefix };\n}\n\n/**\n * Convert snippet with `|` cursor marker into (insertText, cursorIndexInInsertText)\n */\nfunction renderSnippet(snippet: string): { insertText: string; cursorIndex: number } {\n const idx = snippet.indexOf(\"|\");\n if (idx === -1) return { insertText: snippet, cursorIndex: snippet.length };\n const insertText = snippet.replace(\"|\", \"\");\n return { insertText, cursorIndex: idx };\n}\n\nexport class ShortcutRegistry {\n private templates = new Map<string, Template>();\n private lookup = new Map<string, Map<string, Shortcut>>();\n\n constructor(templates: Template[]) {\n for (const t of templates) this.registerTemplate(t);\n }\n\n registerTemplate(t: Template) {\n this.templates.set(t.id, t);\n\n const map = new Map<string, Shortcut>();\n for (const sc of t.shortcuts) {\n map.set(normalizeKey(t, sc.key), sc);\n for (const a of sc.aliases ?? []) map.set(normalizeKey(t, a), sc);\n }\n this.lookup.set(t.id, map);\n }\n\n listTemplates(): { id: string; name: string }[] {\n return [...this.templates.values()].map(t => ({ id: t.id, name: t.name }));\n }\n\n suggest(prefix: string, templateId: string, limit = 10): Suggestion[] {\n const t = this.templates.get(templateId);\n if (!t) return [];\n\n const p = normalizeKey(t, prefix);\n const out: Suggestion[] = [];\n\n for (const sc of t.shortcuts) {\n const k = normalizeKey(t, sc.key);\n if (k.startsWith(p)) {\n const item: Suggestion = { key: sc.key };\n if (sc.label !== undefined) item.label = sc.label;\n if (sc.description !== undefined) item.description = sc.description;\n out.push(item);\n\n if (out.length >= limit) break;\n }\n }\n return out;\n }\n\n build(alias: string, value: string, opts: ExpandOptions): string {\n const t = this.templates.get(opts.templateId);\n const m = this.lookup.get(opts.templateId);\n if (!t || !m) return `${alias}:${value}`;\n\n const key = normalizeKey(t, alias);\n const sc = m.get(key);\n if (!sc) return `${alias}:${value}`;\n\n const v = maybeWrapValue(value, opts.wrapBareValues ?? true);\n\n if (sc.kind === \"field\" && sc.field) return `${sc.field}:${v}`;\n if (sc.kind === \"macro\" && sc.macro) return sc.macro.replaceAll(\"{{value}}\", v);\n\n return `${alias}:${v}`;\n }\n\n expand(query: string, opts: ExpandOptions): string {\n const t = this.templates.get(opts.templateId);\n const m = this.lookup.get(opts.templateId);\n if (!t || !m) return query;\n\n let i = 0;\n let out = \"\";\n\n while (i < query.length) {\n if (!/[A-Za-z0-9_]/.test(query[i]!)) {\n out += query[i]!;\n i++;\n continue;\n }\n\n let j = i;\n while (j < query.length && /[A-Za-z0-9_]/.test(query[j]!)) j++;\n const keyRaw = query.slice(i, j);\n\n let k = j;\n while (k < query.length && /\\s/.test(query[k]!)) k++;\n\n if (query[k] !== \":\") {\n out += query[i]!;\n i++;\n continue;\n }\n\n const keyNorm = normalizeKey(t, keyRaw);\n const sc = m.get(keyNorm);\n\n out += sc ? \"\" : query.slice(i, k + 1);\n k++;\n\n const [valueRaw, nextIdx] = readValue(query, k);\n const valueNorm = maybeWrapValue(valueRaw, opts.wrapBareValues ?? true);\n\n if (!sc) out += valueRaw;\n else if (sc.kind === \"field\" && sc.field) out += `${sc.field}:${valueNorm}`;\n else if (sc.kind === \"macro\" && sc.macro) out += sc.macro.replaceAll(\"{{value}}\", valueNorm);\n else out += `${keyRaw}:${valueNorm}`;\n\n i = nextIdx;\n }\n\n return out;\n }\n\n /**\n * NEW: Autocomplete shortcuts.\n * Given current text and cursor position, return completion items like:\n * - label: \"TAC:()\"\n * - insertText: \"TAC:()\"\n * - newCursor: places cursor inside ()\n */\n complete(text: string, cursor: number, opts: { templateId: string; limit?: number }): CompletionItem[] {\n const t = this.templates.get(opts.templateId);\n if (!t) return [];\n\n // If cursor is right after \":\" (user is entering value), don't suggest shortcut keys\n if (cursor > 0 && text[cursor - 1] === \":\") return [];\n\n const { start, end, prefix } = getTokenRange(text, cursor);\n if (!prefix) return [];\n\n const suggestions = this.suggest(prefix, opts.templateId, opts.limit ?? 10);\n\n const items: CompletionItem[] = [];\n for (const s of suggestions) {\n // find shortcut object so we can use optional snippet/description\n const sc = t.shortcuts.find(x => normalizeKey(t, x.key) === normalizeKey(t, s.key));\n const rawSnippet = sc?.snippet ?? `${s.key}:(|)`;\n const { insertText, cursorIndex } = renderSnippet(rawSnippet);\n\n const replaceFrom = start;\n const replaceTo = end;\n\n const newTextLengthDelta = insertText.length - (replaceTo - replaceFrom);\n const newCursor = replaceFrom + cursorIndex;\n const desc = sc?.description;\n\n const item: CompletionItem = {\n key: s.key,\n label: insertText,\n replaceFrom,\n replaceTo,\n insertText,\n newCursor\n };\n\n if (desc !== undefined) item.description = desc;\n\n items.push(item);\n\n // NOTE: newTextLengthDelta isn't used here, because newCursor is absolute within the new string\n // by construction. Keep it if you later add multi-edit support.\n void newTextLengthDelta;\n }\n\n return items;\n }\n\n /**\n * NEW: Apply a chosen completion to (text, cursor) and return updated (text, cursor).\n * UI can then call input.setSelectionRange(cursor, cursor).\n */\n applyCompletion(text: string, item: CompletionItem): { text: string; cursor: number } {\n const next =\n text.slice(0, item.replaceFrom) +\n item.insertText +\n text.slice(item.replaceTo);\n\n return { text: next, cursor: item.newCursor };\n }\n}\n\nexport function createRegistry(templates: Template[]) {\n return new ShortcutRegistry(templates);\n}\n\nexport { patsnapTemplate } from \"./templates/patsnap.js\";\n","// src/templates/patsnap.ts\nimport type { Template } from \"../index.js\";\n\nexport const patsnapTemplate: Template = {\n id: \"patsnap\",\n name: \"Patsnap\",\n normalizeKey: \"upper\",\n shortcuts: [\n // --- Text fields (from your 1st screenshot) ---\n { key: \"TA\", kind: \"field\", field: \"TA_ALL\", label: \"Title + Abstract\", description: \"Search in title and abstract\", aliases: [\"TA_ALL\"] },\n { key: \"TTL\", kind: \"field\", field: \"TTL_ALL\", label: \"Title\", description: \"Search in title\", aliases: [\"TTL_ALL\"] },\n { key: \"TAC\", kind: \"field\", field: \"TAC_ALL\", label: \"Title+Abstract+Claims\", description: \"Search in title, abstract, and claims\", aliases: [\"TAC_ALL\"] },\n { key: \"TACD\", kind: \"field\", field: \"TACD_ALL\", label: \"Title+Abstract+Claims+Description\", description: \"Search in title/abstract/claims/description\", aliases: [\"TACD_ALL\"] },\n { key: \"ABST\", kind: \"field\", field: \"ABST_ALL\", label: \"Abstract\", description: \"Search in abstract\", aliases: [\"ABST_ALL\"] },\n { key: \"CLMS\", kind: \"field\", field: \"CLMS_ALL\", label: \"Claims\", description: \"Search in claims\", aliases: [\"CLMS_ALL\"] },\n { key: \"DESC\", kind: \"field\", field: \"DESC_ALL\", label: \"Description\", description: \"Search in description\", aliases: [\"DESC_ALL\"] },\n\n { key: \"DESC_F\", kind: \"field\", field: \"DESC_F\", label: \"Technical Field\", description: \"Description: technical field\" },\n { key: \"DESC_B\", kind: \"field\", field: \"DESC_B\", label: \"Background Art\", description: \"Description: background art\" },\n { key: \"DESC_S\", kind: \"field\", field: \"DESC_S\", label: \"Summary of Invention\", description: \"Description: summary\" },\n { key: \"DESC_D\", kind: \"field\", field: \"DESC_D\", label: \"Brief Description of Drawings\", description: \"Description: drawings\" },\n { key: \"DESC_E\", kind: \"field\", field: \"DESC_E\", label: \"Description of Embodiments\", description: \"Description: embodiments\" },\n\n { key: \"ICLMS\", kind: \"field\", field: \"ICLMS_ALL\", label: \"Independent Claims\", description: \"Search in independent claims\", aliases: [\"ICLMS_ALL\"] },\n { key: \"PROBLEM_SUM\", kind: \"field\", field: \"PROBLEM_SUM\", label: \"Technical Problem\", description: \"Problem summary\" },\n { key: \"METHOD_SUM\", kind: \"field\", field: \"METHOD_SUM\", label: \"Technical Method\", description: \"Method summary\" },\n { key: \"BENEFIT_SUM\", kind: \"field\", field: \"BENEFIT_SUM\", label: \"Technical Benefit\", description: \"Benefit summary\" },\n\n // --- Classification (2nd screenshot) ---\n { key: \"MCPC\", kind: \"field\", field: \"MCPC\", label: \"Main CPC\" },\n { key: \"CPC_SUB_GROUP\", kind: \"field\", field: \"CPC_SUB_GROUP\", label: \"CPC Sub Group\" },\n { key: \"IPC_CPC\", kind: \"field\", field: \"IPC_CPC\", label: \"IPC & CPC\" },\n { key: \"UPC\", kind: \"field\", field: \"UPC\", label: \"UPC\" },\n { key: \"LOC\", kind: \"field\", field: \"LOC\", label: \"LOC\" },\n { key: \"FI\", kind: \"field\", field: \"FI\", label: \"FI\" },\n { key: \"FTERM\", kind: \"field\", field: \"FTERM\", label: \"F-TERM\" },\n { key: \"ADC\", kind: \"field\", field: \"ADC\", label: \"Application Domain\" },\n { key: \"TTC\", kind: \"field\", field: \"TTC\", label: \"Technology Topic\" },\n { key: \"SEIC\", kind: \"field\", field: \"SEIC\", label: \"Main SEIC\" },\n { key: \"SEIC_ALL\", kind: \"field\", field: \"SEIC_ALL\", label: \"SEIC (All)\" },\n { key: \"GBC\", kind: \"field\", field: \"GBC\", label: \"GBC\" },\n\n // --- Assignees / Inventors (3rd screenshot) ---\n { key: \"ALL_AN\", kind: \"field\", field: \"ALL_AN\", label: \"All Assignees\" },\n { key: \"ANCS\", kind: \"field\", field: \"ANCS\", label: \"Std. Current Assignee\" },\n { key: \"ANC\", kind: \"field\", field: \"ANC\", label: \"Current Assignee\" },\n { key: \"GNAME\", kind: \"field\", field: \"GNAME\", label: \"Grouped Assignee\" },\n { key: \"ANS\", kind: \"field\", field: \"ANS\", label: \"Std. Original Assignee\" },\n { key: \"AN\", kind: \"field\", field: \"AN\", label: \"Original Assignee\" },\n { key: \"F_AN\", kind: \"field\", field: \"F_AN\", label: \"First Original Assignee\" },\n { key: \"F_ANC\", kind: \"field\", field: \"F_ANC\", label: \"First Current Assignee\" },\n { key: \"IN\", kind: \"field\", field: \"IN\", label: \"Inventor Name\" },\n { key: \"F_IN\", kind: \"field\", field: \"F_IN\", label: \"First Inventor\" },\n { key: \"ATC\", kind: \"field\", field: \"ATC\", label: \"Agency\" },\n { key: \"ATCS\", kind: \"field\", field: \"ATCS\", label: \"Std. Agency\" },\n { key: \"AT\", kind: \"field\", field: \"AT\", label: \"Attorney Name\" },\n { key: \"PE\", kind: \"field\", field: \"PE\", label: \"Primary Examiner\" },\n { key: \"AE\", kind: \"field\", field: \"AE\", label: \"Assistant Examiner\" },\n\n // --- Dates (4th screenshot) ---\n { key: \"APD\", kind: \"field\", field: \"APD\", label: \"Application Date\" },\n { key: \"PBD\", kind: \"field\", field: \"PBD\", label: \"Publication Date\" },\n { key: \"PRIORITY_DATE\", kind: \"field\", field: \"PRIORITY_DATE\", label: \"Priority Date\" },\n { key: \"EXDT\", kind: \"field\", field: \"EXDT\", label: \"Estimated Expiry Date\" },\n { key: \"ISD\", kind: \"field\", field: \"ISD\", label: \"Issue Date\" },\n { key: \"EXPD\", kind: \"field\", field: \"EXPD\", label: \"Expiry Date\" },\n { key: \"EXAMINE_DATE\", kind: \"field\", field: \"EXAMINE_DATE\", label: \"Substantive Examination Date\" },\n { key: \"PCTENTRY_DATE\", kind: \"field\", field: \"PCTENTRY_DATE\", label: \"PCT Entry Date\" },\n { key: \"LEGAL_STATUS_DATE\", kind: \"field\", field: \"LEGAL_STATUS_DATE\", label: \"Legal Status Date\" },\n\n // --- Numbers (5th screenshot) ---\n { key: \"PN\", kind: \"field\", field: \"PN\", label: \"Publication Number\" },\n { key: \"APNO\", kind: \"field\", field: \"APNO\", label: \"Application Number\" },\n { key: \"PRNO\", kind: \"field\", field: \"PRNO\", label: \"Priority Number\" },\n { key: \"KD\", kind: \"field\", field: \"KD\", label: \"Kind Code\" },\n { key: \"PCT_APNO\", kind: \"field\", field: \"PCT_APNO\", label: \"PCT Application Number\" },\n { key: \"PCT_PN\", kind: \"field\", field: \"PCT_PN\", label: \"PCT Publication Number\" },\n\n // --- Addresses / Regions (6th screenshot) ---\n { key: \"AN_ADD\", kind: \"field\", field: \"AN_ADD\", label: \"Original Assignee Address\" },\n { key: \"ANC_ADD\", kind: \"field\", field: \"ANC_ADD\", label: \"Current Assignee Address\" },\n { key: \"IN_ADDRESS\", kind: \"field\", field: \"IN_ADDRESS\", label: \"Inventor Address\" },\n { key: \"PRIORITY_COUNTRY\", kind: \"field\", field: \"PRIORITY_COUNTRY\", label: \"Priority Country/Region\" },\n { key: \"AUTHORITY\", kind: \"field\", field: \"AUTHORITY\", label: \"Authority\" },\n { key: \"EPDS\", kind: \"field\", field: \"EPDS\", label: \"EP Designated State\" },\n { key: \"ENTRY_COUNTRY\", kind: \"field\", field: \"ENTRY_COUNTRY\", label: \"Entry Country/Region\" },\n\n // --- Citations / Family (7th screenshot) ---\n { key: \"B_CITES\", kind: \"field\", field: \"B_CITES\", label: \"Backward Citations\" },\n { key: \"F_CITES\", kind: \"field\", field: \"F_CITES\", label: \"Forward Citations\" },\n { key: \"BF_CITES\", kind: \"field\", field: \"BF_CITES\", label: \"Backward Or Forward Citations\" },\n { key: \"B_CITES_COUNT\", kind: \"field\", field: \"B_CITES_COUNT\", label: \"Count Of Backward Citations\" },\n { key: \"F_CITES_COUNT\", kind: \"field\", field: \"F_CITES_COUNT\", label: \"Count Of Forward Citations\" },\n { key: \"F_CITES_ANC\", kind: \"field\", field: \"F_CITES_ANC\", label: \"Assignee Forward Citations (Current)\" },\n { key: \"B_CITES_ANC\", kind: \"field\", field: \"B_CITES_ANC\", label: \"Assignee Backward Citations (Current)\" },\n { key: \"CITE_CATEGORY\", kind: \"field\", field: \"CITE_CATEGORY\", label: \"Citation/Rejection Category\" },\n { key: \"FAM\", kind: \"field\", field: \"FAM\", label: \"Simple Family\" },\n { key: \"EFAM\", kind: \"field\", field: \"EFAM\", label: \"PatSnap Family\" },\n { key: \"FAM_COUNT\", kind: \"field\", field: \"FAM_COUNT\", label: \"Simple Family Application Count\" },\n { key: \"IFAM_COUNT\", kind: \"field\", field: \"IFAM_COUNT\", label: \"INPADOC Family Application Count\" },\n { key: \"EFAM_COUNT\", kind: \"field\", field: \"EFAM_COUNT\", label: \"PatSnap Family Application Count\" },\n { key: \"FAM_COUNTRY_COUNT\", kind: \"field\", field: \"FAM_COUNTRY_COUNT\", label: \"Simple Family Jurisdiction Count\" },\n { key: \"IFAM_COUNTRY_COUNT\", kind: \"field\", field: \"IFAM_COUNTRY_COUNT\", label: \"INPADOC Family Jurisdiction Count\" },\n { key: \"EFAM_COUNTRY_COUNT\", kind: \"field\", field: \"EFAM_COUNTRY_COUNT\", label: \"PatSnap Family Jurisdiction Count\" },\n\n // --- Legal status / metrics (8th screenshot) ---\n { key: \"LEGAL_STATUS\", kind: \"field\", field: \"LEGAL_STATUS\", label: \"Legal Status\" },\n { key: \"LEGAL_EVENT\", kind: \"field\", field: \"LEGAL_EVENT\", label: \"Legal Event\" },\n { key: \"SIMPLE_LEGAL_STATUS\", kind: \"field\", field: \"SIMPLE_LEGAL_STATUS\", label: \"Simple Legal Status\" },\n { key: \"UP_STATUS\", kind: \"field\", field: \"UP_STATUS\", label: \"Status of Unified Patent Court\" },\n { key: \"ENTRY_COUNTRY_LS\", kind: \"field\", field: \"ENTRY_COUNTRY_LS\", label: \"Legal Status of Entry Country/Region\" },\n { key: \"ENTRY_COUNTRY_SLS\", kind: \"field\", field: \"ENTRY_COUNTRY_SLS\", label: \"Simple Legal Status of Entry Country/Region\" },\n { key: \"PV\", kind: \"field\", field: \"PV\", label: \"Patent Value\" },\n { key: \"PAGE_COUNT\", kind: \"field\", field: \"PAGE_COUNT\", label: \"Page Count\" },\n { key: \"CLAIM_COUNT\", kind: \"field\", field: \"CLAIM_COUNT\", label: \"Claim Count\" },\n { key: \"FCLMS_WORDCOUNT\", kind: \"field\", field: \"FCLMS_WORDCOUNT\", label: \"Word count of first claim\" },\n { key: \"AN_COUNT\", kind: \"field\", field: \"AN_COUNT\", label: \"Count of Original Assignees\" },\n { key: \"ANC_COUNT\", kind: \"field\", field: \"ANC_COUNT\", label: \"Count of Current Assignees\" },\n { key: \"IN_COUNT\", kind: \"field\", field: \"IN_COUNT\", label: \"Count of Inventors\" },\n { key: \"GOV\", kind: \"field\", field: \"GOV\", label: \"Government Interest\" }\n ]\n};\n"],"mappings":"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","names":["j"]}
@@ -0,0 +1,85 @@
1
+ declare const patsnapTemplate: Template;
2
+
3
+ type ShortcutKind = "field" | "macro";
4
+ type Suggestion = {
5
+ key: string;
6
+ label?: string;
7
+ description?: string;
8
+ };
9
+ type Shortcut = {
10
+ key: string;
11
+ kind: ShortcutKind;
12
+ field?: string;
13
+ macro?: string;
14
+ label?: string;
15
+ description?: string;
16
+ aliases?: string[];
17
+ /**
18
+ * Optional autocomplete snippet.
19
+ * Use `|` to mark cursor position after insertion.
20
+ * Example: "TAC:(|)" -> inserts "TAC:()" and cursor is inside parentheses.
21
+ *
22
+ * If omitted, defaults to `${key}:(|)`.
23
+ */
24
+ snippet?: string;
25
+ };
26
+ type Template = {
27
+ id: string;
28
+ name: string;
29
+ shortcuts: Shortcut[];
30
+ normalizeKey?: "upper" | "none";
31
+ };
32
+ type ExpandOptions = {
33
+ templateId: string;
34
+ wrapBareValues?: boolean;
35
+ };
36
+ /**
37
+ * Completion item returned by registry.complete().
38
+ * - replaceFrom/replaceTo tells UI what range to replace
39
+ * - insertText is what to insert
40
+ * - newCursor is absolute cursor position in the final string
41
+ */
42
+ type CompletionItem = {
43
+ key: string;
44
+ label: string;
45
+ description?: string;
46
+ replaceFrom: number;
47
+ replaceTo: number;
48
+ insertText: string;
49
+ newCursor: number;
50
+ };
51
+ declare class ShortcutRegistry {
52
+ private templates;
53
+ private lookup;
54
+ constructor(templates: Template[]);
55
+ registerTemplate(t: Template): void;
56
+ listTemplates(): {
57
+ id: string;
58
+ name: string;
59
+ }[];
60
+ suggest(prefix: string, templateId: string, limit?: number): Suggestion[];
61
+ build(alias: string, value: string, opts: ExpandOptions): string;
62
+ expand(query: string, opts: ExpandOptions): string;
63
+ /**
64
+ * NEW: Autocomplete shortcuts.
65
+ * Given current text and cursor position, return completion items like:
66
+ * - label: "TAC:()"
67
+ * - insertText: "TAC:()"
68
+ * - newCursor: places cursor inside ()
69
+ */
70
+ complete(text: string, cursor: number, opts: {
71
+ templateId: string;
72
+ limit?: number;
73
+ }): CompletionItem[];
74
+ /**
75
+ * NEW: Apply a chosen completion to (text, cursor) and return updated (text, cursor).
76
+ * UI can then call input.setSelectionRange(cursor, cursor).
77
+ */
78
+ applyCompletion(text: string, item: CompletionItem): {
79
+ text: string;
80
+ cursor: number;
81
+ };
82
+ }
83
+ declare function createRegistry(templates: Template[]): ShortcutRegistry;
84
+
85
+ export { type CompletionItem, type ExpandOptions, type Shortcut, type ShortcutKind, ShortcutRegistry, type Suggestion, type Template, createRegistry, patsnapTemplate };
@@ -0,0 +1,85 @@
1
+ declare const patsnapTemplate: Template;
2
+
3
+ type ShortcutKind = "field" | "macro";
4
+ type Suggestion = {
5
+ key: string;
6
+ label?: string;
7
+ description?: string;
8
+ };
9
+ type Shortcut = {
10
+ key: string;
11
+ kind: ShortcutKind;
12
+ field?: string;
13
+ macro?: string;
14
+ label?: string;
15
+ description?: string;
16
+ aliases?: string[];
17
+ /**
18
+ * Optional autocomplete snippet.
19
+ * Use `|` to mark cursor position after insertion.
20
+ * Example: "TAC:(|)" -> inserts "TAC:()" and cursor is inside parentheses.
21
+ *
22
+ * If omitted, defaults to `${key}:(|)`.
23
+ */
24
+ snippet?: string;
25
+ };
26
+ type Template = {
27
+ id: string;
28
+ name: string;
29
+ shortcuts: Shortcut[];
30
+ normalizeKey?: "upper" | "none";
31
+ };
32
+ type ExpandOptions = {
33
+ templateId: string;
34
+ wrapBareValues?: boolean;
35
+ };
36
+ /**
37
+ * Completion item returned by registry.complete().
38
+ * - replaceFrom/replaceTo tells UI what range to replace
39
+ * - insertText is what to insert
40
+ * - newCursor is absolute cursor position in the final string
41
+ */
42
+ type CompletionItem = {
43
+ key: string;
44
+ label: string;
45
+ description?: string;
46
+ replaceFrom: number;
47
+ replaceTo: number;
48
+ insertText: string;
49
+ newCursor: number;
50
+ };
51
+ declare class ShortcutRegistry {
52
+ private templates;
53
+ private lookup;
54
+ constructor(templates: Template[]);
55
+ registerTemplate(t: Template): void;
56
+ listTemplates(): {
57
+ id: string;
58
+ name: string;
59
+ }[];
60
+ suggest(prefix: string, templateId: string, limit?: number): Suggestion[];
61
+ build(alias: string, value: string, opts: ExpandOptions): string;
62
+ expand(query: string, opts: ExpandOptions): string;
63
+ /**
64
+ * NEW: Autocomplete shortcuts.
65
+ * Given current text and cursor position, return completion items like:
66
+ * - label: "TAC:()"
67
+ * - insertText: "TAC:()"
68
+ * - newCursor: places cursor inside ()
69
+ */
70
+ complete(text: string, cursor: number, opts: {
71
+ templateId: string;
72
+ limit?: number;
73
+ }): CompletionItem[];
74
+ /**
75
+ * NEW: Apply a chosen completion to (text, cursor) and return updated (text, cursor).
76
+ * UI can then call input.setSelectionRange(cursor, cursor).
77
+ */
78
+ applyCompletion(text: string, item: CompletionItem): {
79
+ text: string;
80
+ cursor: number;
81
+ };
82
+ }
83
+ declare function createRegistry(templates: Template[]): ShortcutRegistry;
84
+
85
+ export { type CompletionItem, type ExpandOptions, type Shortcut, type ShortcutKind, ShortcutRegistry, type Suggestion, type Template, createRegistry, patsnapTemplate };
package/dist/index.js ADDED
@@ -0,0 +1,341 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/templates/patsnap.ts
6
+ var patsnapTemplate = {
7
+ id: "patsnap",
8
+ name: "Patsnap",
9
+ normalizeKey: "upper",
10
+ shortcuts: [
11
+ // --- Text fields (from your 1st screenshot) ---
12
+ { key: "TA", kind: "field", field: "TA_ALL", label: "Title + Abstract", description: "Search in title and abstract", aliases: ["TA_ALL"] },
13
+ { key: "TTL", kind: "field", field: "TTL_ALL", label: "Title", description: "Search in title", aliases: ["TTL_ALL"] },
14
+ { key: "TAC", kind: "field", field: "TAC_ALL", label: "Title+Abstract+Claims", description: "Search in title, abstract, and claims", aliases: ["TAC_ALL"] },
15
+ { key: "TACD", kind: "field", field: "TACD_ALL", label: "Title+Abstract+Claims+Description", description: "Search in title/abstract/claims/description", aliases: ["TACD_ALL"] },
16
+ { key: "ABST", kind: "field", field: "ABST_ALL", label: "Abstract", description: "Search in abstract", aliases: ["ABST_ALL"] },
17
+ { key: "CLMS", kind: "field", field: "CLMS_ALL", label: "Claims", description: "Search in claims", aliases: ["CLMS_ALL"] },
18
+ { key: "DESC", kind: "field", field: "DESC_ALL", label: "Description", description: "Search in description", aliases: ["DESC_ALL"] },
19
+ { key: "DESC_F", kind: "field", field: "DESC_F", label: "Technical Field", description: "Description: technical field" },
20
+ { key: "DESC_B", kind: "field", field: "DESC_B", label: "Background Art", description: "Description: background art" },
21
+ { key: "DESC_S", kind: "field", field: "DESC_S", label: "Summary of Invention", description: "Description: summary" },
22
+ { key: "DESC_D", kind: "field", field: "DESC_D", label: "Brief Description of Drawings", description: "Description: drawings" },
23
+ { key: "DESC_E", kind: "field", field: "DESC_E", label: "Description of Embodiments", description: "Description: embodiments" },
24
+ { key: "ICLMS", kind: "field", field: "ICLMS_ALL", label: "Independent Claims", description: "Search in independent claims", aliases: ["ICLMS_ALL"] },
25
+ { key: "PROBLEM_SUM", kind: "field", field: "PROBLEM_SUM", label: "Technical Problem", description: "Problem summary" },
26
+ { key: "METHOD_SUM", kind: "field", field: "METHOD_SUM", label: "Technical Method", description: "Method summary" },
27
+ { key: "BENEFIT_SUM", kind: "field", field: "BENEFIT_SUM", label: "Technical Benefit", description: "Benefit summary" },
28
+ // --- Classification (2nd screenshot) ---
29
+ { key: "MCPC", kind: "field", field: "MCPC", label: "Main CPC" },
30
+ { key: "CPC_SUB_GROUP", kind: "field", field: "CPC_SUB_GROUP", label: "CPC Sub Group" },
31
+ { key: "IPC_CPC", kind: "field", field: "IPC_CPC", label: "IPC & CPC" },
32
+ { key: "UPC", kind: "field", field: "UPC", label: "UPC" },
33
+ { key: "LOC", kind: "field", field: "LOC", label: "LOC" },
34
+ { key: "FI", kind: "field", field: "FI", label: "FI" },
35
+ { key: "FTERM", kind: "field", field: "FTERM", label: "F-TERM" },
36
+ { key: "ADC", kind: "field", field: "ADC", label: "Application Domain" },
37
+ { key: "TTC", kind: "field", field: "TTC", label: "Technology Topic" },
38
+ { key: "SEIC", kind: "field", field: "SEIC", label: "Main SEIC" },
39
+ { key: "SEIC_ALL", kind: "field", field: "SEIC_ALL", label: "SEIC (All)" },
40
+ { key: "GBC", kind: "field", field: "GBC", label: "GBC" },
41
+ // --- Assignees / Inventors (3rd screenshot) ---
42
+ { key: "ALL_AN", kind: "field", field: "ALL_AN", label: "All Assignees" },
43
+ { key: "ANCS", kind: "field", field: "ANCS", label: "Std. Current Assignee" },
44
+ { key: "ANC", kind: "field", field: "ANC", label: "Current Assignee" },
45
+ { key: "GNAME", kind: "field", field: "GNAME", label: "Grouped Assignee" },
46
+ { key: "ANS", kind: "field", field: "ANS", label: "Std. Original Assignee" },
47
+ { key: "AN", kind: "field", field: "AN", label: "Original Assignee" },
48
+ { key: "F_AN", kind: "field", field: "F_AN", label: "First Original Assignee" },
49
+ { key: "F_ANC", kind: "field", field: "F_ANC", label: "First Current Assignee" },
50
+ { key: "IN", kind: "field", field: "IN", label: "Inventor Name" },
51
+ { key: "F_IN", kind: "field", field: "F_IN", label: "First Inventor" },
52
+ { key: "ATC", kind: "field", field: "ATC", label: "Agency" },
53
+ { key: "ATCS", kind: "field", field: "ATCS", label: "Std. Agency" },
54
+ { key: "AT", kind: "field", field: "AT", label: "Attorney Name" },
55
+ { key: "PE", kind: "field", field: "PE", label: "Primary Examiner" },
56
+ { key: "AE", kind: "field", field: "AE", label: "Assistant Examiner" },
57
+ // --- Dates (4th screenshot) ---
58
+ { key: "APD", kind: "field", field: "APD", label: "Application Date" },
59
+ { key: "PBD", kind: "field", field: "PBD", label: "Publication Date" },
60
+ { key: "PRIORITY_DATE", kind: "field", field: "PRIORITY_DATE", label: "Priority Date" },
61
+ { key: "EXDT", kind: "field", field: "EXDT", label: "Estimated Expiry Date" },
62
+ { key: "ISD", kind: "field", field: "ISD", label: "Issue Date" },
63
+ { key: "EXPD", kind: "field", field: "EXPD", label: "Expiry Date" },
64
+ { key: "EXAMINE_DATE", kind: "field", field: "EXAMINE_DATE", label: "Substantive Examination Date" },
65
+ { key: "PCTENTRY_DATE", kind: "field", field: "PCTENTRY_DATE", label: "PCT Entry Date" },
66
+ { key: "LEGAL_STATUS_DATE", kind: "field", field: "LEGAL_STATUS_DATE", label: "Legal Status Date" },
67
+ // --- Numbers (5th screenshot) ---
68
+ { key: "PN", kind: "field", field: "PN", label: "Publication Number" },
69
+ { key: "APNO", kind: "field", field: "APNO", label: "Application Number" },
70
+ { key: "PRNO", kind: "field", field: "PRNO", label: "Priority Number" },
71
+ { key: "KD", kind: "field", field: "KD", label: "Kind Code" },
72
+ { key: "PCT_APNO", kind: "field", field: "PCT_APNO", label: "PCT Application Number" },
73
+ { key: "PCT_PN", kind: "field", field: "PCT_PN", label: "PCT Publication Number" },
74
+ // --- Addresses / Regions (6th screenshot) ---
75
+ { key: "AN_ADD", kind: "field", field: "AN_ADD", label: "Original Assignee Address" },
76
+ { key: "ANC_ADD", kind: "field", field: "ANC_ADD", label: "Current Assignee Address" },
77
+ { key: "IN_ADDRESS", kind: "field", field: "IN_ADDRESS", label: "Inventor Address" },
78
+ { key: "PRIORITY_COUNTRY", kind: "field", field: "PRIORITY_COUNTRY", label: "Priority Country/Region" },
79
+ { key: "AUTHORITY", kind: "field", field: "AUTHORITY", label: "Authority" },
80
+ { key: "EPDS", kind: "field", field: "EPDS", label: "EP Designated State" },
81
+ { key: "ENTRY_COUNTRY", kind: "field", field: "ENTRY_COUNTRY", label: "Entry Country/Region" },
82
+ // --- Citations / Family (7th screenshot) ---
83
+ { key: "B_CITES", kind: "field", field: "B_CITES", label: "Backward Citations" },
84
+ { key: "F_CITES", kind: "field", field: "F_CITES", label: "Forward Citations" },
85
+ { key: "BF_CITES", kind: "field", field: "BF_CITES", label: "Backward Or Forward Citations" },
86
+ { key: "B_CITES_COUNT", kind: "field", field: "B_CITES_COUNT", label: "Count Of Backward Citations" },
87
+ { key: "F_CITES_COUNT", kind: "field", field: "F_CITES_COUNT", label: "Count Of Forward Citations" },
88
+ { key: "F_CITES_ANC", kind: "field", field: "F_CITES_ANC", label: "Assignee Forward Citations (Current)" },
89
+ { key: "B_CITES_ANC", kind: "field", field: "B_CITES_ANC", label: "Assignee Backward Citations (Current)" },
90
+ { key: "CITE_CATEGORY", kind: "field", field: "CITE_CATEGORY", label: "Citation/Rejection Category" },
91
+ { key: "FAM", kind: "field", field: "FAM", label: "Simple Family" },
92
+ { key: "EFAM", kind: "field", field: "EFAM", label: "PatSnap Family" },
93
+ { key: "FAM_COUNT", kind: "field", field: "FAM_COUNT", label: "Simple Family Application Count" },
94
+ { key: "IFAM_COUNT", kind: "field", field: "IFAM_COUNT", label: "INPADOC Family Application Count" },
95
+ { key: "EFAM_COUNT", kind: "field", field: "EFAM_COUNT", label: "PatSnap Family Application Count" },
96
+ { key: "FAM_COUNTRY_COUNT", kind: "field", field: "FAM_COUNTRY_COUNT", label: "Simple Family Jurisdiction Count" },
97
+ { key: "IFAM_COUNTRY_COUNT", kind: "field", field: "IFAM_COUNTRY_COUNT", label: "INPADOC Family Jurisdiction Count" },
98
+ { key: "EFAM_COUNTRY_COUNT", kind: "field", field: "EFAM_COUNTRY_COUNT", label: "PatSnap Family Jurisdiction Count" },
99
+ // --- Legal status / metrics (8th screenshot) ---
100
+ { key: "LEGAL_STATUS", kind: "field", field: "LEGAL_STATUS", label: "Legal Status" },
101
+ { key: "LEGAL_EVENT", kind: "field", field: "LEGAL_EVENT", label: "Legal Event" },
102
+ { key: "SIMPLE_LEGAL_STATUS", kind: "field", field: "SIMPLE_LEGAL_STATUS", label: "Simple Legal Status" },
103
+ { key: "UP_STATUS", kind: "field", field: "UP_STATUS", label: "Status of Unified Patent Court" },
104
+ { key: "ENTRY_COUNTRY_LS", kind: "field", field: "ENTRY_COUNTRY_LS", label: "Legal Status of Entry Country/Region" },
105
+ { key: "ENTRY_COUNTRY_SLS", kind: "field", field: "ENTRY_COUNTRY_SLS", label: "Simple Legal Status of Entry Country/Region" },
106
+ { key: "PV", kind: "field", field: "PV", label: "Patent Value" },
107
+ { key: "PAGE_COUNT", kind: "field", field: "PAGE_COUNT", label: "Page Count" },
108
+ { key: "CLAIM_COUNT", kind: "field", field: "CLAIM_COUNT", label: "Claim Count" },
109
+ { key: "FCLMS_WORDCOUNT", kind: "field", field: "FCLMS_WORDCOUNT", label: "Word count of first claim" },
110
+ { key: "AN_COUNT", kind: "field", field: "AN_COUNT", label: "Count of Original Assignees" },
111
+ { key: "ANC_COUNT", kind: "field", field: "ANC_COUNT", label: "Count of Current Assignees" },
112
+ { key: "IN_COUNT", kind: "field", field: "IN_COUNT", label: "Count of Inventors" },
113
+ { key: "GOV", kind: "field", field: "GOV", label: "Government Interest" }
114
+ ]
115
+ };
116
+
117
+ // src/index.ts
118
+ function normalizeKey(t, key) {
119
+ return t.normalizeKey === "upper" ? key.toUpperCase() : key;
120
+ }
121
+ function isBareValue(v) {
122
+ const s = v.trim();
123
+ return !(s.startsWith("(") || s.startsWith("[") || s.startsWith('"'));
124
+ }
125
+ function maybeWrapValue(v, wrapBareValues) {
126
+ const s = v.trim();
127
+ if (!wrapBareValues) return s;
128
+ if (!isBareValue(s)) return s;
129
+ return `(${s})`;
130
+ }
131
+ function readValue(input, start) {
132
+ let i = start;
133
+ while (i < input.length && /\s/.test(input[i])) i++;
134
+ const ch = input[i];
135
+ if (!ch) return ["", i];
136
+ const readBalanced = (open, close) => {
137
+ let depth = 0;
138
+ let j2 = i;
139
+ while (j2 < input.length) {
140
+ const c = input[j2];
141
+ if (c === open) depth++;
142
+ else if (c === close) {
143
+ depth--;
144
+ if (depth === 0) {
145
+ j2++;
146
+ return [input.slice(i, j2), j2];
147
+ }
148
+ } else if (c === '"') {
149
+ j2++;
150
+ while (j2 < input.length) {
151
+ if (input[j2] === "\\" && j2 + 1 < input.length) {
152
+ j2 += 2;
153
+ continue;
154
+ }
155
+ if (input[j2] === '"') {
156
+ j2++;
157
+ break;
158
+ }
159
+ j2++;
160
+ }
161
+ continue;
162
+ }
163
+ j2++;
164
+ }
165
+ return [input.slice(i), input.length];
166
+ };
167
+ if (ch === "(") return readBalanced("(", ")");
168
+ if (ch === "[") return readBalanced("[", "]");
169
+ if (ch === '"') {
170
+ let j2 = i + 1;
171
+ while (j2 < input.length) {
172
+ if (input[j2] === "\\" && j2 + 1 < input.length) {
173
+ j2 += 2;
174
+ continue;
175
+ }
176
+ if (input[j2] === '"') {
177
+ j2++;
178
+ break;
179
+ }
180
+ j2++;
181
+ }
182
+ return [input.slice(i, j2), j2];
183
+ }
184
+ let j = i;
185
+ while (j < input.length && !/\s/.test(input[j])) j++;
186
+ return [input.slice(i, j), j];
187
+ }
188
+ function getTokenRange(text, cursor) {
189
+ const isWord = (c) => /[A-Za-z0-9_]/.test(c);
190
+ let start = Math.max(0, cursor);
191
+ while (start > 0 && isWord(text[start - 1])) start--;
192
+ let end = Math.max(0, cursor);
193
+ while (end < text.length && isWord(text[end])) end++;
194
+ const prefix = text.slice(start, cursor);
195
+ return { start, end, prefix };
196
+ }
197
+ function renderSnippet(snippet) {
198
+ const idx = snippet.indexOf("|");
199
+ if (idx === -1) return { insertText: snippet, cursorIndex: snippet.length };
200
+ const insertText = snippet.replace("|", "");
201
+ return { insertText, cursorIndex: idx };
202
+ }
203
+ var ShortcutRegistry = class {
204
+ constructor(templates) {
205
+ __publicField(this, "templates", /* @__PURE__ */ new Map());
206
+ __publicField(this, "lookup", /* @__PURE__ */ new Map());
207
+ for (const t of templates) this.registerTemplate(t);
208
+ }
209
+ registerTemplate(t) {
210
+ this.templates.set(t.id, t);
211
+ const map = /* @__PURE__ */ new Map();
212
+ for (const sc of t.shortcuts) {
213
+ map.set(normalizeKey(t, sc.key), sc);
214
+ for (const a of sc.aliases ?? []) map.set(normalizeKey(t, a), sc);
215
+ }
216
+ this.lookup.set(t.id, map);
217
+ }
218
+ listTemplates() {
219
+ return [...this.templates.values()].map((t) => ({ id: t.id, name: t.name }));
220
+ }
221
+ suggest(prefix, templateId, limit = 10) {
222
+ const t = this.templates.get(templateId);
223
+ if (!t) return [];
224
+ const p = normalizeKey(t, prefix);
225
+ const out = [];
226
+ for (const sc of t.shortcuts) {
227
+ const k = normalizeKey(t, sc.key);
228
+ if (k.startsWith(p)) {
229
+ const item = { key: sc.key };
230
+ if (sc.label !== void 0) item.label = sc.label;
231
+ if (sc.description !== void 0) item.description = sc.description;
232
+ out.push(item);
233
+ if (out.length >= limit) break;
234
+ }
235
+ }
236
+ return out;
237
+ }
238
+ build(alias, value, opts) {
239
+ const t = this.templates.get(opts.templateId);
240
+ const m = this.lookup.get(opts.templateId);
241
+ if (!t || !m) return `${alias}:${value}`;
242
+ const key = normalizeKey(t, alias);
243
+ const sc = m.get(key);
244
+ if (!sc) return `${alias}:${value}`;
245
+ const v = maybeWrapValue(value, opts.wrapBareValues ?? true);
246
+ if (sc.kind === "field" && sc.field) return `${sc.field}:${v}`;
247
+ if (sc.kind === "macro" && sc.macro) return sc.macro.replaceAll("{{value}}", v);
248
+ return `${alias}:${v}`;
249
+ }
250
+ expand(query, opts) {
251
+ const t = this.templates.get(opts.templateId);
252
+ const m = this.lookup.get(opts.templateId);
253
+ if (!t || !m) return query;
254
+ let i = 0;
255
+ let out = "";
256
+ while (i < query.length) {
257
+ if (!/[A-Za-z0-9_]/.test(query[i])) {
258
+ out += query[i];
259
+ i++;
260
+ continue;
261
+ }
262
+ let j = i;
263
+ while (j < query.length && /[A-Za-z0-9_]/.test(query[j])) j++;
264
+ const keyRaw = query.slice(i, j);
265
+ let k = j;
266
+ while (k < query.length && /\s/.test(query[k])) k++;
267
+ if (query[k] !== ":") {
268
+ out += query[i];
269
+ i++;
270
+ continue;
271
+ }
272
+ const keyNorm = normalizeKey(t, keyRaw);
273
+ const sc = m.get(keyNorm);
274
+ out += sc ? "" : query.slice(i, k + 1);
275
+ k++;
276
+ const [valueRaw, nextIdx] = readValue(query, k);
277
+ const valueNorm = maybeWrapValue(valueRaw, opts.wrapBareValues ?? true);
278
+ if (!sc) out += valueRaw;
279
+ else if (sc.kind === "field" && sc.field) out += `${sc.field}:${valueNorm}`;
280
+ else if (sc.kind === "macro" && sc.macro) out += sc.macro.replaceAll("{{value}}", valueNorm);
281
+ else out += `${keyRaw}:${valueNorm}`;
282
+ i = nextIdx;
283
+ }
284
+ return out;
285
+ }
286
+ /**
287
+ * NEW: Autocomplete shortcuts.
288
+ * Given current text and cursor position, return completion items like:
289
+ * - label: "TAC:()"
290
+ * - insertText: "TAC:()"
291
+ * - newCursor: places cursor inside ()
292
+ */
293
+ complete(text, cursor, opts) {
294
+ const t = this.templates.get(opts.templateId);
295
+ if (!t) return [];
296
+ if (cursor > 0 && text[cursor - 1] === ":") return [];
297
+ const { start, end, prefix } = getTokenRange(text, cursor);
298
+ if (!prefix) return [];
299
+ const suggestions = this.suggest(prefix, opts.templateId, opts.limit ?? 10);
300
+ const items = [];
301
+ for (const s of suggestions) {
302
+ const sc = t.shortcuts.find((x) => normalizeKey(t, x.key) === normalizeKey(t, s.key));
303
+ const rawSnippet = sc?.snippet ?? `${s.key}:(|)`;
304
+ const { insertText, cursorIndex } = renderSnippet(rawSnippet);
305
+ const replaceFrom = start;
306
+ const replaceTo = end;
307
+ const newTextLengthDelta = insertText.length - (replaceTo - replaceFrom);
308
+ const newCursor = replaceFrom + cursorIndex;
309
+ const desc = sc?.description;
310
+ const item = {
311
+ key: s.key,
312
+ label: insertText,
313
+ replaceFrom,
314
+ replaceTo,
315
+ insertText,
316
+ newCursor
317
+ };
318
+ if (desc !== void 0) item.description = desc;
319
+ items.push(item);
320
+ void newTextLengthDelta;
321
+ }
322
+ return items;
323
+ }
324
+ /**
325
+ * NEW: Apply a chosen completion to (text, cursor) and return updated (text, cursor).
326
+ * UI can then call input.setSelectionRange(cursor, cursor).
327
+ */
328
+ applyCompletion(text, item) {
329
+ const next = text.slice(0, item.replaceFrom) + item.insertText + text.slice(item.replaceTo);
330
+ return { text: next, cursor: item.newCursor };
331
+ }
332
+ };
333
+ function createRegistry(templates) {
334
+ return new ShortcutRegistry(templates);
335
+ }
336
+ export {
337
+ ShortcutRegistry,
338
+ createRegistry,
339
+ patsnapTemplate
340
+ };
341
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/templates/patsnap.ts","../src/index.ts"],"sourcesContent":["// src/templates/patsnap.ts\nimport type { Template } from \"../index.js\";\n\nexport const patsnapTemplate: Template = {\n id: \"patsnap\",\n name: \"Patsnap\",\n normalizeKey: \"upper\",\n shortcuts: [\n // --- Text fields (from your 1st screenshot) ---\n { key: \"TA\", kind: \"field\", field: \"TA_ALL\", label: \"Title + Abstract\", description: \"Search in title and abstract\", aliases: [\"TA_ALL\"] },\n { key: \"TTL\", kind: \"field\", field: \"TTL_ALL\", label: \"Title\", description: \"Search in title\", aliases: [\"TTL_ALL\"] },\n { key: \"TAC\", kind: \"field\", field: \"TAC_ALL\", label: \"Title+Abstract+Claims\", description: \"Search in title, abstract, and claims\", aliases: [\"TAC_ALL\"] },\n { key: \"TACD\", kind: \"field\", field: \"TACD_ALL\", label: \"Title+Abstract+Claims+Description\", description: \"Search in title/abstract/claims/description\", aliases: [\"TACD_ALL\"] },\n { key: \"ABST\", kind: \"field\", field: \"ABST_ALL\", label: \"Abstract\", description: \"Search in abstract\", aliases: [\"ABST_ALL\"] },\n { key: \"CLMS\", kind: \"field\", field: \"CLMS_ALL\", label: \"Claims\", description: \"Search in claims\", aliases: [\"CLMS_ALL\"] },\n { key: \"DESC\", kind: \"field\", field: \"DESC_ALL\", label: \"Description\", description: \"Search in description\", aliases: [\"DESC_ALL\"] },\n\n { key: \"DESC_F\", kind: \"field\", field: \"DESC_F\", label: \"Technical Field\", description: \"Description: technical field\" },\n { key: \"DESC_B\", kind: \"field\", field: \"DESC_B\", label: \"Background Art\", description: \"Description: background art\" },\n { key: \"DESC_S\", kind: \"field\", field: \"DESC_S\", label: \"Summary of Invention\", description: \"Description: summary\" },\n { key: \"DESC_D\", kind: \"field\", field: \"DESC_D\", label: \"Brief Description of Drawings\", description: \"Description: drawings\" },\n { key: \"DESC_E\", kind: \"field\", field: \"DESC_E\", label: \"Description of Embodiments\", description: \"Description: embodiments\" },\n\n { key: \"ICLMS\", kind: \"field\", field: \"ICLMS_ALL\", label: \"Independent Claims\", description: \"Search in independent claims\", aliases: [\"ICLMS_ALL\"] },\n { key: \"PROBLEM_SUM\", kind: \"field\", field: \"PROBLEM_SUM\", label: \"Technical Problem\", description: \"Problem summary\" },\n { key: \"METHOD_SUM\", kind: \"field\", field: \"METHOD_SUM\", label: \"Technical Method\", description: \"Method summary\" },\n { key: \"BENEFIT_SUM\", kind: \"field\", field: \"BENEFIT_SUM\", label: \"Technical Benefit\", description: \"Benefit summary\" },\n\n // --- Classification (2nd screenshot) ---\n { key: \"MCPC\", kind: \"field\", field: \"MCPC\", label: \"Main CPC\" },\n { key: \"CPC_SUB_GROUP\", kind: \"field\", field: \"CPC_SUB_GROUP\", label: \"CPC Sub Group\" },\n { key: \"IPC_CPC\", kind: \"field\", field: \"IPC_CPC\", label: \"IPC & CPC\" },\n { key: \"UPC\", kind: \"field\", field: \"UPC\", label: \"UPC\" },\n { key: \"LOC\", kind: \"field\", field: \"LOC\", label: \"LOC\" },\n { key: \"FI\", kind: \"field\", field: \"FI\", label: \"FI\" },\n { key: \"FTERM\", kind: \"field\", field: \"FTERM\", label: \"F-TERM\" },\n { key: \"ADC\", kind: \"field\", field: \"ADC\", label: \"Application Domain\" },\n { key: \"TTC\", kind: \"field\", field: \"TTC\", label: \"Technology Topic\" },\n { key: \"SEIC\", kind: \"field\", field: \"SEIC\", label: \"Main SEIC\" },\n { key: \"SEIC_ALL\", kind: \"field\", field: \"SEIC_ALL\", label: \"SEIC (All)\" },\n { key: \"GBC\", kind: \"field\", field: \"GBC\", label: \"GBC\" },\n\n // --- Assignees / Inventors (3rd screenshot) ---\n { key: \"ALL_AN\", kind: \"field\", field: \"ALL_AN\", label: \"All Assignees\" },\n { key: \"ANCS\", kind: \"field\", field: \"ANCS\", label: \"Std. Current Assignee\" },\n { key: \"ANC\", kind: \"field\", field: \"ANC\", label: \"Current Assignee\" },\n { key: \"GNAME\", kind: \"field\", field: \"GNAME\", label: \"Grouped Assignee\" },\n { key: \"ANS\", kind: \"field\", field: \"ANS\", label: \"Std. Original Assignee\" },\n { key: \"AN\", kind: \"field\", field: \"AN\", label: \"Original Assignee\" },\n { key: \"F_AN\", kind: \"field\", field: \"F_AN\", label: \"First Original Assignee\" },\n { key: \"F_ANC\", kind: \"field\", field: \"F_ANC\", label: \"First Current Assignee\" },\n { key: \"IN\", kind: \"field\", field: \"IN\", label: \"Inventor Name\" },\n { key: \"F_IN\", kind: \"field\", field: \"F_IN\", label: \"First Inventor\" },\n { key: \"ATC\", kind: \"field\", field: \"ATC\", label: \"Agency\" },\n { key: \"ATCS\", kind: \"field\", field: \"ATCS\", label: \"Std. Agency\" },\n { key: \"AT\", kind: \"field\", field: \"AT\", label: \"Attorney Name\" },\n { key: \"PE\", kind: \"field\", field: \"PE\", label: \"Primary Examiner\" },\n { key: \"AE\", kind: \"field\", field: \"AE\", label: \"Assistant Examiner\" },\n\n // --- Dates (4th screenshot) ---\n { key: \"APD\", kind: \"field\", field: \"APD\", label: \"Application Date\" },\n { key: \"PBD\", kind: \"field\", field: \"PBD\", label: \"Publication Date\" },\n { key: \"PRIORITY_DATE\", kind: \"field\", field: \"PRIORITY_DATE\", label: \"Priority Date\" },\n { key: \"EXDT\", kind: \"field\", field: \"EXDT\", label: \"Estimated Expiry Date\" },\n { key: \"ISD\", kind: \"field\", field: \"ISD\", label: \"Issue Date\" },\n { key: \"EXPD\", kind: \"field\", field: \"EXPD\", label: \"Expiry Date\" },\n { key: \"EXAMINE_DATE\", kind: \"field\", field: \"EXAMINE_DATE\", label: \"Substantive Examination Date\" },\n { key: \"PCTENTRY_DATE\", kind: \"field\", field: \"PCTENTRY_DATE\", label: \"PCT Entry Date\" },\n { key: \"LEGAL_STATUS_DATE\", kind: \"field\", field: \"LEGAL_STATUS_DATE\", label: \"Legal Status Date\" },\n\n // --- Numbers (5th screenshot) ---\n { key: \"PN\", kind: \"field\", field: \"PN\", label: \"Publication Number\" },\n { key: \"APNO\", kind: \"field\", field: \"APNO\", label: \"Application Number\" },\n { key: \"PRNO\", kind: \"field\", field: \"PRNO\", label: \"Priority Number\" },\n { key: \"KD\", kind: \"field\", field: \"KD\", label: \"Kind Code\" },\n { key: \"PCT_APNO\", kind: \"field\", field: \"PCT_APNO\", label: \"PCT Application Number\" },\n { key: \"PCT_PN\", kind: \"field\", field: \"PCT_PN\", label: \"PCT Publication Number\" },\n\n // --- Addresses / Regions (6th screenshot) ---\n { key: \"AN_ADD\", kind: \"field\", field: \"AN_ADD\", label: \"Original Assignee Address\" },\n { key: \"ANC_ADD\", kind: \"field\", field: \"ANC_ADD\", label: \"Current Assignee Address\" },\n { key: \"IN_ADDRESS\", kind: \"field\", field: \"IN_ADDRESS\", label: \"Inventor Address\" },\n { key: \"PRIORITY_COUNTRY\", kind: \"field\", field: \"PRIORITY_COUNTRY\", label: \"Priority Country/Region\" },\n { key: \"AUTHORITY\", kind: \"field\", field: \"AUTHORITY\", label: \"Authority\" },\n { key: \"EPDS\", kind: \"field\", field: \"EPDS\", label: \"EP Designated State\" },\n { key: \"ENTRY_COUNTRY\", kind: \"field\", field: \"ENTRY_COUNTRY\", label: \"Entry Country/Region\" },\n\n // --- Citations / Family (7th screenshot) ---\n { key: \"B_CITES\", kind: \"field\", field: \"B_CITES\", label: \"Backward Citations\" },\n { key: \"F_CITES\", kind: \"field\", field: \"F_CITES\", label: \"Forward Citations\" },\n { key: \"BF_CITES\", kind: \"field\", field: \"BF_CITES\", label: \"Backward Or Forward Citations\" },\n { key: \"B_CITES_COUNT\", kind: \"field\", field: \"B_CITES_COUNT\", label: \"Count Of Backward Citations\" },\n { key: \"F_CITES_COUNT\", kind: \"field\", field: \"F_CITES_COUNT\", label: \"Count Of Forward Citations\" },\n { key: \"F_CITES_ANC\", kind: \"field\", field: \"F_CITES_ANC\", label: \"Assignee Forward Citations (Current)\" },\n { key: \"B_CITES_ANC\", kind: \"field\", field: \"B_CITES_ANC\", label: \"Assignee Backward Citations (Current)\" },\n { key: \"CITE_CATEGORY\", kind: \"field\", field: \"CITE_CATEGORY\", label: \"Citation/Rejection Category\" },\n { key: \"FAM\", kind: \"field\", field: \"FAM\", label: \"Simple Family\" },\n { key: \"EFAM\", kind: \"field\", field: \"EFAM\", label: \"PatSnap Family\" },\n { key: \"FAM_COUNT\", kind: \"field\", field: \"FAM_COUNT\", label: \"Simple Family Application Count\" },\n { key: \"IFAM_COUNT\", kind: \"field\", field: \"IFAM_COUNT\", label: \"INPADOC Family Application Count\" },\n { key: \"EFAM_COUNT\", kind: \"field\", field: \"EFAM_COUNT\", label: \"PatSnap Family Application Count\" },\n { key: \"FAM_COUNTRY_COUNT\", kind: \"field\", field: \"FAM_COUNTRY_COUNT\", label: \"Simple Family Jurisdiction Count\" },\n { key: \"IFAM_COUNTRY_COUNT\", kind: \"field\", field: \"IFAM_COUNTRY_COUNT\", label: \"INPADOC Family Jurisdiction Count\" },\n { key: \"EFAM_COUNTRY_COUNT\", kind: \"field\", field: \"EFAM_COUNTRY_COUNT\", label: \"PatSnap Family Jurisdiction Count\" },\n\n // --- Legal status / metrics (8th screenshot) ---\n { key: \"LEGAL_STATUS\", kind: \"field\", field: \"LEGAL_STATUS\", label: \"Legal Status\" },\n { key: \"LEGAL_EVENT\", kind: \"field\", field: \"LEGAL_EVENT\", label: \"Legal Event\" },\n { key: \"SIMPLE_LEGAL_STATUS\", kind: \"field\", field: \"SIMPLE_LEGAL_STATUS\", label: \"Simple Legal Status\" },\n { key: \"UP_STATUS\", kind: \"field\", field: \"UP_STATUS\", label: \"Status of Unified Patent Court\" },\n { key: \"ENTRY_COUNTRY_LS\", kind: \"field\", field: \"ENTRY_COUNTRY_LS\", label: \"Legal Status of Entry Country/Region\" },\n { key: \"ENTRY_COUNTRY_SLS\", kind: \"field\", field: \"ENTRY_COUNTRY_SLS\", label: \"Simple Legal Status of Entry Country/Region\" },\n { key: \"PV\", kind: \"field\", field: \"PV\", label: \"Patent Value\" },\n { key: \"PAGE_COUNT\", kind: \"field\", field: \"PAGE_COUNT\", label: \"Page Count\" },\n { key: \"CLAIM_COUNT\", kind: \"field\", field: \"CLAIM_COUNT\", label: \"Claim Count\" },\n { key: \"FCLMS_WORDCOUNT\", kind: \"field\", field: \"FCLMS_WORDCOUNT\", label: \"Word count of first claim\" },\n { key: \"AN_COUNT\", kind: \"field\", field: \"AN_COUNT\", label: \"Count of Original Assignees\" },\n { key: \"ANC_COUNT\", kind: \"field\", field: \"ANC_COUNT\", label: \"Count of Current Assignees\" },\n { key: \"IN_COUNT\", kind: \"field\", field: \"IN_COUNT\", label: \"Count of Inventors\" },\n { key: \"GOV\", kind: \"field\", field: \"GOV\", label: \"Government Interest\" }\n ]\n};\n","// src/index.ts\n\nexport type ShortcutKind = \"field\" | \"macro\";\n\nexport type Suggestion = {\n key: string;\n label?: string;\n description?: string;\n};\n\nexport type Shortcut = {\n key: string; // what user types, e.g. \"TAC\"\n kind: ShortcutKind; // \"field\" or \"macro\"\n field?: string; // if kind=\"field\": actual field, e.g. \"TAC_ALL\"\n macro?: string; // if kind=\"macro\": string with {{value}} placeholder\n label?: string;\n description?: string;\n aliases?: string[];\n\n /**\n * Optional autocomplete snippet.\n * Use `|` to mark cursor position after insertion.\n * Example: \"TAC:(|)\" -> inserts \"TAC:()\" and cursor is inside parentheses.\n *\n * If omitted, defaults to `${key}:(|)`.\n */\n snippet?: string;\n};\n\nexport type Template = {\n id: string;\n name: string;\n shortcuts: Shortcut[];\n normalizeKey?: \"upper\" | \"none\";\n};\n\nexport type ExpandOptions = {\n templateId: string;\n wrapBareValues?: boolean;\n};\n\n/**\n * Completion item returned by registry.complete().\n * - replaceFrom/replaceTo tells UI what range to replace\n * - insertText is what to insert\n * - newCursor is absolute cursor position in the final string\n */\nexport type CompletionItem = {\n key: string; // \"TAC\"\n label: string; // what you show in dropdown (e.g. \"TAC:()\")\n description?: string;\n\n replaceFrom: number;\n replaceTo: number;\n\n insertText: string; // e.g. \"TAC:()\"\n newCursor: number; // absolute cursor pos in final string\n};\n\nfunction normalizeKey(t: Template, key: string): string {\n return t.normalizeKey === \"upper\" ? key.toUpperCase() : key;\n}\n\nfunction isBareValue(v: string): boolean {\n const s = v.trim();\n return !(s.startsWith(\"(\") || s.startsWith(\"[\") || s.startsWith(\"\\\"\"));\n}\n\nfunction maybeWrapValue(v: string, wrapBareValues: boolean): string {\n const s = v.trim();\n if (!wrapBareValues) return s;\n if (!isBareValue(s)) return s;\n return `(${s})`;\n}\n\n// Reads a value after \":\" supporting (), [], \"\" and bare tokens.\n// Returns [value, nextIndex]\nfunction readValue(input: string, start: number): [string, number] {\n let i = start;\n while (i < input.length && /\\s/.test(input[i]!)) i++;\n\n const ch = input[i];\n if (!ch) return [\"\", i];\n\n const readBalanced = (open: string, close: string): [string, number] => {\n let depth = 0;\n let j = i;\n while (j < input.length) {\n const c = input[j]!;\n if (c === open) depth++;\n else if (c === close) {\n depth--;\n if (depth === 0) {\n j++;\n return [input.slice(i, j), j];\n }\n } else if (c === \"\\\"\") {\n j++;\n while (j < input.length) {\n if (input[j] === \"\\\\\" && j + 1 < input.length) { j += 2; continue; }\n if (input[j] === \"\\\"\") { j++; break; }\n j++;\n }\n continue;\n }\n j++;\n }\n return [input.slice(i), input.length];\n };\n\n if (ch === \"(\") return readBalanced(\"(\", \")\");\n if (ch === \"[\") return readBalanced(\"[\", \"]\");\n\n if (ch === \"\\\"\") {\n let j = i + 1;\n while (j < input.length) {\n if (input[j] === \"\\\\\" && j + 1 < input.length) { j += 2; continue; }\n if (input[j] === \"\\\"\") { j++; break; }\n j++;\n }\n return [input.slice(i, j), j];\n }\n\n let j = i;\n while (j < input.length && !/\\s/.test(input[j]!)) j++;\n return [input.slice(i, j), j];\n}\n\n/**\n * Find the \"word\" under/left of cursor for shortcut completion.\n * We treat a shortcut token as [A-Za-z0-9_]+\n */\nfunction getTokenRange(text: string, cursor: number): { start: number; end: number; prefix: string } {\n const isWord = (c: string) => /[A-Za-z0-9_]/.test(c);\n\n let start = Math.max(0, cursor);\n while (start > 0 && isWord(text[start - 1]!)) start--;\n\n let end = Math.max(0, cursor);\n while (end < text.length && isWord(text[end]!)) end++;\n\n const prefix = text.slice(start, cursor);\n return { start, end, prefix };\n}\n\n/**\n * Convert snippet with `|` cursor marker into (insertText, cursorIndexInInsertText)\n */\nfunction renderSnippet(snippet: string): { insertText: string; cursorIndex: number } {\n const idx = snippet.indexOf(\"|\");\n if (idx === -1) return { insertText: snippet, cursorIndex: snippet.length };\n const insertText = snippet.replace(\"|\", \"\");\n return { insertText, cursorIndex: idx };\n}\n\nexport class ShortcutRegistry {\n private templates = new Map<string, Template>();\n private lookup = new Map<string, Map<string, Shortcut>>();\n\n constructor(templates: Template[]) {\n for (const t of templates) this.registerTemplate(t);\n }\n\n registerTemplate(t: Template) {\n this.templates.set(t.id, t);\n\n const map = new Map<string, Shortcut>();\n for (const sc of t.shortcuts) {\n map.set(normalizeKey(t, sc.key), sc);\n for (const a of sc.aliases ?? []) map.set(normalizeKey(t, a), sc);\n }\n this.lookup.set(t.id, map);\n }\n\n listTemplates(): { id: string; name: string }[] {\n return [...this.templates.values()].map(t => ({ id: t.id, name: t.name }));\n }\n\n suggest(prefix: string, templateId: string, limit = 10): Suggestion[] {\n const t = this.templates.get(templateId);\n if (!t) return [];\n\n const p = normalizeKey(t, prefix);\n const out: Suggestion[] = [];\n\n for (const sc of t.shortcuts) {\n const k = normalizeKey(t, sc.key);\n if (k.startsWith(p)) {\n const item: Suggestion = { key: sc.key };\n if (sc.label !== undefined) item.label = sc.label;\n if (sc.description !== undefined) item.description = sc.description;\n out.push(item);\n\n if (out.length >= limit) break;\n }\n }\n return out;\n }\n\n build(alias: string, value: string, opts: ExpandOptions): string {\n const t = this.templates.get(opts.templateId);\n const m = this.lookup.get(opts.templateId);\n if (!t || !m) return `${alias}:${value}`;\n\n const key = normalizeKey(t, alias);\n const sc = m.get(key);\n if (!sc) return `${alias}:${value}`;\n\n const v = maybeWrapValue(value, opts.wrapBareValues ?? true);\n\n if (sc.kind === \"field\" && sc.field) return `${sc.field}:${v}`;\n if (sc.kind === \"macro\" && sc.macro) return sc.macro.replaceAll(\"{{value}}\", v);\n\n return `${alias}:${v}`;\n }\n\n expand(query: string, opts: ExpandOptions): string {\n const t = this.templates.get(opts.templateId);\n const m = this.lookup.get(opts.templateId);\n if (!t || !m) return query;\n\n let i = 0;\n let out = \"\";\n\n while (i < query.length) {\n if (!/[A-Za-z0-9_]/.test(query[i]!)) {\n out += query[i]!;\n i++;\n continue;\n }\n\n let j = i;\n while (j < query.length && /[A-Za-z0-9_]/.test(query[j]!)) j++;\n const keyRaw = query.slice(i, j);\n\n let k = j;\n while (k < query.length && /\\s/.test(query[k]!)) k++;\n\n if (query[k] !== \":\") {\n out += query[i]!;\n i++;\n continue;\n }\n\n const keyNorm = normalizeKey(t, keyRaw);\n const sc = m.get(keyNorm);\n\n out += sc ? \"\" : query.slice(i, k + 1);\n k++;\n\n const [valueRaw, nextIdx] = readValue(query, k);\n const valueNorm = maybeWrapValue(valueRaw, opts.wrapBareValues ?? true);\n\n if (!sc) out += valueRaw;\n else if (sc.kind === \"field\" && sc.field) out += `${sc.field}:${valueNorm}`;\n else if (sc.kind === \"macro\" && sc.macro) out += sc.macro.replaceAll(\"{{value}}\", valueNorm);\n else out += `${keyRaw}:${valueNorm}`;\n\n i = nextIdx;\n }\n\n return out;\n }\n\n /**\n * NEW: Autocomplete shortcuts.\n * Given current text and cursor position, return completion items like:\n * - label: \"TAC:()\"\n * - insertText: \"TAC:()\"\n * - newCursor: places cursor inside ()\n */\n complete(text: string, cursor: number, opts: { templateId: string; limit?: number }): CompletionItem[] {\n const t = this.templates.get(opts.templateId);\n if (!t) return [];\n\n // If cursor is right after \":\" (user is entering value), don't suggest shortcut keys\n if (cursor > 0 && text[cursor - 1] === \":\") return [];\n\n const { start, end, prefix } = getTokenRange(text, cursor);\n if (!prefix) return [];\n\n const suggestions = this.suggest(prefix, opts.templateId, opts.limit ?? 10);\n\n const items: CompletionItem[] = [];\n for (const s of suggestions) {\n // find shortcut object so we can use optional snippet/description\n const sc = t.shortcuts.find(x => normalizeKey(t, x.key) === normalizeKey(t, s.key));\n const rawSnippet = sc?.snippet ?? `${s.key}:(|)`;\n const { insertText, cursorIndex } = renderSnippet(rawSnippet);\n\n const replaceFrom = start;\n const replaceTo = end;\n\n const newTextLengthDelta = insertText.length - (replaceTo - replaceFrom);\n const newCursor = replaceFrom + cursorIndex;\n const desc = sc?.description;\n\n const item: CompletionItem = {\n key: s.key,\n label: insertText,\n replaceFrom,\n replaceTo,\n insertText,\n newCursor\n };\n\n if (desc !== undefined) item.description = desc;\n\n items.push(item);\n\n // NOTE: newTextLengthDelta isn't used here, because newCursor is absolute within the new string\n // by construction. Keep it if you later add multi-edit support.\n void newTextLengthDelta;\n }\n\n return items;\n }\n\n /**\n * NEW: Apply a chosen completion to (text, cursor) and return updated (text, cursor).\n * UI can then call input.setSelectionRange(cursor, cursor).\n */\n applyCompletion(text: string, item: CompletionItem): { text: string; cursor: number } {\n const next =\n text.slice(0, item.replaceFrom) +\n item.insertText +\n text.slice(item.replaceTo);\n\n return { text: next, cursor: item.newCursor };\n }\n}\n\nexport function createRegistry(templates: Template[]) {\n return new ShortcutRegistry(templates);\n}\n\nexport { patsnapTemplate } from \"./templates/patsnap.js\";\n"],"mappings":"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","names":["j"]}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "patent-query-shortcuts",
3
+ "version": "0.1.0",
4
+ "description": "Shortcut expansion + template system for patent search queries (e.g., TAC -> Title/Abstract/Claims)",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": ["dist", "README.md", "LICENSE"],
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "test": "vitest run",
20
+ "lint": "eslint .",
21
+ "format": "prettier -w .",
22
+ "typecheck": "tsc --noEmit",
23
+ "prepublishOnly": "npm run typecheck && npm run test && npm run build"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^22.0.0",
27
+ "eslint": "^9.0.0",
28
+ "prettier": "^3.0.0",
29
+ "tsup": "^8.0.0",
30
+ "typescript": "^5.0.0",
31
+ "vitest": "^2.0.0"
32
+ }
33
+ }