@deepcitation/deepcitation-js 1.1.49 → 1.1.50
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 +156 -157
- package/lib/{chunk-D2TKEF6D.cjs → chunk-4ILSZKAP.cjs} +3 -2
- package/lib/chunk-4ILSZKAP.cjs.map +1 -0
- package/lib/chunk-5XGN7UAV.js +2 -0
- package/lib/chunk-5XGN7UAV.js.map +1 -0
- package/lib/{chunk-2PRW5PVT.cjs → chunk-ALJ2ZQ2S.cjs} +2 -1
- package/lib/chunk-ALJ2ZQ2S.cjs.map +1 -0
- package/lib/{chunk-F2MMVEVC.cjs → chunk-BYLIBOAU.cjs} +2 -1
- package/lib/chunk-BYLIBOAU.cjs.map +1 -0
- package/lib/{chunk-ND6LFDGK.js → chunk-KBDVUQEE.js} +2 -1
- package/lib/chunk-KBDVUQEE.js.map +1 -0
- package/lib/{chunk-PKXMJNRX.js → chunk-LLLVZOXB.js} +2 -1
- package/lib/chunk-LLLVZOXB.js.map +1 -0
- package/lib/{chunk-DHVODVIA.cjs → chunk-PJWAX2VG.cjs} +2 -1
- package/lib/chunk-PJWAX2VG.cjs.map +1 -0
- package/lib/{chunk-UUR2SQKU.cjs → chunk-QUW3L3UU.cjs} +2 -1
- package/lib/chunk-QUW3L3UU.cjs.map +1 -0
- package/lib/chunk-R57DQBOT.js +2 -0
- package/lib/chunk-R57DQBOT.js.map +1 -0
- package/lib/{chunk-3XSZLKJW.js → chunk-TDGYSF3B.js} +3 -2
- package/lib/chunk-TDGYSF3B.js.map +1 -0
- package/lib/client/index.cjs +2 -1
- package/lib/client/index.cjs.map +1 -0
- package/lib/client/index.js +2 -1
- package/lib/client/index.js.map +1 -0
- package/lib/index.cjs +2 -1
- package/lib/index.cjs.map +1 -0
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -0
- package/lib/prompts/index.cjs +2 -1
- package/lib/prompts/index.cjs.map +1 -0
- package/lib/prompts/index.js +2 -1
- package/lib/prompts/index.js.map +1 -0
- package/lib/react/index.cjs +4 -3
- package/lib/react/index.cjs.map +1 -0
- package/lib/react/index.js +3 -2
- package/lib/react/index.js.map +1 -0
- package/lib/types/index.cjs +2 -1
- package/lib/types/index.cjs.map +1 -0
- package/lib/types/index.js +2 -1
- package/lib/types/index.js.map +1 -0
- package/package.json +161 -152
- package/src/tailwind.css +5 -5
- package/lib/chunk-HRCAI3NV.js +0 -1
- package/lib/chunk-O2XFH626.js +0 -1
package/README.md
CHANGED
|
@@ -1,157 +1,156 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
# @deepcitation/deepcitation-js
|
|
4
|
-
|
|
5
|
-
**Instantly trustworthy AI content with eliminated hallucination risk.**
|
|
6
|
-
|
|
7
|
-
[](https://www.npmjs.com/package/@deepcitation/deepcitation-js)
|
|
8
|
-
[](https://opensource.org/licenses/MIT)
|
|
9
|
-
[](https://www.typescriptlang.org/)
|
|
10
|
-
|
|
11
|
-
[Documentation](https://deepcitation.com/docs) · [
|
|
12
|
-
|
|
13
|
-
</div>
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
DeepCitation solves this by deterministically verifying every citation against your sources. We provide visual proof for every claim, making content instantly trustworthy and safer to present to users.
|
|
22
|
-
|
|
23
|
-
<div align="center">
|
|
24
|
-
<img src="./examples/assets/deepcitation-medical-demo.gif" alt="DeepCitation demo showing instant certainty with verified inline citations" width="700" />
|
|
25
|
-
<br />
|
|
26
|
-
<em>DeepCitation demo showing instant certainty with verified inline citations
|
|
27
|
-
</div>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
{ role: "
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
import {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
MIT License - see [LICENSE](./LICENSE) for details.
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# @deepcitation/deepcitation-js
|
|
4
|
+
|
|
5
|
+
**Instantly trustworthy AI content with eliminated hallucination risk.**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@deepcitation/deepcitation-js)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
|
|
11
|
+
[Documentation](https://deepcitation.com/docs) · [Get API Key](https://deepcitation.com/signup) · [Examples](./examples)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
LLMs hallucinate citations and cite pages that don't exist. **Citations alone are not enough.**
|
|
20
|
+
|
|
21
|
+
DeepCitation solves this by deterministically verifying every citation against your sources. We provide visual proof for every claim, making content instantly trustworthy and safer to present to users.
|
|
22
|
+
|
|
23
|
+
<div align="center">
|
|
24
|
+
<img src="./examples/assets/deepcitation-medical-demo.gif" alt="DeepCitation demo showing instant certainty with verified inline citations" width="700" />
|
|
25
|
+
<br />
|
|
26
|
+
<em>DeepCitation demo showing instant certainty with verified inline citations</em>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Before: "Recent results indicate 35% EF [1]" → ❓ Did the LLM make this up?
|
|
31
|
+
After: "Recent results indicate 35% EF [1]" → ✅ Verified on page 1, line 12 (with screenshot)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install @deepcitation/deepcitation-js
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Documentation
|
|
41
|
+
|
|
42
|
+
Full documentation is available at [deepcitation.com/docs](https://deepcitation.com/docs).
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
DeepCitation works in three steps: **Pre-Prompt**, **Post-Prompt**, and **Display**.
|
|
47
|
+
|
|
48
|
+
### Step 1: Pre-Prompt
|
|
49
|
+
|
|
50
|
+
Upload attachments and enhance your prompt with citation instructions.
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { DeepCitation, wrapCitationPrompt } from "@deepcitation/deepcitation-js";
|
|
54
|
+
|
|
55
|
+
const deepcitation = new DeepCitation({ apiKey: process.env.DEEPCITATION_API_KEY });
|
|
56
|
+
|
|
57
|
+
// Upload source files
|
|
58
|
+
const { fileDataParts, deepTextPromptPortion } = await deepcitation.prepareFiles([
|
|
59
|
+
{ file: pdfBuffer, filename: "report.pdf" },
|
|
60
|
+
]);
|
|
61
|
+
|
|
62
|
+
// Wrap prompts with citation instructions
|
|
63
|
+
const { enhancedSystemPrompt, enhancedUserPrompt } = wrapCitationPrompt({
|
|
64
|
+
systemPrompt: "You are a helpful assistant...",
|
|
65
|
+
userPrompt: "Analyze this document",
|
|
66
|
+
deepTextPromptPortion,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Call your LLM
|
|
70
|
+
const response = await llm.chat({
|
|
71
|
+
messages: [
|
|
72
|
+
{ role: "system", content: enhancedSystemPrompt },
|
|
73
|
+
{ role: "user", content: enhancedUserPrompt },
|
|
74
|
+
],
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Step 2: Post-Prompt
|
|
79
|
+
|
|
80
|
+
Verify citations against the attachments.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const result = await deepcitation.verify({
|
|
84
|
+
llmOutput: response.content,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// result.verifications contains verification status + visual proof
|
|
88
|
+
const { verifications } = result;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Step 3: Display
|
|
92
|
+
|
|
93
|
+
Parse the LLM output and render verified citations inline with React components.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { CitationComponent } from "@deepcitation/deepcitation-js/react";
|
|
97
|
+
import { parseCitation, generateCitationKey } from "@deepcitation/deepcitation-js";
|
|
98
|
+
import "@deepcitation/deepcitation-js/react/styles.css";
|
|
99
|
+
|
|
100
|
+
function Response({ llmOutput, verifications }) {
|
|
101
|
+
const renderWithCitations = (text: string) => {
|
|
102
|
+
const parts = text.split(/(<cite\s+[^>]*\/>)/g);
|
|
103
|
+
|
|
104
|
+
return parts.map((part, index) => {
|
|
105
|
+
if (part.startsWith("<cite")) {
|
|
106
|
+
const { citation } = parseCitation(part);
|
|
107
|
+
const citationKey = generateCitationKey(citation);
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<CitationComponent
|
|
111
|
+
key={index}
|
|
112
|
+
citation={citation}
|
|
113
|
+
verification={verifications[citationKey]}
|
|
114
|
+
/>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
return <span key={index}>{part}</span>;
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
return <div>{renderWithCitations(llmOutput)}</div>;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Examples
|
|
126
|
+
|
|
127
|
+
Check out the [examples directory](./examples) for complete, runnable examples:
|
|
128
|
+
|
|
129
|
+
- [**basic-verification**](./examples/basic-verification) – Core 3-step workflow
|
|
130
|
+
- [**nextjs-ai-sdk**](./examples/nextjs-ai-sdk) – Full-stack Next.js chat app
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
cd examples/basic-verification
|
|
134
|
+
npm install
|
|
135
|
+
cp .env.example .env # Add your API keys
|
|
136
|
+
npm run start:openai
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Supported Formats
|
|
140
|
+
|
|
141
|
+
- **Documents:** PDF (Text & Scanned), DOCX, XLSX, PPTX, HTML
|
|
142
|
+
- **Images:** JPG, PNG, TIFF, WebP, HEIC
|
|
143
|
+
- **Web:** Public URLs
|
|
144
|
+
|
|
145
|
+
## Support
|
|
146
|
+
|
|
147
|
+
- **Feature requests:** [GitHub Discussions](https://github.com/deepcitation/deepcitation-js/discussions)
|
|
148
|
+
- **Bug reports:** [GitHub Issues](https://github.com/deepcitation/deepcitation-js/issues)
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
We welcome contributions! Please start a discussion in [GitHub Discussions](https://github.com/deepcitation/deepcitation-js/discussions) before submitting a pull request.
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT License - see [LICENSE](./LICENSE) for details.
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
'use strict';var
|
|
2
|
-
exports.a=h
|
|
1
|
+
'use strict';var chunkALJ2ZQ2S_cjs=require('./chunk-ALJ2ZQ2S.cjs'),chunkBYLIBOAU_cjs=require('./chunk-BYLIBOAU.cjs');var P="https://api.deepcitation.com";function F(p,t){if(typeof Buffer<"u"&&Buffer.isBuffer(p)){let e=Uint8Array.from(p);return {blob:new Blob([e]),name:t||"document"}}if(p instanceof Blob)return {blob:p,name:t||(p instanceof File?p.name:"document")};throw new Error("Invalid file type. Expected File, Blob, or Buffer.")}async function d(p,t){return (await p.json().catch(()=>({})))?.error?.message||`${t} failed with status ${p.status}`}var h=class{constructor(t){chunkBYLIBOAU_cjs.a(this,"apiKey");chunkBYLIBOAU_cjs.a(this,"apiUrl");if(!t.apiKey)throw new Error("DeepCitation API key is required. Get one at https://deepcitation.com/dashboard");this.apiKey=t.apiKey,this.apiUrl=t.apiUrl?.replace(/\/$/,"")||P;}async uploadFile(t,e){let{blob:l,name:r}=F(t,e?.filename),o=new FormData;o.append("file",l,r),e?.attachmentId&&o.append("attachmentId",e.attachmentId),e?.filename&&o.append("filename",e.filename);let i=await fetch(`${this.apiUrl}/prepareFile`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:o});if(!i.ok)throw new Error(await d(i,"Upload"));return await i.json()}async convertToPdf(t){let e=typeof t=="string"?{url:t}:t,{url:l,file:r,filename:o,attachmentId:i}=e;if(!l&&!r)throw new Error("Either url or file must be provided");let n;if(l)n=await fetch(`${this.apiUrl}/convertFile`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify({url:l,filename:o,attachmentId:i})});else {let{blob:f,name:s}=F(r,o),a=new FormData;a.append("file",f,s),i&&a.append("attachmentId",i),o&&a.append("filename",o),n=await fetch(`${this.apiUrl}/convertFile`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:a});}if(!n.ok)throw new Error(await d(n,"Conversion"));return await n.json()}async prepareConvertedFile(t){let e=await fetch(`${this.apiUrl}/prepareFile`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify({attachmentId:t.attachmentId})});if(!e.ok)throw new Error(await d(e,"Prepare"));return await e.json()}async prepareFiles(t){if(t.length===0)return {fileDataParts:[],deepTextPromptPortion:[]};let e=t.map(({file:i,filename:n,attachmentId:f})=>this.uploadFile(i,{filename:n,attachmentId:f}).then(s=>({result:s,filename:n}))),r=(await Promise.all(e)).map(({result:i,filename:n})=>({attachmentId:i.attachmentId,deepTextPromptPortion:i.deepTextPromptPortion,filename:n||i.metadata?.filename})),o=r.map(i=>i.deepTextPromptPortion);return {fileDataParts:r,deepTextPromptPortion:o}}async verifyAttachment(t,e,l){let r={};if(Array.isArray(e))for(let s of e){let a=chunkALJ2ZQ2S_cjs.d(s);r[a]=s;}else if(typeof e=="object"&&e!==null)if("fullPhrase"in e||"value"in e){let s=chunkALJ2ZQ2S_cjs.d(e);r[s]=e;}else Object.assign(r,e);else throw new Error("Invalid citations format");if(Object.keys(r).length===0)return {verifications:{}};let o=`${this.apiUrl}/verifyCitations`,i={data:{attachmentId:t,citations:r,outputImageFormat:l?.outputImageFormat||"avif"}},n=await fetch(o,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify(i)});if(!n.ok)throw new Error(await d(n,"Verification"));return await n.json()}async verify(t,e){let{llmOutput:l,outputImageFormat:r="avif"}=t;if(e||(e=chunkALJ2ZQ2S_cjs.v(l)),Object.keys(e).length===0)return {verifications:{}};let o=new Map;for(let[a,c]of Object.entries(e)){let m=c.attachmentId||"";o.has(m)||o.set(m,{}),o.get(m)[a]=c;}let i=[],n={};for(let[a,c]of o)a?i.push(this.verifyAttachment(a,c,{outputImageFormat:r})):(Object.assign(n,c),typeof console<"u"&&console.warn&&console.warn(`[DeepCitation] ${Object.keys(c).length} citation(s) skipped: missing attachmentId`));let f=await Promise.all(i),s={};for(let a of f)Object.assign(s,a.verifications);for(let a of Object.keys(n))s[a]={status:"skipped"};return {verifications:s}}};
|
|
2
|
+
exports.a=h;//# sourceMappingURL=chunk-4ILSZKAP.cjs.map
|
|
3
|
+
//# sourceMappingURL=chunk-4ILSZKAP.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/DeepCitation.ts"],"names":["DEFAULT_API_URL","toBlob","file","filename","uint8","extractErrorMessage","response","fallbackAction","DeepCitation","config","__publicField","options","blob","name","formData","input","inputObj","url","attachmentId","files","uploadPromises","result","fileDataParts","deepTextPromptPortion","part","citations","citationMap","citation","key","generateCitationKey","requestUrl","requestBody","llmOutput","outputImageFormat","getAllCitationsFromLlmOutput","citationsByAttachment","verificationPromises","skippedCitations","fileCitations","results","allVerifications"],"mappings":"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","file":"chunk-4ILSZKAP.cjs","sourcesContent":["import { getAllCitationsFromLlmOutput } from \"../parsing/parseCitation.js\";\nimport { generateCitationKey } from \"../react/utils.js\";\nimport type { Citation } from \"../types/index.js\";\nimport type {\n CitationInput,\n ConvertFileInput,\n ConvertFileResponse,\n DeepCitationConfig,\n FileDataPart,\n FileInput,\n PrepareConvertedFileOptions,\n PrepareFilesResult,\n UploadFileOptions,\n UploadFileResponse,\n VerifyInput,\n VerifyCitationsOptions,\n VerifyCitationsResponse,\n} from \"./types.js\";\n\nconst DEFAULT_API_URL = \"https://api.deepcitation.com\";\n\n/** Convert File/Blob/Buffer to a Blob suitable for FormData */\nfunction toBlob(\n file: File | Blob | Buffer,\n filename?: string\n): { blob: Blob; name: string } {\n if (typeof Buffer !== \"undefined\" && Buffer.isBuffer(file)) {\n const uint8 = Uint8Array.from(file);\n return { blob: new Blob([uint8]), name: filename || \"document\" };\n }\n if (file instanceof Blob) {\n return {\n blob: file,\n name: filename || (file instanceof File ? file.name : \"document\"),\n };\n }\n throw new Error(\"Invalid file type. Expected File, Blob, or Buffer.\");\n}\n\n/** Extract error message from API response */\nasync function extractErrorMessage(\n response: Response,\n fallbackAction: string\n): Promise<string> {\n const error = await response.json().catch(() => ({}));\n return (\n error?.error?.message ||\n `${fallbackAction} failed with status ${response.status}`\n );\n}\n\n/**\n * DeepCitation client for file upload and citation verification.\n *\n * @example\n * ```typescript\n * import { DeepCitation } from '@deepcitation/deepcitation-js';\n *\n * const dc = new DeepCitation({ apiKey: process.env.DEEPCITATION_API_KEY });\n *\n * // Upload a file\n * const { attachmentId, promptContent } = await deepcitation.uploadFile(file);\n *\n * // Include promptContent in your LLM messages\n * const response = await llm.chat({\n * messages: [\n * { role: \"system\", content: wrapSystemCitationPrompt({ systemPrompt }) },\n * { role: \"user\", content: userMessage + \"\\n\\n\" + promptContent },\n * ]\n * });\n *\n * // Verify citations in the LLM output\n * const citations = getAllCitationsFromLlmOutput(response);\n * const verified = await deepcitation.verifyCitations(attachmentId, citations);\n * ```\n */\nexport class DeepCitation {\n private readonly apiKey: string;\n private readonly apiUrl: string;\n\n /**\n * Create a new DeepCitation client instance.\n *\n * @param config - Configuration options\n * @throws Error if apiKey is not provided\n */\n constructor(config: DeepCitationConfig) {\n if (!config.apiKey) {\n throw new Error(\n \"DeepCitation API key is required. Get one at https://deepcitation.com/dashboard\"\n );\n }\n this.apiKey = config.apiKey;\n this.apiUrl = config.apiUrl?.replace(/\\/$/, \"\") || DEFAULT_API_URL;\n }\n\n /**\n * Upload a file for citation verification.\n *\n * Supported file types:\n * - PDF documents\n * - Images (PNG, JPEG, WebP, AVIF, HEIC)\n * - Coming soon: DOCX, XLSX, plain text\n *\n * @param file - The file to upload (File, Blob, or Buffer)\n * @param options - Optional upload options\n * @returns Upload response with attachmentId and extracted text\n *\n * @example\n * ```typescript\n * // Browser with File object\n * const file = document.querySelector('input[type=\"file\"]').files[0];\n * const result = await deepcitation.uploadFile(file);\n *\n * // Node.js with Buffer\n * const buffer = fs.readFileSync('document.pdf');\n * const result = await deepcitation.uploadFile(buffer, { filename: 'document.pdf' });\n * ```\n */\n async uploadFile(\n file: File | Blob | Buffer,\n options?: UploadFileOptions\n ): Promise<UploadFileResponse> {\n const { blob, name } = toBlob(file, options?.filename);\n const formData = new FormData();\n formData.append(\"file\", blob, name);\n\n if (options?.attachmentId) formData.append(\"attachmentId\", options.attachmentId);\n if (options?.filename) formData.append(\"filename\", options.filename);\n\n const response = await fetch(`${this.apiUrl}/prepareFile`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n body: formData,\n });\n\n if (!response.ok) {\n throw new Error(await extractErrorMessage(response, \"Upload\"));\n }\n\n return (await response.json()) as UploadFileResponse;\n }\n\n /**\n * Convert a URL or Office file to PDF for citation verification.\n * The converted file can then be processed with prepareConvertedFile().\n *\n * Supported Office formats:\n * - Microsoft Word (.doc, .docx)\n * - Microsoft Excel (.xls, .xlsx)\n * - Microsoft PowerPoint (.ppt, .pptx)\n * - OpenDocument (.odt, .ods, .odp)\n * - Rich Text Format (.rtf)\n * - CSV (.csv)\n *\n * @param input - URL string or object with URL/file options\n * @returns Conversion result with attachmentId for prepareConvertedFile\n *\n * @example\n * ```typescript\n * // Convert a URL to PDF\n * const result = await deepcitation.convertToPdf({ url: \"https://example.com/article\" });\n *\n * // Convert an Office document\n * const result = await deepcitation.convertToPdf({\n * file: docxBuffer,\n * filename: \"report.docx\"\n * });\n *\n * // Then prepare the file for verification\n * const { deepTextPromptPortion, attachmentId } = await deepcitation.prepareConvertedFile({\n * attachmentId: result.attachmentId\n * });\n * ```\n */\n async convertToPdf(\n input: ConvertFileInput | string\n ): Promise<ConvertFileResponse> {\n const inputObj: ConvertFileInput =\n typeof input === \"string\" ? { url: input } : input;\n const { url, file, filename, attachmentId } = inputObj;\n\n if (!url && !file) {\n throw new Error(\"Either url or file must be provided\");\n }\n\n let response: Response;\n\n if (url) {\n response = await fetch(`${this.apiUrl}/convertFile`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ url, filename, attachmentId }),\n });\n } else {\n const { blob, name } = toBlob(file!, filename);\n const formData = new FormData();\n formData.append(\"file\", blob, name);\n if (attachmentId) formData.append(\"attachmentId\", attachmentId);\n if (filename) formData.append(\"filename\", filename);\n\n response = await fetch(`${this.apiUrl}/convertFile`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n body: formData,\n });\n }\n\n if (!response.ok) {\n throw new Error(await extractErrorMessage(response, \"Conversion\"));\n }\n\n return (await response.json()) as ConvertFileResponse;\n }\n\n /**\n * Prepare a previously converted file for citation verification.\n * Use this after calling convertToPdf() to extract text and get deepTextPromptPortion.\n *\n * @param options - Options with attachmentId from convertFile\n * @returns Upload response with attachmentId and extracted text\n *\n * @example\n * ```typescript\n * // First convert the file\n * const converted = await deepcitation.convertToPdf({ url: \"https://example.com/article\" });\n *\n * // Then prepare it for verification\n * const { deepTextPromptPortion, attachmentId } = await deepcitation.prepareConvertedFile({\n * attachmentId: converted.attachmentId\n * });\n *\n * // Use deepTextPromptPortion in your LLM prompt...\n * ```\n */\n async prepareConvertedFile(\n options: PrepareConvertedFileOptions\n ): Promise<UploadFileResponse> {\n const response = await fetch(`${this.apiUrl}/prepareFile`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n attachmentId: options.attachmentId,\n }),\n });\n\n if (!response.ok) {\n throw new Error(await extractErrorMessage(response, \"Prepare\"));\n }\n\n return (await response.json()) as UploadFileResponse;\n }\n\n /**\n * Upload multiple files for citation verification and get structured content.\n * This is the recommended way to prepare files for LLM prompts.\n *\n * @param files - Array of files to upload with optional filenames and attachmentIds\n * @returns Object containing fileDataParts for verification and deepTextPromptPortion for LLM\n *\n * @example\n * ```typescript\n * const { fileDataParts, deepTextPromptPortion } = await deepcitation.prepareFiles([\n * { file: pdfBuffer, filename: \"report.pdf\" },\n * { file: invoiceBuffer, filename: \"invoice.pdf\" },\n * ]);\n *\n * // Use deepTextPromptPortion in wrapCitationPrompt\n * const { enhancedSystemPrompt, enhancedUserPrompt } = wrapCitationPrompt({\n * systemPrompt,\n * userPrompt,\n * deepTextPromptPortion\n * });\n *\n * // Use fileDataParts later for verification\n * const result = await deepcitation.verifyAll({ llmOutput, fileDataParts });\n * ```\n */\n async prepareFiles(files: FileInput[]): Promise<PrepareFilesResult> {\n if (files.length === 0) {\n return { fileDataParts: [], deepTextPromptPortion: [] };\n }\n\n // Upload all files in parallel\n const uploadPromises = files.map(({ file, filename, attachmentId }) =>\n this.uploadFile(file, { filename, attachmentId }).then((result) => ({\n result,\n filename,\n }))\n );\n\n const uploadResults = await Promise.all(uploadPromises);\n\n // Extract file data parts with deepTextPromptPortion included (single source of truth)\n const fileDataParts: FileDataPart[] = uploadResults.map(\n ({ result, filename }) => ({\n attachmentId: result.attachmentId,\n deepTextPromptPortion: result.deepTextPromptPortion,\n filename: filename || result.metadata?.filename,\n })\n );\n\n // Also return separate array for backwards compatibility (deprecated)\n const deepTextPromptPortion: string[] = fileDataParts.map(\n (part) => part.deepTextPromptPortion\n );\n\n return { fileDataParts, deepTextPromptPortion };\n }\n\n /**\n * Verify citations against a single attachment/file.\n *\n * For most use cases, prefer `verify()` which automatically parses citations\n * from LLM output and handles multiple attachments. Use this method when you\n * need fine-grained control over per-attachment verification.\n *\n * @param attachmentId - The attachment ID returned from uploadFile\n * @param citations - Citations to verify (from getAllCitationsFromLlmOutput)\n * @param options - Optional verification options\n * @returns Verification results with status and proof images\n *\n * @example\n * ```typescript\n * import { getAllCitationsFromLlmOutput } from '@deepcitation/deepcitation-js';\n *\n * const citations = getAllCitationsFromLlmOutput(llmResponse);\n * const verified = await deepcitation.verifyAttachment(attachmentId, citations);\n *\n * for (const [key, result] of Object.entries(verified.verifications)) {\n * console.log(key, result.status);\n * // \"found\", \"partial_text_found\", \"not_found\", etc.\n * }\n * ```\n */\n async verifyAttachment(\n attachmentId: string,\n citations: CitationInput,\n options?: VerifyCitationsOptions\n ): Promise<VerifyCitationsResponse> {\n // Normalize citations to a map with citation keys\n const citationMap: Record<string, Citation> = {};\n\n if (Array.isArray(citations)) {\n // Array of citations - generate keys\n for (const citation of citations) {\n const key = generateCitationKey(citation);\n citationMap[key] = citation;\n }\n } else if (typeof citations === \"object\" && citations !== null) {\n // Check if it's a single citation or a map\n if (\"fullPhrase\" in citations || \"value\" in citations) {\n // Single citation\n const key = generateCitationKey(citations as Citation);\n citationMap[key] = citations as Citation;\n } else {\n // Already a map\n Object.assign(citationMap, citations);\n }\n } else {\n throw new Error(\"Invalid citations format\");\n }\n\n // If no citations to verify, return empty result\n if (Object.keys(citationMap).length === 0) {\n return { verifications: {} };\n }\n\n const requestUrl = `${this.apiUrl}/verifyCitations`;\n const requestBody = {\n data: {\n attachmentId,\n citations: citationMap,\n outputImageFormat: options?.outputImageFormat || \"avif\",\n },\n };\n\n const response = await fetch(requestUrl, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n throw new Error(await extractErrorMessage(response, \"Verification\"));\n }\n\n const result = (await response.json()) as VerifyCitationsResponse;\n return result;\n }\n\n /**\n * Parse and verify all citations from LLM output.\n *\n * This is the recommended method for citation verification. It automatically:\n * 1. Parses citations from LLM output (no raw content sent to our servers)\n * 2. Groups citations by attachment ID\n * 3. Verifies each attachment in parallel\n *\n * For privacy-conscious users: we only receive the parsed citation metadata,\n * not your raw LLM output. This method is a convenience wrapper that parses\n * locally and makes per-attachment verification calls.\n *\n * @param input - Object containing llmOutput and optional outputImageFormat\n * @param citations - Optional pre-parsed citations (skips parsing if provided)\n * @returns Verification results with status and proof images\n *\n * @example\n * ```typescript\n * const result = await deepcitation.verify({\n * llmOutput: response.content,\n * });\n *\n * for (const [key, verification] of Object.entries(result.verifications)) {\n * console.log(key, verification.status);\n * }\n * ```\n */\n async verify(\n input: VerifyInput,\n citations?: { [key: string]: Citation }\n ): Promise<VerifyCitationsResponse> {\n const { llmOutput, outputImageFormat = \"avif\" } = input;\n\n // Parse citations from LLM output\n if (!citations) citations = getAllCitationsFromLlmOutput(llmOutput);\n\n // If no citations found, return empty result\n if (Object.keys(citations).length === 0) {\n return { verifications: {} };\n }\n\n // Group citations by attachmentId\n const citationsByAttachment = new Map<string, Record<string, Citation>>();\n for (const [key, citation] of Object.entries(citations)) {\n const attachmentId = citation.attachmentId || \"\";\n if (!citationsByAttachment.has(attachmentId)) {\n citationsByAttachment.set(attachmentId, {});\n }\n citationsByAttachment.get(attachmentId)![key] = citation;\n }\n\n const verificationPromises: Promise<VerifyCitationsResponse>[] = [];\n const skippedCitations: Record<string, Citation> = {};\n\n for (const [attachmentId, fileCitations] of citationsByAttachment) {\n if (attachmentId) {\n verificationPromises.push(\n this.verifyAttachment(attachmentId, fileCitations, { outputImageFormat })\n );\n } else {\n Object.assign(skippedCitations, fileCitations);\n if (typeof console !== \"undefined\" && console.warn) {\n console.warn(\n `[DeepCitation] ${Object.keys(fileCitations).length} citation(s) skipped: missing attachmentId`\n );\n }\n }\n }\n\n const results = await Promise.all(verificationPromises);\n const allVerifications: VerifyCitationsResponse[\"verifications\"] = {};\n for (const result of results) {\n Object.assign(allVerifications, result.verifications);\n }\n\n for (const key of Object.keys(skippedCitations)) {\n allVerifications[key] = { status: \"skipped\" };\n }\n\n return { verifications: allVerifications };\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-5XGN7UAV.js"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
'use strict';function Z(t){return new TextEncoder().encode(t)}function W(t){let e=1732584193,s=4023233417,r=2562383102,n=271733878,a=3285377520,y=t.length,h=y*8,o=y+1+8,i=Math.ceil(o/64)*64,u=new ArrayBuffer(i),k=new Uint8Array(u),c=new DataView(u);k.set(t),k[y]=128,c.setUint32(i-8,Math.floor(h/4294967296),false),c.setUint32(i-4,h>>>0,false);let d=new Uint32Array(80);for(let f=0;f<i;f+=64){for(let m=0;m<16;m++)d[m]=c.getUint32(f+m*4,false);for(let m=16;m<80;m++){let A=d[m-3]^d[m-8]^d[m-14]^d[m-16];d[m]=A<<1|A>>>31;}let C=e,g=s,l=r,x=n,b=a;for(let m=0;m<80;m++){let A,_;m<20?(A=g&l|~g&x,_=1518500249):m<40?(A=g^l^x,_=1859775393):m<60?(A=g&l|g&x|l&x,_=2400959708):(A=g^l^x,_=3395469782);let p=(C<<5|C>>>27)+A+b+_+d[m]>>>0;b=x,x=l,l=(g<<30|g>>>2)>>>0,g=C,C=p;}e=e+C>>>0,s=s+g>>>0,r=r+l>>>0,n=n+x>>>0,a=a+b>>>0;}let I=f=>f.toString(16).padStart(8,"0");return I(e)+I(s)+I(r)+I(n)+I(a)}function R(t){try{if(!t)return "";let e=typeof t=="string"?t:JSON.stringify(t);return W(Z(e))}catch(e){console.error("Error in making the hash:",e);}return ""}var v=new Map;function U(t){let e=v.get(t);return e||(e=new RegExp(`${t}='((?:[^'\\\\]|\\\\.)*)'`),v.set(t,e)),e}function D(t){if(!t)return;let e=[],s=t.split(",");for(let r of s){let n=r.trim();if(n)if(n.includes("-")){let[a,y]=n.split("-"),h=parseInt(a,10),o=parseInt(y,10);if(!isNaN(h)&&!isNaN(o)&&h<=o)for(let i=h;i<=o;i++)e.push(i);else isNaN(h)||e.push(h);}else {let a=parseInt(n,10);isNaN(a)||e.push(a);}}if(e.length!==0)return [...new Set(e)].sort((r,n)=>r-n)}function O(t){let e=t?.status,s=["not_found"].includes(e||""),r=["found","found_key_span_only","found_phrase_missed_value"].includes(e||""),n=["partial_text_found","found_on_other_page","found_on_other_line","first_word_found"].includes(e||""),a=["pending","loading",null,void 0].includes(e);return {isVerified:r,isMiss:s,isPartialMatch:n,isPending:a}}var B=(t,e,s,r)=>{let n=_=>{if(!_)return;let p=_;return (p.startsWith("'")||p.startsWith('"'))&&(p=p.slice(1)),(p.endsWith("'")||p.endsWith('"'))&&!p.endsWith("\\'")&&!p.endsWith('\\"')&&(p=p.slice(0,-1)),p=p.replace(/\\"/g,'"'),p=p.replace(/\\'/g,"'"),p=p.replace(/\\n/g," "),p=p.replace(/\\\\/g,"\\"),p},a=s?.current?s.current++:void 0,y=t.substring(0,t.indexOf("<cite")),h=t.includes("/>")?t.slice(t.indexOf("/>")+2):"",o=t.substring(t.indexOf("<cite"),t.indexOf("/>")+2),i=(_,p)=>{for(let w of p){let P=U(w),T=_.match(P);if(T)return T[1]}},u=i(o,["attachment_id","attachmentId","file_id","fileId"]),k=u?.length===20?u:e||u,c=i(o,["start_page_key","startPageKey","start_page"]),d,I;if(c){let _=c.match(/page[\_a-zA-Z]*(\d+)_index_(\d+)/);_&&(d=parseInt(_[1]),I=parseInt(_[2]));}let f=n(i(o,["full_phrase","fullPhrase"])),C=n(i(o,["key_span","keySpan"])),g=n(i(o,["reasoning"])),l=n(i(o,["value"])),x;try{let p=i(o,["line_ids","lineIds"])?.replace(/[A-Za-z_[\](){}:]/g,"");x=p?D(p):void 0;}catch(_){r&&console.error("Error parsing lineIds",_);}let b=i(o,["timestamps"]),m;if(b){let[_,p]=b.split("-")||[];m={startTime:_,endTime:p};}let A={attachmentId:k,pageNumber:d,startPageKey:`page_number_${d||1}_index_${I||0}`,fullPhrase:f,keySpan:C||l,citationNumber:a,lineIds:x,beforeCite:y,timestamps:m,reasoning:g};return {beforeCite:y,afterCite:h,citation:A}},J=(t,e)=>{if(!t)return null;let s=t.fullPhrase??t.full_phrase,r=t.startPageKey??t.start_page_key,n=t.keySpan??t.key_span,a=t.lineIds??t.line_ids,y=t.attachmentId??t.attachment_id??t.fileId??t.file_id,h=t.reasoning,o=t.value;if(!s)return null;let i;if(r){let c=r.match(/page[_a-zA-Z]*(\d+)_index_(\d+)/i);if(c)i=parseInt(c[1],10);else {let d=r.match(/^(\d+)_(\d+)$/);d&&(i=parseInt(d[1],10));}}let u=a?.length?[...a].sort((c,d)=>c-d):void 0;return {attachmentId:y,pageNumber:i,fullPhrase:s,citationNumber:e,lineIds:u,keySpan:n||o,reasoning:h}},M=t=>typeof t=="object"&&t!==null&&("fullPhrase"in t||"full_phrase"in t||"startPageKey"in t||"start_page_key"in t||"keySpan"in t||"key_span"in t||"lineIds"in t||"line_ids"in t),$=t=>Array.isArray(t)?t.length>0&&t.some(M):typeof t=="object"&&t!==null?M(t):false,z=t=>{let e={},s=Array.isArray(t)?t:[t],r=1;for(let n of s){let a=J(n,r++);if(a&&a.fullPhrase){let y=S(a);e[y]=a;}}return e},K=(t,e)=>{if(!(!t||typeof t!="object")){if(t.citation&&$(t.citation)){let s=Array.isArray(t.citation)?t.citation:[t.citation];e.push(...s);}if(t.citations&&$(t.citations)){let s=Array.isArray(t.citations)?t.citations:[t.citations];e.push(...s);}if(Array.isArray(t))for(let s of t)K(s,e);else for(let s of Object.keys(t))s!=="citation"&&s!=="citations"&&K(t[s],e);}},V=t=>{let e=E(t),s=/<cite\s+(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|[^'">/])*\/>/g,r=e.match(s);if(!r||r.length===0)return {};let n={},a={current:1};for(let y of r){let{citation:h}=B(y,void 0,a);if(h&&h.fullPhrase){let o=S(h);n[o]=h;}}return n},tt=t=>{if(!t)return {};let e={};if(typeof t=="object"){if($(t)){let n=z(t);Object.assign(e,n);}else {let n=[];if(K(t,n),n.length>0){let a=z(n);Object.assign(e,a);}}let s=JSON.stringify(t),r=V(s);Object.assign(e,r);}else if(typeof t=="string"){let s=V(t);Object.assign(e,s);}return e};function et(t){let e=new Map,s=Array.isArray(t)?t.map((r,n)=>[S(r)||String(n+1),r]):Object.entries(t);for(let[r,n]of s){let a=n.attachmentId||"";e.has(a)||e.set(a,{}),e.get(a)[r]=n;}return e}function nt(t){let e={},s=Array.isArray(t)?t.map((r,n)=>[S(r)||String(n+1),r]):Object.entries(t);for(let[r,n]of s){let a=n.attachmentId||"";e[a]||(e[a]={}),e[a][r]=n;}return e}var F=t=>{let e={},s=/([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(['"])((?:[^'"\\]|\\.)*)\2/g,r;for(;(r=s.exec(t))!==null;){let n=r[1].toLowerCase().replace(/([a-z])([A-Z])/g,"$1_$2").toLowerCase(),a=r[3],y=n==="fileid"||n==="file_id"||n==="attachmentid"?"attachment_id":n==="keyspan"?"key_span":n==="fullphrase"?"full_phrase":n==="lineids"?"line_ids":n==="startpagekey"||n==="start_pagekey"?"start_page_key":n;e[y]=a;}return e},H=t=>{let e=O(t);return e.isMiss?"\u274C":e.isVerified&&!e.isPartialMatch?"\u2611\uFE0F":e.isPartialMatch?"\u2705":e.isPending?"\u231B":"\u25CC"},q=(t,e={})=>{let{leaveKeySpanBehind:s=false,verifications:r,showVerificationStatus:n=false}=e,a=0,y=/<cite\s+[^>]*?\/>/g;return t.replace(y,h=>{a++;let o=F(h),i="";if(s&&o.key_span&&(i=o.key_span.replace(/\\'/g,"'").replace(/\\"/g,'"')),n&&r){let u,k=g=>{if(!g)return;let l=g.match(/page[_a-zA-Z]*(\d+)/);return l?parseInt(l[1],10):void 0},c=g=>{if(!g)return;let x=g.replace(/(\d+)-(\d+)/g,(b,m,A)=>{let _=parseInt(m,10),p=parseInt(A,10);if(_<=p){let w=[];for(let P=_;P<=p;P++)w.push(P);return w.join(",")}return m}).split(",").map(b=>parseInt(b.trim(),10)).filter(b=>!isNaN(b));return x.length>0?x:void 0},d=g=>g?.replace(/\\'/g,"'").replace(/\\"/g,'"'),I={attachmentId:o.attachment_id,pageNumber:k(o.start_page_key),fullPhrase:d(o.full_phrase),keySpan:d(o.key_span),lineIds:c(o.line_ids)},f=S(I);if(u=r[f],!u){let g=String(a);u=r[g];}let C=H(u);i=i?`${i}${C}`:C;}return i})},at=(t,e)=>q(t,{leaveKeySpanBehind:e}),ot=t=>t.replace(/<page_number_\d+_index_\d+>/g,"").replace(/<\/page_number_\d+_index_\d+>/g,"").trim(),ct=t=>{let e=/<line id="[^"]*">|<\/line>/g;return t.replace(e,"")},L=t=>{if(!t)return null;let e=t.match(/\d+/)?.[0];return e?parseInt(e):null},G=t=>{let e=t.match(/^(<cite\s+(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|[^'">/])*>)([\s\S]*?)<\/cite>$/);if(!e){let h=t.match(/^(<cite\s+(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|[^'">/])*>)$/);if(h){let o=h[1].replace(/>$/," />");return N(o)}return N(t)}let[,s,r]=e;if(!r||!r.trim())return N(t);let n=s.replace(/>$/," />"),a=r.trim(),y=N(n);return a+y},E=t=>{let e=t?.trim()||"";e=e.replace(/(?<![<a-zA-Z])cite\s+(attachment_id|file_id|fileId|attachmentId)\s*=/gi,"<cite $1=");let s=e.split(/(<cite[\s\S]*?(?:\/>|<\/cite>|>(?=\s*$|[\r\n])(?![\s\S]*<\/cite>)))/gm);if(s.length<=1){let r=e.match(/<cite\s+(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|[^'">/])*>/g);if(r&&r.length>0){let n=e.replace(/<cite\s+(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|[^'">/])*>/g,a=>a.replace(/>$/," />"));return N(n)}return N(e)}return e=s.map(r=>r.startsWith("<cite")?G(r):r).join(""),e},N=t=>{let e=t;e=e.replace(/\\_/g,"_"),e=e.replace(/><\/cite>/g,"/>");let s=o=>{let i=o.toLowerCase();return i==="fullphrase"||i==="full_phrase"?"full_phrase":i==="lineids"||i==="line_ids"?"line_ids":i==="startpagekey"||i==="start_pagekey"||i==="start_page_key"?"start_page_key":i==="fileid"||i==="file_id"||i==="attachmentid"||i==="attachment_id"?"attachment_id":i==="keyspan"||i==="key_span"?"key_span":i==="reasoning"||i==="value"?i:i==="timestamps"||i==="timestamp"||i==="timestamps"?"timestamps":i},r={""":'"',"'":"'","<":"<",">":">","&":"&"},n=/&(?:quot|apos|lt|gt|amp);/g,a=o=>o.replace(n,i=>r[i]||i),y=/(fullPhrase|full_phrase|keySpan|key_span|reasoning|value)\s*=\s*(['"])([\s\S]*?)(?=\s+(?:line_ids|lineIds|timestamps|fileId|file_id|attachmentId|attachment_id|start_page_key|start_pageKey|startPageKey|keySpan|key_span|reasoning|value|full_phrase)\s*=|\s*\/>|['"]>)/gm;e=e.replace(y,(o,i,u,k)=>{let c=k;return c.endsWith(u)&&(c=c.slice(0,-1)),c=c.replace(/(\r?\n)+|(\*|_){2,}|\*/g,d=>d.includes(`
|
|
2
|
-
`)||d.includes("\r")?" ":""),c=a(c),c=c.replace(/\\\\'/g,"'").replace(/\\'/g,"'").replace(/'/g,"\\'"),c=c.replace(/\\\\"/g,'"').replace(/\\"/g,'"').replace(/"/g,'\\"'),`${s(i)}='${c}'`}),e=e.replace(/(line_ids|lineIds|timestamps)=['"]?([\[\]\(\){}A-Za-z0-9_\-, ]+)['"]?(\s*\/?>|\s+)/gm,(o,i,u,k)=>{let c=u.replace(/[A-Za-z\[\]\(\){}]/g,"");return c=c.replace(/(\d+)-(\d+)/g,(d,I,f)=>{let C=parseInt(I,10),g=parseInt(f,10),l=[];if(C<=g)for(let x=C;x<=g;x++)l.push(x);else l.push(C);return l.join(",")}),c=c.replace(/,+/g,",").replace(/^,|,$/g,""),`${s(i)}='${c}'${k}`});let h=o=>{let i=/([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(['"])((?:[^'"\\\n]|\\.)*)(?:\2)/g,u={},k;for(;k=i.exec(o);){let l=k[1],x=k[3],b=s(l);u[b]=x;}let c=Object.keys(u);if(c.length===0)return o;let d=typeof u.timestamps=="string"&&u.timestamps.length>0,I=c.filter(l=>l.startsWith("start_page")),f=[];u.attachment_id&&f.push("attachment_id"),d?(u.full_phrase&&f.push("full_phrase"),u.key_span&&f.push("key_span"),f.push("timestamps")):(I.includes("start_page_key")&&f.push("start_page_key"),I.filter(l=>l!=="start_page_key").sort().forEach(l=>f.push(l)),u.full_phrase&&f.push("full_phrase"),u.key_span&&f.push("key_span"),u.line_ids&&f.push("line_ids")),u.reasoning&&f.push("reasoning"),u.value&&f.push("value");let C=new Set(f);return c.filter(l=>!C.has(l)).sort().forEach(l=>f.push(l)),`<cite ${f.map(l=>`${l}='${u[l]}'`).join(" ")} />`};return e=e.replace(/<cite\b[\s\S]*?\/>/gm,o=>h(o)),e};function ft(...t){return t.filter(Boolean).join(" ")}function X(t){return t.type==="url"||typeof t.url=="string"&&t.url.length>0}function S(t){let e=t.pageNumber||L(t.startPageKey),s=[t.attachmentId||"",e?.toString()||"",t.fullPhrase||"",t.keySpan?.toString()||"",t.lineIds?.join(",")||"",t.timestamps?.startTime||"",t.timestamps?.endTime||""];return X(t)&&s.push(t.url||"",t.title||"",t.domain||""),R(s.join("|")).slice(0,16)}function gt(t){let e=[t.attachmentId||"",t.label||"",t.verifiedFullPhrase||"",t.verifiedKeySpan||"",t.verifiedLineIds?.join(",")||"",t.verifiedPageNumber?.toString()||"",t.verifiedTimestamps?.startTime||"",t.verifiedTimestamps?.endTime||"",t.verifiedMatchSnippet||"",t.hitIndexWithinPage?.toString()||""];return R(e.join("|")).slice(0,16)}function dt(t){let e=Math.random().toString(36).slice(2,11);return `${t}-${e}`}function mt(t,e={}){let{fallbackDisplay:s}=e;return t.keySpan?.toString()||t.citationNumber?.toString()||s||"1"}function ht(t){return t.citationNumber?.toString()||"1"}function yt(t){return t.keySpan?.toString()||""}function _t(...t){return t.filter(Boolean).join(" ")}var xt=4,Ct=1;exports.a=R;exports.b=ft;exports.c=X;exports.d=S;exports.e=gt;exports.f=dt;exports.g=mt;exports.h=ht;exports.i=yt;exports.j=_t;exports.k=xt;exports.l=Ct;exports.m=H;exports.n=q;exports.o=at;exports.p=ot;exports.q=ct;exports.r=L;exports.s=E;exports.t=O;exports.u=B;exports.v=tt;exports.w=et;exports.x=nt
|
|
2
|
+
`)||d.includes("\r")?" ":""),c=a(c),c=c.replace(/\\\\'/g,"'").replace(/\\'/g,"'").replace(/'/g,"\\'"),c=c.replace(/\\\\"/g,'"').replace(/\\"/g,'"').replace(/"/g,'\\"'),`${s(i)}='${c}'`}),e=e.replace(/(line_ids|lineIds|timestamps)=['"]?([\[\]\(\){}A-Za-z0-9_\-, ]+)['"]?(\s*\/?>|\s+)/gm,(o,i,u,k)=>{let c=u.replace(/[A-Za-z\[\]\(\){}]/g,"");return c=c.replace(/(\d+)-(\d+)/g,(d,I,f)=>{let C=parseInt(I,10),g=parseInt(f,10),l=[];if(C<=g)for(let x=C;x<=g;x++)l.push(x);else l.push(C);return l.join(",")}),c=c.replace(/,+/g,",").replace(/^,|,$/g,""),`${s(i)}='${c}'${k}`});let h=o=>{let i=/([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(['"])((?:[^'"\\\n]|\\.)*)(?:\2)/g,u={},k;for(;k=i.exec(o);){let l=k[1],x=k[3],b=s(l);u[b]=x;}let c=Object.keys(u);if(c.length===0)return o;let d=typeof u.timestamps=="string"&&u.timestamps.length>0,I=c.filter(l=>l.startsWith("start_page")),f=[];u.attachment_id&&f.push("attachment_id"),d?(u.full_phrase&&f.push("full_phrase"),u.key_span&&f.push("key_span"),f.push("timestamps")):(I.includes("start_page_key")&&f.push("start_page_key"),I.filter(l=>l!=="start_page_key").sort().forEach(l=>f.push(l)),u.full_phrase&&f.push("full_phrase"),u.key_span&&f.push("key_span"),u.line_ids&&f.push("line_ids")),u.reasoning&&f.push("reasoning"),u.value&&f.push("value");let C=new Set(f);return c.filter(l=>!C.has(l)).sort().forEach(l=>f.push(l)),`<cite ${f.map(l=>`${l}='${u[l]}'`).join(" ")} />`};return e=e.replace(/<cite\b[\s\S]*?\/>/gm,o=>h(o)),e};function ft(...t){return t.filter(Boolean).join(" ")}function X(t){return t.type==="url"||typeof t.url=="string"&&t.url.length>0}function S(t){let e=t.pageNumber||L(t.startPageKey),s=[t.attachmentId||"",e?.toString()||"",t.fullPhrase||"",t.keySpan?.toString()||"",t.lineIds?.join(",")||"",t.timestamps?.startTime||"",t.timestamps?.endTime||""];return X(t)&&s.push(t.url||"",t.title||"",t.domain||""),R(s.join("|")).slice(0,16)}function gt(t){let e=[t.attachmentId||"",t.label||"",t.verifiedFullPhrase||"",t.verifiedKeySpan||"",t.verifiedLineIds?.join(",")||"",t.verifiedPageNumber?.toString()||"",t.verifiedTimestamps?.startTime||"",t.verifiedTimestamps?.endTime||"",t.verifiedMatchSnippet||"",t.hitIndexWithinPage?.toString()||""];return R(e.join("|")).slice(0,16)}function dt(t){let e=Math.random().toString(36).slice(2,11);return `${t}-${e}`}function mt(t,e={}){let{fallbackDisplay:s}=e;return t.keySpan?.toString()||t.citationNumber?.toString()||s||"1"}function ht(t){return t.citationNumber?.toString()||"1"}function yt(t){return t.keySpan?.toString()||""}function _t(...t){return t.filter(Boolean).join(" ")}var xt=4,Ct=1;exports.a=R;exports.b=ft;exports.c=X;exports.d=S;exports.e=gt;exports.f=dt;exports.g=mt;exports.h=ht;exports.i=yt;exports.j=_t;exports.k=xt;exports.l=Ct;exports.m=H;exports.n=q;exports.o=at;exports.p=ot;exports.q=ct;exports.r=L;exports.s=E;exports.t=O;exports.u=B;exports.v=tt;exports.w=et;exports.x=nt;//# sourceMappingURL=chunk-ALJ2ZQ2S.cjs.map
|
|
3
|
+
//# sourceMappingURL=chunk-ALJ2ZQ2S.cjs.map
|