@cloro-dev/response-parser 0.1.5 → 0.2.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 +149 -102
- package/dist/core/detector.d.ts.map +1 -1
- package/dist/core/parser.d.ts.map +1 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +17 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/ai-mode.d.ts.map +1 -1
- package/dist/providers/chatgpt.d.ts.map +1 -1
- package/dist/providers/copilot.d.ts.map +1 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/{react/providers/perplexity.d.ts → providers/grok.d.ts} +5 -5
- package/dist/providers/grok.d.ts.map +1 -0
- package/package.json +4 -29
- package/dist/react/components/AiResponseRenderer.d.ts +0 -24
- package/dist/react/components/AiResponseRenderer.d.ts.map +0 -1
- package/dist/react/components/IframeRenderer.d.ts +0 -12
- package/dist/react/components/IframeRenderer.d.ts.map +0 -1
- package/dist/react/components/ResponseRenderer.d.ts +0 -24
- package/dist/react/components/ResponseRenderer.d.ts.map +0 -1
- package/dist/react/core/detector.d.ts +0 -17
- package/dist/react/core/detector.d.ts.map +0 -1
- package/dist/react/core/parser.d.ts +0 -40
- package/dist/react/core/parser.d.ts.map +0 -1
- package/dist/react/core/types.d.ts +0 -34
- package/dist/react/core/types.d.ts.map +0 -1
- package/dist/react/hooks/useAiResponse.d.ts +0 -19
- package/dist/react/hooks/useAiResponse.d.ts.map +0 -1
- package/dist/react/hooks/useResponse.d.ts +0 -19
- package/dist/react/hooks/useResponse.d.ts.map +0 -1
- package/dist/react/index.d.ts +0 -86
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.esm.js +0 -2
- package/dist/react/index.esm.js.map +0 -1
- package/dist/react/index.js +0 -2
- package/dist/react/index.js.map +0 -1
- package/dist/react/providers/ai-mode.d.ts +0 -21
- package/dist/react/providers/ai-mode.d.ts.map +0 -1
- package/dist/react/providers/ai-overview.d.ts +0 -21
- package/dist/react/providers/ai-overview.d.ts.map +0 -1
- package/dist/react/providers/base-provider.d.ts +0 -34
- package/dist/react/providers/base-provider.d.ts.map +0 -1
- package/dist/react/providers/chatgpt.d.ts +0 -22
- package/dist/react/providers/chatgpt.d.ts.map +0 -1
- package/dist/react/providers/copilot.d.ts +0 -25
- package/dist/react/providers/copilot.d.ts.map +0 -1
- package/dist/react/providers/gemini.d.ts +0 -21
- package/dist/react/providers/gemini.d.ts.map +0 -1
- package/dist/react/providers/perplexity.d.ts.map +0 -1
- package/dist/react/react/components/AiResponseRenderer.d.ts +0 -24
- package/dist/react/react/components/AiResponseRenderer.d.ts.map +0 -1
- package/dist/react/react/components/IframeRenderer.d.ts +0 -12
- package/dist/react/react/components/IframeRenderer.d.ts.map +0 -1
- package/dist/react/react/components/ResponseRenderer.d.ts +0 -24
- package/dist/react/react/components/ResponseRenderer.d.ts.map +0 -1
- package/dist/react/react/hooks/useAiResponse.d.ts +0 -19
- package/dist/react/react/hooks/useAiResponse.d.ts.map +0 -1
- package/dist/react/react/hooks/useResponse.d.ts +0 -19
- package/dist/react/react/hooks/useResponse.d.ts.map +0 -1
- package/dist/react/react/index.d.ts +0 -7
- package/dist/react/react/index.d.ts.map +0 -1
- package/dist/react/styles/index.d.ts +0 -1
- package/dist/react/styles/index.d.ts.map +0 -1
- package/dist/react/utils/helpers.d.ts +0 -28
- package/dist/react/utils/helpers.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# @cloro-dev/response-parser
|
|
2
2
|
|
|
3
|
-
A powerful TypeScript library for parsing
|
|
3
|
+
A powerful TypeScript library for parsing AI model responses from ChatGPT, Gemini, Perplexity, Copilot, and Google AI Overview/Mode.
|
|
4
|
+
|
|
5
|
+
> **Framework-Agnostic**: This library returns HTML strings that can be rendered in any framework (React, Vue, Svelte, vanilla JS, etc.).
|
|
4
6
|
|
|
5
7
|
## Features
|
|
6
8
|
|
|
7
9
|
- 🤖 **Multi-Provider Support**: ChatGPT, Gemini, Perplexity, Copilot, AI Overview, AI Mode
|
|
8
10
|
- 🔍 **Auto-Detection**: Automatically detects the AI provider from response structure
|
|
9
11
|
- 🎨 **Built-in Styling**: Provider-specific styling with dark mode support
|
|
10
|
-
-
|
|
11
|
-
- 🔒 **Secure**:
|
|
12
|
+
- 🔧 **Framework-Agnostic**: Pure HTML output for any framework
|
|
13
|
+
- 🔒 **Secure**: Automatic script sanitization
|
|
12
14
|
- 📦 **TypeScript**: Full TypeScript support with comprehensive types
|
|
13
15
|
- 🎯 **Lightweight**: No runtime dependencies for core parsing
|
|
14
16
|
|
|
@@ -24,7 +26,7 @@ pnpm add @cloro-dev/response-parser
|
|
|
24
26
|
|
|
25
27
|
## Quick Start
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
This library parses AI responses and returns sanitized HTML strings. You can render the HTML in any framework:
|
|
28
30
|
|
|
29
31
|
```typescript
|
|
30
32
|
import { parseAiResponse, detectProvider } from "@cloro-dev/response-parser";
|
|
@@ -38,35 +40,73 @@ console.log(parsed.html); // Sanitized HTML ready for rendering
|
|
|
38
40
|
console.log(parsed.text); // Plain text version
|
|
39
41
|
```
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
## Usage Examples
|
|
44
|
+
|
|
45
|
+
### React
|
|
42
46
|
|
|
43
47
|
```tsx
|
|
44
|
-
import {
|
|
48
|
+
import { parseAiResponse } from "@cloro-dev/response-parser";
|
|
45
49
|
|
|
46
50
|
function MyComponent() {
|
|
47
|
-
const
|
|
51
|
+
const parsed = parseAiResponse(aiResponse, {
|
|
52
|
+
invertColors: true,
|
|
53
|
+
removeLinks: true
|
|
54
|
+
});
|
|
48
55
|
|
|
49
56
|
return (
|
|
50
|
-
<
|
|
51
|
-
response={aiResponse}
|
|
52
|
-
removeLinks={false}
|
|
53
|
-
invertColors={false}
|
|
54
|
-
autoDetect
|
|
55
|
-
className="w-full h-96"
|
|
56
|
-
iframeProps={{
|
|
57
|
-
sandbox: "allow-popups",
|
|
58
|
-
}}
|
|
59
|
-
onProviderDetected={(provider) => console.log("Detected:", provider)}
|
|
60
|
-
/>
|
|
57
|
+
<div dangerouslySetInnerHTML={{ __html: parsed.html }} />
|
|
61
58
|
);
|
|
62
59
|
}
|
|
63
60
|
```
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
### Vue
|
|
63
|
+
|
|
64
|
+
```vue
|
|
65
|
+
<script setup>
|
|
66
|
+
import { parseAiResponse } from "@cloro-dev/response-parser";
|
|
67
|
+
|
|
68
|
+
const parsed = parseAiResponse(aiResponse, {
|
|
69
|
+
invertColors: true,
|
|
70
|
+
removeLinks: true
|
|
71
|
+
});
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<template>
|
|
75
|
+
<div v-html="parsed.html"></div>
|
|
76
|
+
</template>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Svelte
|
|
80
|
+
|
|
81
|
+
```svelte
|
|
82
|
+
<script>
|
|
83
|
+
import { parseAiResponse } from "@cloro-dev/response-parser";
|
|
84
|
+
|
|
85
|
+
const parsed = parseAiResponse(aiResponse, {
|
|
86
|
+
invertColors: true,
|
|
87
|
+
removeLinks: true
|
|
88
|
+
});
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<div>{@html parsed.html}</div>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Vanilla JavaScript
|
|
95
|
+
|
|
96
|
+
```javascript
|
|
97
|
+
import { parseAiResponse } from "@cloro-dev/response-parser";
|
|
66
98
|
|
|
67
|
-
|
|
99
|
+
const parsed = parseAiResponse(aiResponse, {
|
|
100
|
+
invertColors: true,
|
|
101
|
+
removeLinks: true
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
document.getElementById('output').innerHTML = parsed.html;
|
|
105
|
+
```
|
|
68
106
|
|
|
69
|
-
|
|
107
|
+
## API Reference
|
|
108
|
+
|
|
109
|
+
### `parseAiResponse(response, options?)`
|
|
70
110
|
|
|
71
111
|
Parse an AI response with auto-detected provider.
|
|
72
112
|
|
|
@@ -80,64 +120,35 @@ Parse an AI response with auto-detected provider.
|
|
|
80
120
|
|
|
81
121
|
**Returns:** `ParsedResponse | null`
|
|
82
122
|
|
|
83
|
-
|
|
123
|
+
```typescript
|
|
124
|
+
interface ParsedResponse {
|
|
125
|
+
provider: AIProvider;
|
|
126
|
+
html: string;
|
|
127
|
+
text: string;
|
|
128
|
+
sources?: Array<{
|
|
129
|
+
title: string;
|
|
130
|
+
url: string;
|
|
131
|
+
snippet?: string;
|
|
132
|
+
}>;
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### `detectProvider(response)`
|
|
84
137
|
|
|
85
138
|
Detect the AI provider from a response.
|
|
86
139
|
|
|
87
140
|
**Returns:** `AIProvider | null`
|
|
88
141
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
- `provider`: Explicitly specify provider
|
|
100
|
-
- `removeLinks`: Remove all hyperlinks (default: `false`)
|
|
101
|
-
- `invertColors`: Apply color inversion (default: `false`)
|
|
102
|
-
- `removeHeader`: Remove navigation bar/header (default: `false`, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
|
|
103
|
-
- `removeFooter`: Remove follow-up input box/footer (default: `false`, ChatGPT, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
|
|
104
|
-
- `removeSidebar`: Remove sidebar (default: `false`, ChatGPT, Gemini & Copilot)
|
|
105
|
-
- `className`: CSS class for container
|
|
106
|
-
- `iframeProps`: Additional props for iframe
|
|
107
|
-
- `loadingComponent`: Custom loading component
|
|
108
|
-
- `errorComponent`: Custom error component
|
|
109
|
-
- `fallbackComponent`: Custom fallback component
|
|
110
|
-
- `onRenderComplete`: Callback when rendering completes
|
|
111
|
-
- `onProviderDetected`: Callback when provider is detected
|
|
112
|
-
|
|
113
|
-
### Hooks
|
|
114
|
-
|
|
115
|
-
#### `useResponse(response, options?)`
|
|
116
|
-
|
|
117
|
-
React hook for parsing AI responses.
|
|
118
|
-
|
|
119
|
-
**Options:**
|
|
120
|
-
|
|
121
|
-
- `autoDetect`: Auto-detect provider (default: `true`)
|
|
122
|
-
- `provider`: Explicitly specify provider
|
|
123
|
-
- `removeLinks`: Remove all hyperlinks (default: `false`)
|
|
124
|
-
- `invertColors`: Apply color inversion (default: `false`)
|
|
125
|
-
- `removeHeader`: Remove navigation bar/header (default: `false`, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
|
|
126
|
-
- `removeFooter`: Remove follow-up input box/footer (default: `false`, ChatGPT, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
|
|
127
|
-
- `removeSidebar`: Remove sidebar (default: `false`, ChatGPT, Gemini & Copilot)
|
|
128
|
-
- `onProviderDetected`: Callback when provider is detected
|
|
129
|
-
- `onError`: Callback when error occurs
|
|
130
|
-
|
|
131
|
-
**Returns:**
|
|
132
|
-
|
|
133
|
-
- `parsed`: Parsed response object
|
|
134
|
-
- `provider`: Detected provider
|
|
135
|
-
- `isLoading`: Loading state
|
|
136
|
-
- `error`: Error object
|
|
137
|
-
- `html`: HTML string
|
|
138
|
-
- `text`: Plain text string
|
|
139
|
-
- `sources`: Sources array (if available)
|
|
140
|
-
- `reparse`: Function to re-parse with new options
|
|
142
|
+
```typescript
|
|
143
|
+
type AIProvider =
|
|
144
|
+
| 'CHATGPT'
|
|
145
|
+
| 'GEMINI'
|
|
146
|
+
| 'PERPLEXITY'
|
|
147
|
+
| 'COPILOT'
|
|
148
|
+
| 'AI_OVERVIEW'
|
|
149
|
+
| 'AI_MODE'
|
|
150
|
+
| 'GROK';
|
|
151
|
+
```
|
|
141
152
|
|
|
142
153
|
## Supported Providers
|
|
143
154
|
|
|
@@ -150,7 +161,7 @@ React hook for parsing AI responses.
|
|
|
150
161
|
| AI Overview | ✅ | WIZ data extraction |
|
|
151
162
|
| AI Mode | ✅ | Google UI hiding |
|
|
152
163
|
|
|
153
|
-
##
|
|
164
|
+
## Common Use Cases
|
|
154
165
|
|
|
155
166
|
### Remove Hyperlinks
|
|
156
167
|
|
|
@@ -164,24 +175,22 @@ const parsed = parseAiResponse(response, {
|
|
|
164
175
|
|
|
165
176
|
### Dark Mode
|
|
166
177
|
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
/>
|
|
178
|
+
```typescript
|
|
179
|
+
const parsed = parseAiResponse(response, {
|
|
180
|
+
invertColors: true, // Apply CSS filter for dark mode
|
|
181
|
+
removeLinks: true, // Optionally remove links
|
|
182
|
+
});
|
|
173
183
|
```
|
|
174
184
|
|
|
175
185
|
### Clean View (Remove UI Elements)
|
|
176
186
|
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
/>
|
|
187
|
+
```typescript
|
|
188
|
+
const parsed = parseAiResponse(response, {
|
|
189
|
+
removeHeader: true, // Remove top navigation bar
|
|
190
|
+
removeFooter: true, // Remove follow-up input box
|
|
191
|
+
removeLinks: true, // Remove all hyperlinks
|
|
192
|
+
invertColors: true, // Dark mode
|
|
193
|
+
});
|
|
185
194
|
```
|
|
186
195
|
|
|
187
196
|
### Manual Provider Specification
|
|
@@ -194,21 +203,58 @@ const parsed = parseAiResponse(response, {
|
|
|
194
203
|
});
|
|
195
204
|
```
|
|
196
205
|
|
|
197
|
-
###
|
|
206
|
+
### Provider Detection Only
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import { detectProvider } from "@cloro-dev/response-parser";
|
|
210
|
+
|
|
211
|
+
const provider = detectProvider(response);
|
|
212
|
+
console.log(`Detected: ${provider}`); // 'CHATGPT' | 'GEMINI' | etc.
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Migration from v0.1.x
|
|
216
|
+
|
|
217
|
+
If you were using React components from v0.1.x, here's how to migrate:
|
|
218
|
+
|
|
219
|
+
### Before (v0.1.x with React)
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
import { ResponseRenderer } from "@cloro-dev/response-parser/react";
|
|
223
|
+
|
|
224
|
+
<ResponseRenderer
|
|
225
|
+
response={response}
|
|
226
|
+
invertColors={true}
|
|
227
|
+
removeLinks={true}
|
|
228
|
+
onProviderDetected={(provider) => console.log("Detected:", provider)}
|
|
229
|
+
/>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### After (v0.2.0 framework-agnostic)
|
|
198
233
|
|
|
199
234
|
```tsx
|
|
200
|
-
|
|
201
|
-
<div className="error">
|
|
202
|
-
<p>Failed to load: {error.message}</p>
|
|
203
|
-
<button onClick={retry}>Retry</button>
|
|
204
|
-
</div>
|
|
205
|
-
);
|
|
235
|
+
import { parseAiResponse } from "@cloro-dev/response-parser";
|
|
206
236
|
|
|
207
|
-
|
|
237
|
+
const parsed = parseAiResponse(response, {
|
|
238
|
+
invertColors: true,
|
|
239
|
+
removeLinks: true
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
console.log("Detected:", parsed.provider);
|
|
243
|
+
|
|
244
|
+
<div dangerouslySetInnerHTML={{ __html: parsed.html }} />
|
|
208
245
|
```
|
|
209
246
|
|
|
247
|
+
The core parsing logic is identical - you just need to handle the HTML rendering yourself in your framework of choice.
|
|
248
|
+
|
|
210
249
|
## What's Changed
|
|
211
250
|
|
|
251
|
+
### v0.2.0
|
|
252
|
+
|
|
253
|
+
- ✅ **Removed** React components and hooks (now framework-agnostic)
|
|
254
|
+
- ✅ **Removed** React peer dependency
|
|
255
|
+
- ✅ **Simplified** API to return pure HTML strings
|
|
256
|
+
- ✅ **Keep** core parsing logic (unchanged)
|
|
257
|
+
|
|
212
258
|
### v0.1.4
|
|
213
259
|
|
|
214
260
|
- ✅ **Renamed** `removeNavbar` → `removeHeader` (removes navigation bar/header)
|
|
@@ -228,11 +274,6 @@ const ErrorComponent = ({ error, retry }) => (
|
|
|
228
274
|
- ❌ **Removed** `includeStyles` option (always enabled)
|
|
229
275
|
- ❌ **Removed** `baseUrl` option (uses provider default)
|
|
230
276
|
|
|
231
|
-
### Component Renaming
|
|
232
|
-
|
|
233
|
-
- `AiResponseRenderer` → `ResponseRenderer`
|
|
234
|
-
- `useAiResponse` → `useResponse`
|
|
235
|
-
|
|
236
277
|
## Development
|
|
237
278
|
|
|
238
279
|
```bash
|
|
@@ -247,6 +288,12 @@ pnpm test
|
|
|
247
288
|
|
|
248
289
|
# Development mode
|
|
249
290
|
pnpm dev
|
|
291
|
+
|
|
292
|
+
# Type check
|
|
293
|
+
pnpm type-check
|
|
294
|
+
|
|
295
|
+
# Lint
|
|
296
|
+
pnpm lint
|
|
250
297
|
```
|
|
251
298
|
|
|
252
299
|
## License
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/core/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/core/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAiEvC;IAEF;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,GAAG,gBAAgB,GAAG,IAAI;IA4CrD;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,GAAG,GAAG,gBAAgB,EAAE;IA2BzD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO;CAI9D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAUnE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAmC;;IAYpD;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,GAAG,IAAI;IA4BnE;;OAEG;IACH,iBAAiB,CACf,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,UAAU,EACpB,OAAO,CAAC,EAAE,YAAY,GACrB,cAAc,GAAG,IAAI;IAcxB;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,GAAG,GAAG,UAAU,GAAG,IAAI;IAKhD;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,GAAG,GAAG,KAAK,CAAC;QAAE,QAAQ,EAAE,UAAU,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAItF;;OAEG;IACH,OAAO,CAAC,YAAY;IAuDpB;;OAEG;IACH,qBAAqB,IAAI,UAAU,EAAE;IAIrC;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI;CAG5D;AAGD,eAAO,MAAM,MAAM,kBAAyB,CAAC;AAG7C,eAAO,MAAM,eAAe,GAAI,UAAU,GAAG,EAAE,UAAU,YAAY,0BACpC,CAAC;AAElC,eAAO,MAAM,cAAc,GAAI,UAAU,GAAG,sBACX,CAAC"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type AIProvider = 'CHATGPT' | 'GEMINI' | 'PERPLEXITY' | 'COPILOT' | 'AIOVERVIEW' | 'AIMODE';
|
|
1
|
+
export type AIProvider = 'CHATGPT' | 'GEMINI' | 'PERPLEXITY' | 'COPILOT' | 'AIOVERVIEW' | 'AIMODE' | 'GROK';
|
|
2
2
|
export interface ParsedResponse {
|
|
3
3
|
provider: AIProvider;
|
|
4
4
|
html: string;
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,MAAM,CAAC;AAEX,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;CACjB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type AIProvider = 'CHATGPT' | 'GEMINI' | 'PERPLEXITY' | 'COPILOT' | 'AIOVERVIEW' | 'AIMODE';
|
|
1
|
+
type AIProvider = 'CHATGPT' | 'GEMINI' | 'PERPLEXITY' | 'COPILOT' | 'AIOVERVIEW' | 'AIMODE' | 'GROK';
|
|
2
2
|
interface ParsedResponse {
|
|
3
3
|
provider: AIProvider;
|
|
4
4
|
html: string;
|
|
@@ -235,5 +235,20 @@ declare class AIModeProvider extends BaseProvider {
|
|
|
235
235
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
|
|
238
|
+
declare class GrokProvider extends BaseProvider {
|
|
239
|
+
readonly name: AIProvider;
|
|
240
|
+
readonly baseUrl = "https://grok.com";
|
|
241
|
+
extractContent(response: any): ContentExtraction;
|
|
242
|
+
/**
|
|
243
|
+
* Remove Grok header from HTML
|
|
244
|
+
*/
|
|
245
|
+
removeHeader(html: string): string;
|
|
246
|
+
/**
|
|
247
|
+
* Remove Grok footer/input area from HTML
|
|
248
|
+
*/
|
|
249
|
+
removeFooter(html: string): string;
|
|
250
|
+
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export { AIModeProvider, AIOverviewProvider, AIResponseParser, BaseProvider, ChatGPTProvider, CopilotProvider, GeminiProvider, GrokProvider, PerplexityProvider, ProviderDetector, detectProvider, parseAiResponse, parser };
|
|
239
254
|
export type { AIProvider, ContentExtraction, DetectedProvider, ParseOptions, ParsedResponse, ProviderConfig, StyleOptions };
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,YAAY,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,YAAY,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
class e{static detect(e){const t={CHATGPT:0,GEMINI:0,PERPLEXITY:0,COPILOT:0,AIOVERVIEW:0,AIMODE:0};for(const[r,o]of Object.entries(this.PROVIDER_PATTERNS))for(const n of o)try{n(e)&&t[r]++}catch(e){}let r=0,o=null;for(const[e,n]of Object.entries(t))n>r&&(r=n,o=e);return 0===r?null:{provider:o,confidence:r/Object.values(t).reduce((e,t)=>Math.max(e,t),1)}}static getAllProviders(e){const t=[];for(const[r,o]of Object.entries(this.PROVIDER_PATTERNS)){let n=0;for(const t of o)try{t(e)&&n++}catch(e){}n>0&&t.push({provider:r,confidence:n/o.length})}return t.sort((e,t)=>t.confidence-e.confidence)}static validate(e,t){const r=this.detect(e);return(null==r?void 0:r.provider)===t&&r.confidence>.5}}e.PROVIDER_PATTERNS={CHATGPT:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("bg-token-bg-primary")||r.includes("text-token-text-secondary")},e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("chatgpt.com")||r.includes("openai.com")}],GEMINI:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("bard-sidenav")||r.includes("mat-sidenav")},e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("gemini.google.com")||r.includes("gem-sys-color")}],PERPLEXITY:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("perplexity.ai")||r.includes("prose")}],COPILOT:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("copilot.microsoft.com")||r.includes('data-testid="sidebar-container"')}],AIOVERVIEW:[e=>{var t,r,o,n;if(null===(r=null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.aioverview)||void 0===r?void 0:r.text)return!0;if(null===(o=null==e?void 0:e.aioverview)||void 0===o?void 0:o.text)return!0;const i=(null===(n=null==e?void 0:e.result)||void 0===n?void 0:n.html)||(null==e?void 0:e.html)||"";return i.includes("WIZ_global_data")||i.includes("DnVkpd")}],AIMODE:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("DZ13He")||r.includes("wYq63b")||r.includes("AI Mode")}]};class t{injectStyles(e,t){let r=e;(null==t?void 0:t.baseUrl)&&!e.includes("<base ")&&(r=r.includes("<head>")?r.replace("<head>",`<head><base href="${t.baseUrl}">`):r.replace(/(<html[^>]*>)/i,`$1<head><base href="${t.baseUrl}"></head>`));const o=(null==t?void 0:t.customCSS)||"";return o&&r.includes("<head>")?r=r.replace("<head>",`<head><style>${o}</style>`):o&&(r=r.replace(/(<html[^>]*>)/i,`$1<head><style>${o}</style></head>`)),r}sanitizeHtml(e){let t=e.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,"");return t=t.replace(/<noscript[\s\S]*?<\/noscript>/gi,""),t}isFullDocument(e){return/^\s*(<html|<!DOCTYPE)/i.test(e)}removeLinks(e){return e.replace(/<a\b[^>]*>([\s\S]*?)<\/a>/gim,"$1")}wrapFragment(e){return`<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'none'; style-src 'unsafe-inline';">\n <style>\n body {\n margin: 0;\n padding: 16px;\n font-family: system-ui, -apple-system, sans-serif;\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n img { max-width: 100%; height: auto; }\n body {\n pointer-events: none;\n user-select: none;\n }\n </style>\n</head>\n<body>\n ${e}\n</body>\n</html>`}}class r extends t{constructor(){super(...arguments),this.name="CHATGPT",this.baseUrl="https://chatgpt.com"}extractContent(e){let t="",r="",o=e;return e.result&&(o=e.result),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?t=o:r=o:"object"==typeof o&&null!==o&&(o.html?t=o.html:o.content?o.content.trim().startsWith("<")?t=o.content:r=o.content:o.text&&(r=o.text)),{html:t,text:r}}removeLinks(e){return e.replace(/<a\b([^>]*)>/gi,(e,t)=>{const r=t.replace(/\s+href\s*=\s*["'][^"']*["']/gi,"").replace(/\s+alt\s*=\s*["'][^"']*["']/gi,"").replace(/\s+rel\s*=\s*["'][^"']*["']/gi,"").replace(/\s+target\s*=\s*["'][^"']*["']/gi,"").trim();return`<span${r?" "+r:""}>`}).replace(/<\/a>/gi,"</span>")}removeSidebar(e){let t=e;return t=t.replace(/<nav[^>]*>.*?<\/nav>/gis,""),t=t.replace(/<div[^>]*class="[^"]*sidebar[^"]*"[^>]*>.*?<\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*id="thread-bottom-container"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*id="thread-bottom"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:leading\][^"]*"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:footer\][^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:trailing\][^"]*"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*text-token-text-secondary[^"]*"[^>]*>.*?ChatGPT can make mistakes\. Check important info\..*?<\/div><\/div>/gis,""),t}parse(e,t){var r;const{html:o,text:n}=this.extractContent(e);if(!o)throw new Error("No HTML content found in ChatGPT response");let i=o;const s=null!==(r=null==t?void 0:t.removeFooter)&&void 0!==r&&r;i=this.sanitizeHtml(i),(null==t?void 0:t.removeSidebar)&&(i=this.removeSidebar(i)),s&&(i=this.removeFooter(i)),(null==t?void 0:t.removeLinks)&&(i=this.removeLinks(i));const l=(null==t?void 0:t.invertColors)?"\n /* Force Dark Background on main containers */\n html, body, main, article, footer, form {\n background-color: #131314 !important;\n }\n ":'\n /* Force Light Background on main containers */\n html, body, main, article, footer, form {\n background-color: #ffffff !important;\n }\n\n /* Override ChatGPT token text color classes - targeting text content only */\n p[class*="text-token"], span[class*="text-token"], div[class*="text-token"],\n h1[class*="text-token"], h2[class*="text-token"], h3[class*="text-token"],\n h4[class*="text-token"], h5[class*="text-token"], h6[class*="text-token"],\n li[class*="text-token"], td[class*="text-token"], th[class*="text-token"],\n [class*="markdown-"], strong, b, em, i, h1, h2, h3, h4, h5, h6, p, li, td, th {\n color: #1a1a1a !important;\n }\n\n /* Force borders and dividers to be visible */\n hr, [class*="border"], [class*="divider"], [class*="separator"],\n [class*="border-t"], [class*="border-b"], [class*="border-l"], [class*="border-r"],\n table, tr, td, th {\n border-color: #d4d4d4 !important;\n }\n ';return i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:l}),{provider:this.name,html:i,text:n,metadata:{isFullDocument:this.isFullDocument(i),sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,footerRemoved:s,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class o extends t{constructor(){super(...arguments),this.name="GEMINI",this.baseUrl="https://gemini.google.com"}extractContent(e){let t="",r="",o=[],n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text),n.aioverview&&(n.aioverview.text&&(r=n.aioverview.text),n.aioverview.sources&&(o=n.aioverview.sources))),{html:t,text:r,sources:o}}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*boqOnegoogleliteOgbOneGoogleBar[^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*side-nav-menu-button[^"]*"[^>]*>.*?<\/div>/gis,""),t=t.replace(/<top-bar-actions[^>]*>.*?<\/top-bar-actions>/gis,""),t=t.replace(/<div[^>]*class="[^"]*desktop-ogb-buffer[^"]*"[^>]*><\/div>/gis,""),t}removeFooter(e){return e.replace(/<input-container[^>]*>.*?<\/input-container>/gis,"")}removeSidebar(e){return e.replace(/<bard-sidenav[^>]*>.*?<\/bard-sidenav>/gis,"")}parse(e,t){var r,o;const{html:n,text:i,sources:s}=this.extractContent(e);if(!n)throw new Error("No HTML content found in Gemini response");let l=n;const a=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,d=null!==(o=null==t?void 0:t.removeFooter)&&void 0!==o&&o;return l=this.sanitizeHtml(l),a&&(l=this.removeHeader(l)),d&&(l=this.removeFooter(l)),(null==t?void 0:t.removeSidebar)&&(l=this.removeSidebar(l)),(null==t?void 0:t.removeLinks)&&(l=this.removeLinks(l)),l=this.injectStyles(l,{baseUrl:this.baseUrl,customCSS:""}),{provider:this.name,html:l,text:i,sources:s,metadata:{isFullDocument:this.isFullDocument(l),headerRemoved:a,footerRemoved:d,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1}}}}class n extends t{constructor(){super(...arguments),this.name="PERPLEXITY",this.baseUrl="https://www.perplexity.ai"}extractContent(e){let t="",r="",o=e;return e.result&&(o=e.result),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?t=o:r=o:"object"==typeof o&&null!==o&&(o.html?t=o.html:o.content?o.content.trim().startsWith("<")?t=o.content:r=o.content:o.text&&(r=o.text)),{html:t,text:r}}removeHeader(e){return e.replace(/<div[^>]*class="[^"]*@container\/header[^"]*"[^>]*>.*?<div[^>]*class="[^"]*absolute bottom-0 inset-x-0 border-b[^"]*"[^>]*><\/div>/gis,"")}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*erp-sidecar:fixed erp-sidecar:w-full bottom-safeAreaInsetBottom p-md pointer-events-none z-10 absolute border-subtlest ring-subtlest divide-subtlest bg-transparent[^"]*"[^>]*>[\s\S]*?(?=<div[^>]*class="[^"]*fixed inset-y-0 right-0[^"]*")/gis,""),t}parse(e,t){var r,o;const{html:n,text:i}=this.extractContent(e);if(!n)throw new Error("No HTML content found in Perplexity response");let s=n;const l=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,a=null!==(o=null==t?void 0:t.removeFooter)&&void 0!==o&&o;s=this.sanitizeHtml(s),l&&(s=this.removeHeader(s)),a&&(s=this.removeFooter(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s));const d=(null==t?void 0:t.invertColors)?"\n html {\n filter: invert(1) hue-rotate(180deg);\n background-color: white !important;\n }\n ":"";return s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:s,text:i,metadata:{isFullDocument:this.isFullDocument(s),linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1,headerRemoved:l,footerRemoved:a}}}}class i extends t{constructor(){super(...arguments),this.name="COPILOT",this.baseUrl="https://copilot.microsoft.com"}extractContent(e){let t="",r="",o=e;return e.result&&(o=e.result),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?t=o:r=o:"object"==typeof o&&null!==o&&(o.html?t=o.html:o.content?o.content.trim().startsWith("<")?t=o.content:r=o.content:o.text&&(r=o.text)),{html:t,text:r}}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*relative shrink-0 min-h-14[^"]*"[^>]*data-testid="backstage-chats"[^>]*>.*?<\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*absolute bottom-0 w-full[^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*mt-\[var\(--composer-container-height\)\][^"]*"[^>]*><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*pointer-events-none absolute flex justify-center z-20 inset-x-0 bottom-\[calc\(var\(--composer-container-height\)\+1rem\)\][^"]*"[^>]*>.*?<button[^>]*data-testid="scroll-to-bottom-button"[^>]*>.*?<\/button><\/div>/gis,""),t}removeCookieBanner(e){let t=e;return t=t.replace(/<div[^>]*id="cookie-banner"[^>]*>.*?<\/div>.*?<\/div>.*?<\/div>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*max-w-cookie-banner[^"]*"[^>]*>.*?<\/div>.*?<\/div>.*?<\/div>.*?<\/div>/gis,""),t}removeSidebar(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*absolute h-full w-0 will-change-auto max-md:bg-sidebar-light[^"]*"[^>]*style="[^"]*"[^>]*>.*?<main/gis,"<main"),t}parse(e,t){var r,o;const{html:n,text:i}=this.extractContent(e);if(!n)throw new Error("No HTML content found in Copilot response");let s=n;const l=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,a=null!==(o=null==t?void 0:t.removeFooter)&&void 0!==o&&o;return s=this.sanitizeHtml(s),s=this.removeCookieBanner(s),l&&(s=this.removeHeader(s)),a&&(s=this.removeFooter(s)),(null==t?void 0:t.removeSidebar)&&(s=this.removeSidebar(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s)),s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:""}),{provider:this.name,html:s,text:i,metadata:{isFullDocument:this.isFullDocument(s),cookieBannerRemoved:!0,headerRemoved:l,footerRemoved:a,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1}}}}class s extends t{constructor(){super(...arguments),this.name="AIOVERVIEW",this.baseUrl="https://www.google.com"}extractContent(e){let t="",r=[],o=e;return e.result&&(o=e.result),o.aioverview&&o.aioverview.sources&&(r=o.aioverview.sources),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")&&(t=o):"object"==typeof o&&null!==o&&(o.html?t=o.html:o.content&&o.content.trim().startsWith("<")&&(t=o.content)),{html:t,sources:r}}removeHeader(e){return e}removeFooter(e){return e}removeSidebar(e){return e}parse(e,t){var r,o;const{html:n,sources:i}=this.extractContent(e);if(!n)throw new Error("No HTML content found in AI Overview response");let s=n;const l=null===(r=null==t?void 0:t.removeHeader)||void 0===r||r,a=null===(o=null==t?void 0:t.removeFooter)||void 0===o||o;s=this.sanitizeHtml(s),l&&(s=this.removeHeader(s)),a&&(s=this.removeFooter(s)),(null==t?void 0:t.removeSidebar)&&(s=this.removeSidebar(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s));let d="";return(null==t?void 0:t.invertColors)?d+="\n /* Dark theme */\n html, body, main, article, footer, form {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n ":d+='\n /* Light theme - force all backgrounds to white */\n *, div, span, p, a, li, td, th, section, article, main, aside, nav, header, footer {\n background-color: #ffffff !important;\n }\n\n html, body, main, article, footer, form {\n background-color: #ffffff !important;\n }\n\n /* Force dark text color on all text elements */\n *, p, span, div, h1, h2, h3, h4, h5, h6, li, td, th, strong, b, em, i, a {\n color: #1a1a1a !important;\n }\n\n /* Force borders and dividers to be visible */\n hr, [class*="border"], [class*="divider"], [class*="separator"],\n [class*="border-t"], [class*="border-b"], [class*="border-l"], [class*="border-r"],\n table, tr, td, th {\n border-color: #d4d4d4 !important;\n }\n ',l&&(d+='\n /* Header hiding */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n .DZ13He, .wYq63b, .eT9Cje, .bNg8Rb, .S6VXfe, .Lu57id {\n display: none !important;\n }\n '),(null==t?void 0:t.removeSidebar)&&(d+="\n /* Sidebar hiding */\n #leftnav, #sidetogether {\n display: none !important;\n }\n "),a&&(d+='\n /* Footer hiding */\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L {\n display: none !important;\n }\n '),s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:s,sources:i,metadata:{isFullDocument:this.isFullDocument(s),headerRemoved:l,footerRemoved:a,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class l extends t{constructor(){super(...arguments),this.name="AIMODE",this.baseUrl="https://www.google.com"}extractContent(e){let t="",r="",o=e;return e.result&&(o=e.result),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?t=o:r=o:"object"==typeof o&&null!==o&&(o.html?t=o.html:o.content?o.content.trim().startsWith("<")?t=o.content:r=o.content:o.text&&(r=o.text)),{html:t,text:r}}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*jsname="oEQ3x"[^>]*class="[^"]*DZ13He[^"]*"[^>]*>.*?<hr class="e9c7U">.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*data-xid="aim-mars-input-plate"[^>]*>[\s\S]*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*jscontroller="P5gZDb"[^>]*>[\s\S]*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*t0ITR hh3ttd[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*y4VEUd vve6Ce[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t}removeSidebar(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*ho072b[^"]*"[^>]*aria-label="AI Mode history"[^>]*>[\s\S]*?<\/div><\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*jsname="NlVIob"[^>]*class="[^"]*qEn1od[^"]*"[^>]*>[\s\S]*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*OEwhSe[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t=t.replace(/<button[^>]*aria-label="Start new search"[^>]*>[\s\S]*?<\/button>/gis,""),t=t.replace(/<button[^>]*aria-label="AI Mode history"[^>]*>[\s\S]*?<\/button>/gis,""),t}parse(e,t){var r,o;const{html:n,text:i}=this.extractContent(e);if(!n)throw new Error("No HTML content found in AI Mode response");let s=n;const l=null===(r=null==t?void 0:t.removeHeader)||void 0===r||r,a=null===(o=null==t?void 0:t.removeFooter)||void 0===o||o;s=this.sanitizeHtml(s),l&&(s=this.removeHeader(s)),a&&(s=this.removeFooter(s)),(null==t?void 0:t.removeSidebar)&&(s=this.removeSidebar(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s));let d="";return d+="\n .KxvlWc, #CXQnmb {\n display: none !important;\n }\n ",(null==t?void 0:t.invertColors)?d+="\n /* Dark theme */\n html, body, main, article, footer, form {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n ":d+='\n /* Light theme - force all backgrounds to white */\n *, div, span, p, a, li, td, th, section, article, main, aside, nav, header, footer {\n background-color: #ffffff !important;\n }\n\n html, body, main, article, footer, form {\n background-color: #ffffff !important;\n }\n\n /* Force dark text color on all text elements */\n *, p, span, div, h1, h2, h3, h4, h5, h6, li, td, th, strong, b, em, i, a {\n color: #1a1a1a !important;\n }\n\n /* Force borders and dividers to be visible */\n hr, [class*="border"], [class*="divider"], [class*="separator"],\n [class*="border-t"], [class*="border-b"], [class*="border-l"], [class*="border-r"],\n table, tr, td, th {\n border-color: #d4d4d4 !important;\n }\n ',l&&(d+='\n /* Header hiding */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n .DZ13He, .wYq63b, .eT9Cje, .bNg8Rb, .S6VXfe, .Lu57id {\n display: none !important;\n }\n '),(null==t?void 0:t.removeSidebar)&&(d+="\n /* Sidebar hiding */\n #leftnav, #sidetogether {\n display: none !important;\n }\n "),a&&(d+='\n /* Footer hiding */\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L {\n display: none !important;\n }\n '),s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:s,text:i,metadata:{isFullDocument:this.isFullDocument(s),headerRemoved:l,footerRemoved:a,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class a{constructor(){this.providers=new Map,this.providers.set("CHATGPT",new r),this.providers.set("GEMINI",new o),this.providers.set("PERPLEXITY",new n),this.providers.set("COPILOT",new i),this.providers.set("AIOVERVIEW",new s),this.providers.set("AIMODE",new l)}parse(t,r){const o=e.detect(t);if(!o)return this.parseGeneric(t);const n=this.providers.get(o.provider);if(!n)return null;try{const e=n.parse(t,r);return{...e,metadata:{...e.metadata,detectionConfidence:o.confidence}}}catch(e){return console.error(`Failed to parse response with ${o.provider}:`,e),null}}parseWithProvider(e,t,r){const o=this.providers.get(t);if(!o)throw new Error(`Unknown provider: ${t}`);try{return o.parse(e,r)}catch(e){return console.error(`Failed to parse response with ${t}:`,e),null}}detectProvider(t){const r=e.detect(t);return(null==r?void 0:r.provider)||null}detectAllProviders(t){return e.getAllProviders(t)}parseGeneric(e){let t="",r="";let o=e;var n;return e.result&&(o=e.result),"string"==typeof(n=o)?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),t||r?(t&&(t=t.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,""),t=t.replace(/<noscript[\s\S]*?<\/noscript>/gi,"")),{provider:"CHATGPT",html:t,text:r,metadata:{isGeneric:!0}}):null}getSupportedProviders(){return Array.from(this.providers.keys())}registerProvider(e,t){this.providers.set(e,t)}}const d=new a,c=(e,t)=>d.parse(e,t),v=e=>d.detectProvider(e);export{l as AIModeProvider,s as AIOverviewProvider,a as AIResponseParser,t as BaseProvider,r as ChatGPTProvider,i as CopilotProvider,o as GeminiProvider,n as PerplexityProvider,e as ProviderDetector,v as detectProvider,c as parseAiResponse,d as parser};
|
|
1
|
+
class e{static detect(e){const t={CHATGPT:0,GEMINI:0,PERPLEXITY:0,COPILOT:0,AIOVERVIEW:0,AIMODE:0,GROK:0};for(const[r,n]of Object.entries(this.PROVIDER_PATTERNS))for(const o of n)try{o(e)&&t[r]++}catch(e){}let r=0,n=null;for(const[e,o]of Object.entries(t))o>r&&(r=o,n=e);return 0===r?null:{provider:n,confidence:r/Object.values(t).reduce((e,t)=>Math.max(e,t),1)}}static getAllProviders(e){const t=[];for(const[r,n]of Object.entries(this.PROVIDER_PATTERNS)){let o=0;for(const t of n)try{t(e)&&o++}catch(e){}o>0&&t.push({provider:r,confidence:o/n.length})}return t.sort((e,t)=>t.confidence-e.confidence)}static validate(e,t){const r=this.detect(e);return(null==r?void 0:r.provider)===t&&r.confidence>.5}}e.PROVIDER_PATTERNS={CHATGPT:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("bg-token-bg-primary")||r.includes("text-token-text-secondary")},e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("chatgpt.com")||r.includes("openai.com")}],GEMINI:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("bard-sidenav")||r.includes("mat-sidenav")},e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("gemini.google.com")||r.includes("gem-sys-color")}],PERPLEXITY:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("perplexity.ai")||r.includes("prose")}],COPILOT:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("copilot.microsoft.com")||r.includes('data-testid="sidebar-container"')}],AIOVERVIEW:[e=>{var t,r,n,o;if(null===(r=null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.aioverview)||void 0===r?void 0:r.text)return!0;if(null===(n=null==e?void 0:e.aioverview)||void 0===n?void 0:n.text)return!0;const a=(null===(o=null==e?void 0:e.result)||void 0===o?void 0:o.html)||(null==e?void 0:e.html)||"";return a.includes("WIZ_global_data")||a.includes("DnVkpd")}],AIMODE:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("DZ13He")||r.includes("wYq63b")||r.includes("AI Mode")}],GROK:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("grok.com")||r.includes("x.ai")}]};class t{injectStyles(e,t){let r=e;(null==t?void 0:t.baseUrl)&&!e.includes("<base ")&&(r=r.includes("<head>")?r.replace("<head>",`<head><base href="${t.baseUrl}">`):r.replace(/(<html[^>]*>)/i,`$1<head><base href="${t.baseUrl}"></head>`));const n=(null==t?void 0:t.customCSS)||"";return n&&r.includes("<head>")?r=r.replace("<head>",`<head><style>${n}</style>`):n&&(r=r.replace(/(<html[^>]*>)/i,`$1<head><style>${n}</style></head>`)),r}sanitizeHtml(e){let t=e.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,"");return t=t.replace(/<noscript[\s\S]*?<\/noscript>/gi,""),t}isFullDocument(e){return/^\s*(<html|<!DOCTYPE)/i.test(e)}removeLinks(e){return e.replace(/<a\b[^>]*>([\s\S]*?)<\/a>/gim,"$1")}wrapFragment(e){return`<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'none'; style-src 'unsafe-inline';">\n <style>\n body {\n margin: 0;\n padding: 16px;\n font-family: system-ui, -apple-system, sans-serif;\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n img { max-width: 100%; height: auto; }\n body {\n pointer-events: none;\n user-select: none;\n }\n </style>\n</head>\n<body>\n ${e}\n</body>\n</html>`}}class r extends t{constructor(){super(...arguments),this.name="CHATGPT",this.baseUrl="https://chatgpt.com"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeLinks(e){return e.replace(/<a\b([^>]*)>/gi,(e,t)=>{const r=t.replace(/\s+href\s*=\s*["'][^"']*["']/gi,"").replace(/\s+alt\s*=\s*["'][^"']*["']/gi,"").replace(/\s+rel\s*=\s*["'][^"']*["']/gi,"").replace(/\s+target\s*=\s*["'][^"']*["']/gi,"").trim();return`<span${r?" "+r:""}>`}).replace(/<\/a>/gi,"</span>")}removeSidebar(e){let t=e;return t=t.replace(/<nav[^>]*>.*?<\/nav>/gis,""),t=t.replace(/<div[^>]*class="[^"]*sidebar[^"]*"[^>]*>.*?<\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*id="thread-bottom-container"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*id="thread-bottom"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:leading\][^"]*"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:footer\][^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:trailing\][^"]*"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*\[view-transition-name:var\(--vt-disclaimer\)\][^>]*>.*?<\/div><\/div>/gis,""),t}parse(e,t){var r;const{html:n,text:o}=this.extractContent(e);if(!n)throw new Error("No HTML content found in ChatGPT response");let a=n;const i=null!==(r=null==t?void 0:t.removeFooter)&&void 0!==r&&r;a=this.sanitizeHtml(a),(null==t?void 0:t.removeSidebar)&&(a=this.removeSidebar(a)),i&&(a=this.removeFooter(a)),(null==t?void 0:t.removeLinks)&&(a=this.removeLinks(a));const s=(null==t?void 0:t.invertColors)?'\n /* Force Light Theme (invert from default dark) - only main background */\n html, body, main {\n background-color: #ffffff !important;\n }\n /* Force all text to dark grey (not pure black for better readability) */\n html, body, main, article, div, span, p, h1, h2, h3, h4, h5, h6, li, a, button, strong, label, textarea {\n color: #1A1A1A !important;\n }\n /* Apply light grey background to user message pills */\n .user-message-bubble-color {\n background-color: #F4F4F4 !important;\n }\n /* Apply light grey background to citation pills - highly specific selector */\n a.flex.rounded-xl.px-2.text-\\[9px\\],\n a[class*="rounded-xl"][class*="px-2"][class*="text-\\[9px\\]"],\n span[class*="webpage-citation-pill"] a {\n background-color: #F4F4F4 !important;\n }\n /* Invert scroll button colors */\n button.rounded-full.w-8.h-8.bg-token-main-surface-primary,\n button[class*="rounded-full"][class*="w-8"][class*="h-8"] {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n }\n /* Invert composer box */\n div[data-composer-surface="true"],\n div.bg-token-bg-primary.dark\\:bg-\\[\\#303030\\] {\n background-color: #ffffff !important;\n border: 1px solid #E5E5E5 !important;\n }\n /* Invert composer pills */\n button.__composer-pill,\n [class*="__composer-pill"] {\n background-color: #F4F4F4 !important;\n border: 1px solid #E5E5E5 !important;\n }\n ':"";return a=this.injectStyles(a,{baseUrl:this.baseUrl,customCSS:s}),{provider:this.name,html:a,text:o,metadata:{isFullDocument:this.isFullDocument(a),sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,footerRemoved:i,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class n extends t{constructor(){super(...arguments),this.name="GEMINI",this.baseUrl="https://gemini.google.com"}extractContent(e){let t="",r="",n=[],o=e;return e.result&&(o=e.result),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?t=o:r=o:"object"==typeof o&&null!==o&&(o.html?t=o.html:o.content?o.content.trim().startsWith("<")?t=o.content:r=o.content:o.text&&(r=o.text),o.aioverview&&(o.aioverview.text&&(r=o.aioverview.text),o.aioverview.sources&&(n=o.aioverview.sources))),{html:t,text:r,sources:n}}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*boqOnegoogleliteOgbOneGoogleBar[^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*side-nav-menu-button[^"]*"[^>]*>.*?<\/div>/gis,""),t=t.replace(/<top-bar-actions[^>]*>.*?<\/top-bar-actions>/gis,""),t=t.replace(/<div[^>]*class="[^"]*desktop-ogb-buffer[^"]*"[^>]*><\/div>/gis,""),t}removeFooter(e){return e.replace(/<input-container[^>]*>.*?<\/input-container>/gis,"")}removeSidebar(e){return e.replace(/<bard-sidenav[^>]*>.*?<\/bard-sidenav>/gis,"")}parse(e,t){var r,n;const{html:o,text:a,sources:i}=this.extractContent(e);if(!o)throw new Error("No HTML content found in Gemini response");let s=o;const l=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,d=null!==(n=null==t?void 0:t.removeFooter)&&void 0!==n&&n;s=this.sanitizeHtml(s),l&&(s=this.removeHeader(s)),d&&(s=this.removeFooter(s)),(null==t?void 0:t.removeSidebar)&&(s=this.removeSidebar(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s));const c=(null==t?void 0:t.invertColors)?'\n html {\n color-scheme: light !important;\n }\n /* Force Light Theme (invert from default dark) - only main background */\n html, body, main {\n background-color: #ffffff !important;\n }\n /* Force all text to dark grey (not pure black for better readability) */\n html, body, main, article, div, span, p, h1, h2, h3, h4, h5, h6, li, a, button, strong, label, textarea {\n color: #1A1A1A !important;\n }\n /* User message bubbles - Gemini specific classes */\n .user-query-bubble-with-background,\n .user-query-container,\n .query-text,\n .query-text-line {\n background-color: #F4F4F4 !important;\n color: #1A1A1A !important;\n }\n /* AI response bubbles - Gemini specific classes */\n .model-response-text,\n .response-container,\n .response-container-content,\n .response-content {\n background-color: #ffffff !important;\n color: #1A1A1A !important;\n }\n /* Input/composer area - Gemini specific classes */\n input-area-v2,\n .input-area,\n .input-area-container,\n .text-input-field,\n .text-input-field_textarea-wrapper,\n .text-input-field-main-area,\n .text-input-field_textarea-inner,\n .text-input-field_textarea,\n .ql-editor,\n .textarea,\n .input-buttons-wrapper-bottom {\n background-color: #ffffff !important;\n color: #1A1A1A !important;\n border-color: #E5E5E5 !important;\n }\n /* Input gradient - remove the dark gradient overlay */\n input-container,\n .input-gradient {\n background: transparent !important;\n }\n input-container::before,\n .input-gradient::before {\n background: linear-gradient(transparent, #ffffff) !important;\n content: none !important;\n }\n /* Input placeholder text */\n .ql-editor::before,\n .textarea::placeholder {\n color: #666666 !important;\n }\n /* Buttons */\n button, [role="button"] {\n background-color: #F4F4F4 !important;\n color: #1A1A1A !important;\n border-color: #E5E5E5 !important;\n }\n /* Links */\n a {\n color: #1a73e8 !important;\n }\n /* Code blocks */\n pre, code, [class*="code"] {\n background-color: #f5f5f5 !important;\n color: #1A1A1A !important;\n border-color: #E5E5E5 !important;\n }\n /* Tables */\n table, td, th {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n color: #1A1A1A !important;\n }\n /* Force borders to be visible */\n [class*="border"], hr {\n border-color: #E5E5E5 !important;\n }\n /* Cards and containers */\n [class*="card"], [class*="container"] {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n }\n ':"";return s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:c}),{provider:this.name,html:s,text:a,sources:i,metadata:{isFullDocument:this.isFullDocument(s),headerRemoved:l,footerRemoved:d,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class o extends t{constructor(){super(...arguments),this.name="PERPLEXITY",this.baseUrl="https://www.perplexity.ai"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeHeader(e){return e.replace(/<div[^>]*class="[^"]*@container\/header[^"]*"[^>]*>.*?<div[^>]*class="[^"]*absolute bottom-0 inset-x-0 border-b[^"]*"[^>]*><\/div>/gis,"")}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*erp-sidecar:fixed erp-sidecar:w-full bottom-safeAreaInsetBottom p-md pointer-events-none z-10 absolute border-subtlest ring-subtlest divide-subtlest bg-transparent[^"]*"[^>]*>[\s\S]*?(?=<div[^>]*class="[^"]*fixed inset-y-0 right-0[^"]*")/gis,""),t}parse(e,t){var r,n;const{html:o,text:a}=this.extractContent(e);if(!o)throw new Error("No HTML content found in Perplexity response");let i=o;const s=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,l=null!==(n=null==t?void 0:t.removeFooter)&&void 0!==n&&n;i=this.sanitizeHtml(i),s&&(i=this.removeHeader(i)),l&&(i=this.removeFooter(i)),(null==t?void 0:t.removeLinks)&&(i=this.removeLinks(i));const d=(null==t?void 0:t.invertColors)?"\n html {\n filter: invert(1) hue-rotate(180deg);\n background-color: white !important;\n }\n ":"";return i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:i,text:a,metadata:{isFullDocument:this.isFullDocument(i),linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1,headerRemoved:s,footerRemoved:l}}}}class a extends t{constructor(){super(...arguments),this.name="COPILOT",this.baseUrl="https://copilot.microsoft.com"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*relative shrink-0 min-h-14[^"]*"[^>]*data-testid="backstage-chats"[^>]*>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*flex items-center px-6 mx-auto w-full max-w-chat[^"]*"[^>]*>.*?<span[^>]*data-testid="date-divider"[^>]*>.*?<\/span>.*?<div[^>]*class="[^"]*border-t-\[1px\][^"]*"[^>]*>.*?<\/div>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*absolute flex end-6 origin-top-right flex-col items-end[^"]*"[^>]*data-testid="settings-wrapper"[^>]*>.*?<\/div><\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*absolute bottom-0 w-full[^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*mt-\[var\(--composer-container-height\)\][^"]*"[^>]*><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*pointer-events-none absolute flex justify-center z-20 inset-x-0 bottom-\[calc\(var\(--composer-container-height\)\+1rem\)\][^"]*"[^>]*>.*?<button[^>]*data-testid="scroll-to-bottom-button"[^>]*>.*?<\/button><\/div>/gis,""),t}removeCookieBanner(e){let t=e;return t=t.replace(/<div[^>]*id="cookie-banner"[^>]*>.*?<\/div>.*?<\/div>.*?<\/div>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*max-w-cookie-banner[^"]*"[^>]*>.*?<\/div>.*?<\/div>.*?<\/div>.*?<\/div>/gis,""),t}removeSidebar(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*absolute h-full w-0 will-change-auto max-md:bg-sidebar-light[^"]*"[^>]*style="[^"]*"[^>]*>.*?<main/gis,"<main"),t}parse(e,t){var r,n;const{html:o,text:a}=this.extractContent(e);if(!o)throw new Error("No HTML content found in Copilot response");let i=o;const s=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,l=null!==(n=null==t?void 0:t.removeFooter)&&void 0!==n&&n;i=this.sanitizeHtml(i),i=this.removeCookieBanner(i),s&&(i=this.removeHeader(i)),l&&(i=this.removeFooter(i)),(null==t?void 0:t.removeSidebar)&&(i=this.removeSidebar(i)),(null==t?void 0:t.removeLinks)&&(i=this.removeLinks(i));const d=(null==t?void 0:t.invertColors)?'\n html {\n color-scheme: light !important;\n }\n /* Force Light Theme (invert from default dark) - only main background */\n html, body, main {\n background-color: #ffffff !important;\n }\n /* Force all text to dark grey (not pure black for better readability) */\n html, body, main, article, div, span, p, h1, h2, h3, h4, h5, h6, li, a, button, strong, label, textarea {\n color: #1A1A1A !important;\n }\n /* User message bubbles - Copilot uses bg-accent-250/60 */\n .bg-accent-250\\/60,\n [class*="bg-accent-250"] {\n background-color: #F4F4F4 !important;\n color: #1A1A1A !important;\n }\n /* Override dark mode user message background */\n .dark\\:bg-accent-200,\n [class*="dark:bg-accent"] {\n background-color: #F4F4F4 !important;\n }\n /* AI response bubbles */\n [class*="ai-message"] {\n background-color: #ffffff !important;\n color: #1A1A1A !important;\n }\n /* Sidebar */\n .bg-sidebar-dark, [class*="bg-sidebar-dark"] {\n background-color: #ffffff !important;\n }\n /* Composer/input area */\n [class*="composer"], [class*="bottom-0"] {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n }\n /* Input textarea */\n textarea {\n background-color: #F4F4F4 !important;\n color: #1A1A1A !important;\n }\n textarea::placeholder {\n color: #666666 !important;\n }\n /* Buttons - only override dark mode backgrounds, let transparent buttons stay transparent */\n [class*="dark:bg-background-350\\/60"],\n [class*="dark:bg-black"],\n [class*="dark:bg-muted"] {\n background-color: #F4F4F4 !important;\n }\n /* Don\'t override bg-transparent buttons */\n .bg-transparent {\n background-color: transparent !important;\n }\n /* Override button dark mode backgrounds */\n .dark\\:bg-background-350\\/60,\n [class*="dark:bg-background"] {\n background-color: #F4F4F4 !important;\n }\n /* Override dark mode borders (before:border-black/8) */\n .dark\\:border-black\\/8,\n [class*="dark:border-black"] {\n border-color: #E5E5E5 !important;\n }\n /* Keep transparent borders */\n .after\\:border-transparent,\n [class*="border-transparent"] {\n border-color: transparent !important;\n }\n /* Override dark mode fill colors */\n .dark\\:fill-white,\n [class*="dark:fill"] {\n fill: #1A1A1A !important;\n }\n /* Links */\n a {\n color: #1a73e8 !important;\n }\n /* Override dark mode accent colors */\n .dark\\:text-accent-600,\n [class*="dark:text-accent"] {\n color: #1a73e8 !important;\n }\n /* Code blocks */\n pre, code, [class*="code"] {\n background-color: #f5f5f5 !important;\n color: #1A1A1A !important;\n border-color: #E5E5E5 !important;\n }\n /* Tables - override dark mode background */\n .dark\\:bg-black\\/25,\n [class*="dark:bg-black"] {\n background-color: #ffffff !important;\n }\n table, td, th {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n color: #1A1A1A !important;\n }\n /* Override dark mode table borders */\n .dark\\:border-stroke-450,\n [class*="dark:border-stroke"] {\n border-color: #E5E5E5 !important;\n }\n /* Force borders to be visible */\n [class*="border"], hr {\n border-color: #E5E5E5 !important;\n }\n /* Foreground colors */\n .text-foreground-800, [class*="text-foreground"] {\n color: #1A1A1A !important;\n }\n /* Override dark mode foreground text */\n .dark\\:fill-white,\n [class*="dark:text-foreground"] {\n color: #1A1A1A !important;\n }\n /* Override dark mode background opacity classes */\n [class*="dark:bg-background-100"],\n [class*="dark:bg-background-150"],\n [class*="dark:bg-background-200"],\n [class*="dark:bg-background-250"],\n [class*="dark:bg-background-350"],\n [class*="dark:bg-background-800"],\n [class*="dark:bg-background-850"],\n [class*="dark:bg-muted-200"],\n [class*="dark:bg-muted-400"],\n [class*="dark:bg-muted-450"] {\n background-color: #F4F4F4 !important;\n }\n /* Override light mode background classes to pure white/gray */\n .bg-background-100,\n .bg-background-150,\n .bg-background-200,\n .bg-background-250,\n [class*="bg-background-1"],\n [class*="bg-background-2"] {\n background-color: #ffffff !important;\n }\n .bg-background-350,\n .bg-background-800,\n .bg-background-850,\n .bg-accent-100,\n .bg-accent-250,\n [class*="bg-accent-1"],\n [class*="bg-accent-2"] {\n background-color: #F4F4F4 !important;\n }\n /* Citation pills - override dark mode */\n .dark\\:bg-white\\/5,\n [class*="dark:bg-white/5"],\n [class*="hover\\:dark\\:bg-accent-250"],\n [class*="focus\\:dark\\:bg-accent-250"] {\n background-color: #F4F4F4 !important;\n }\n /* Citation pills text color */\n .text-foreground-750,\n [class*="text-foreground-750"],\n [class*="dark\\:text-foreground-750"] {\n color: #1A1A1A !important;\n }\n /* Override bg-white/X with dark:bg-background-X pattern */\n .bg-white\\/40,\n .bg-white\\/25,\n .bg-white\\/50,\n .bg-white\\/70,\n .bg-white\\/90,\n [class*="bg-white\\/"] {\n background-color: #ffffff !important;\n }\n /* Pseudo-element overrides - before: gradients */\n [class*="before:from-sidebar-dark"],\n [class*="before:to-sidebar-dark"],\n [class*="dark\\:before:from-sidebar"],\n [class*="dark\\:before:to-sidebar"] {\n background: linear-gradient(transparent, #ffffff) !important;\n }\n /* Override all before: opacity and gradient classes */\n [class*="before:opacity"],\n [class*="before:bg-gradient"],\n [class*="before:from-transparent"],\n [class*="before:to-"] {\n background: linear-gradient(transparent, rgba(255, 255, 255, 0.9)) !important;\n }\n /* Force all before: pseudo-elements to have white/light gradients */\n .before\\:opacity-90\\:before,\n [class*="before:opacity-90"]::before {\n background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.9)) !important;\n }\n /* Pseudo-element overrides - before: borders */\n [class*="before:border-black"],\n [class*="dark\\:before:border-black"] {\n border-color: #E5E5E5 !important;\n }\n /* Pseudo-element overrides - after: borders */\n [class*="after:border-white"],\n [class*="dark\\:after:border-white"] {\n border-color: #E5E5E5 !important;\n }\n /* Pseudo-element overrides - hover states */\n [class*="dark\\:safe-hover:bg-white"],\n [class*="dark\\:active:bg-white"],\n [class*="dark\\:safe-hover\\:before:bg-white"] {\n background-color: #F4F4F4 !important;\n }\n /* Pseudo-element overrides - after:hover */\n [class*="dark\\:after\\:hover:bg-white"],\n [class*="max-md\\:dark\\:after\\:hover"] {\n background-color: rgba(244, 244, 244, 0.5) !important;\n }\n /* Override dark mode marker colors */\n [class*="dark\\:marker:text-foreground"] {\n color: #1A1A1A !important;\n }\n /* Force all before/after pseudo-elements to light colors */\n ::before,\n ::after {\n background-color: transparent !important;\n border-color: #E5E5E5 !important;\n }\n /* Scroll-to-bottom button outer container - force transparent */\n [class*="inset-x-0"][class*="bottom-["],\n .pointer-events-none.absolute.flex.justify-center {\n background-color: transparent !important;\n background: transparent !important;\n }\n [data-testid="scroll-to-bottom-button"] {\n background-color: transparent !important;\n }\n ':"\n /* No color inversion - keep default dark theme */\n ";return i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:i,text:a,metadata:{isFullDocument:this.isFullDocument(i),cookieBannerRemoved:!0,headerRemoved:s,footerRemoved:l,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class i extends t{constructor(){super(...arguments),this.name="AIOVERVIEW",this.baseUrl="https://www.google.com"}extractContent(e){let t="",r=[],n=e;return e.result&&(n=e.result),n.aioverview&&n.aioverview.sources&&(r=n.aioverview.sources),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")&&(t=n):"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content&&n.content.trim().startsWith("<")&&(t=n.content)),{html:t,sources:r}}removeHeader(e){return e}removeFooter(e){return e}removeSidebar(e){return e}parse(e,t){var r,n;const{html:o,sources:a}=this.extractContent(e);if(!o)throw new Error("No HTML content found in AI Overview response");let i=o;const s=null===(r=null==t?void 0:t.removeHeader)||void 0===r||r,l=null===(n=null==t?void 0:t.removeFooter)||void 0===n||n;i=this.sanitizeHtml(i),s&&(i=this.removeHeader(i)),l&&(i=this.removeFooter(i)),(null==t?void 0:t.removeSidebar)&&(i=this.removeSidebar(i)),(null==t?void 0:t.removeLinks)&&(i=this.removeLinks(i));let d="";return(null==t?void 0:t.invertColors)?d+="\n /* Dark theme */\n html, body, main, article, footer, form {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n ":d+='\n /* Light theme - force all backgrounds to white */\n *, div, span, p, a, li, td, th, section, article, main, aside, nav, header, footer {\n background-color: #ffffff !important;\n }\n\n html, body, main, article, footer, form {\n background-color: #ffffff !important;\n }\n\n /* Force dark text color on all text elements */\n *, p, span, div, h1, h2, h3, h4, h5, h6, li, td, th, strong, b, em, i, a {\n color: #1a1a1a !important;\n }\n\n /* Force borders and dividers to be visible */\n hr, [class*="border"], [class*="divider"], [class*="separator"],\n [class*="border-t"], [class*="border-b"], [class*="border-l"], [class*="border-r"],\n table, tr, td, th {\n border-color: #d4d4d4 !important;\n }\n ',s&&(d+='\n /* Header hiding */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n .DZ13He, .wYq63b, .eT9Cje, .bNg8Rb, .S6VXfe, .Lu57id {\n display: none !important;\n }\n '),(null==t?void 0:t.removeSidebar)&&(d+="\n /* Sidebar hiding */\n #leftnav, #sidetogether {\n display: none !important;\n }\n "),l&&(d+='\n /* Footer hiding */\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L {\n display: none !important;\n }\n '),i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:i,sources:a,metadata:{isFullDocument:this.isFullDocument(i),headerRemoved:s,footerRemoved:l,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class s extends t{constructor(){super(...arguments),this.name="AIMODE",this.baseUrl="https://www.google.com"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*jsname="oEQ3x"[^>]*class="[^"]*DZ13He[^"]*"[^>]*>.*?<hr class="e9c7U">.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*data-xid="aim-mars-input-plate"[^>]*>[\s\S]*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*jscontroller="P5gZDb"[^>]*>[\s\S]*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*t0ITR hh3ttd[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*y4VEUd vve6Ce[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t}removeSidebar(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*ho072b[^"]*"[^>]*aria-label="AI Mode history"[^>]*>[\s\S]*?<\/div><\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*jsname="NlVIob"[^>]*class="[^"]*qEn1od[^"]*"[^>]*>[\s\S]*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*OEwhSe[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t=t.replace(/<button[^>]*aria-label="Start new search"[^>]*>[\s\S]*?<\/button>/gis,""),t=t.replace(/<button[^>]*aria-label="AI Mode history"[^>]*>[\s\S]*?<\/button>/gis,""),t}parse(e,t){var r,n;const{html:o,text:a}=this.extractContent(e);if(!o)throw new Error("No HTML content found in AI Mode response");let i=o;const s=null===(r=null==t?void 0:t.removeHeader)||void 0===r||r,l=null===(n=null==t?void 0:t.removeFooter)||void 0===n||n;i=this.sanitizeHtml(i),s&&(i=this.removeHeader(i)),l&&(i=this.removeFooter(i)),(null==t?void 0:t.removeSidebar)&&(i=this.removeSidebar(i)),(null==t?void 0:t.removeLinks)&&(i=this.removeLinks(i));let d="";return d+="\n .KxvlWc, #CXQnmb {\n display: none !important;\n }\n ",(null==t?void 0:t.invertColors)?d+="\n /* Dark theme */\n html, body, main, article, footer, form {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n ":d+='\n /* Light theme - force all backgrounds to white */\n *, div, span, p, a, li, td, th, section, article, main, aside, nav, header, footer {\n background-color: #ffffff !important;\n }\n\n html, body, main, article, footer, form {\n background-color: #ffffff !important;\n }\n\n /* Force dark text color on all text elements */\n *, p, span, div, h1, h2, h3, h4, h5, h6, li, td, th, strong, b, em, i, a {\n color: #1a1a1a !important;\n }\n\n /* Force borders and dividers to be visible */\n hr, [class*="border"], [class*="divider"], [class*="separator"],\n [class*="border-t"], [class*="border-b"], [class*="border-l"], [class*="border-r"],\n table, tr, td, th {\n border-color: #d4d4d4 !important;\n }\n ',s&&(d+='\n /* Header hiding */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n .DZ13He, .wYq63b, .eT9Cje, .bNg8Rb, .S6VXfe, .Lu57id {\n display: none !important;\n }\n '),(null==t?void 0:t.removeSidebar)&&(d+="\n /* Sidebar hiding */\n #leftnav, #sidetogether {\n display: none !important;\n }\n "),l&&(d+='\n /* Footer hiding */\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L {\n display: none !important;\n }\n '),i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:i,text:a,metadata:{isFullDocument:this.isFullDocument(i),headerRemoved:s,footerRemoved:l,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class l extends t{constructor(){super(...arguments),this.name="GROK",this.baseUrl="https://grok.com"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeHeader(e){let t=e;const r=t.match(/<div[^>]*class="[^"]*h-16\s+top-0\s+@\[80rem\]\/nav:h-0[^"]*"[^>]*>/gi);if(!r)return t;const n=t.indexOf(r[0]);if(-1===n)return t;const o=t.substring(n+r[0].length);let a=1,i=0,s=!1;for(;i<o.length&&!s;){const e=o.indexOf("<div",i),t=o.indexOf("</div>",i);if(-1===e&&-1===t)break;if(-1!==t&&(-1===e||t<e))a--,i=t+6,0===a&&(s=!0);else if(-1!==e){a++;const t=o.indexOf(">",e);if(-1===t)break;i=t+1}}if(s){const e=n+r[0].length+i;t=t.substring(0,n)+t.substring(e)}return t}removeFooter(e){let t=e;const r=t.match(/<div[^>]*class="[^"]*absolute\s+inset-x-0\s+bottom-0\s+mx-auto\s+max-w-breakout\s+z-40\s+print:hidden[^"]*"[^>]*>/gi);if(!r)return t;const n=t.indexOf(r[0]);if(-1===n)return t;const o=t.substring(n),a=o.match(/<\/main>/gi);if(!a)return t;const i=n+o.indexOf(a[0]);return t=t.substring(0,n)+t.substring(i),t}parse(e,t){const{html:r,text:n}=this.extractContent(e);if(!r)throw new Error("No HTML content found in Grok response");let o=r;o=this.sanitizeHtml(o),(null==t?void 0:t.removeHeader)&&(o=this.removeHeader(o)),(null==t?void 0:t.removeFooter)&&(o=this.removeFooter(o)),(null==t?void 0:t.invertColors)&&(o=o.replace(/\s*class\s*=\s*"[^"]*dark[^"]*"/gi,e=>e.replace(/\bdark\b/g,"").replace(/\s+/g," ").replace('class=""','class="light"').replace(/^class=""/,'class="light"').replace(/class="\s+/,'class="').replace(/\s+"/,'"')),o=o.replace(/color-scheme:\s*dark/gi,"color-scheme: light")),(null==t?void 0:t.removeLinks)&&(o=this.removeLinks(o));const a=(null==t?void 0:t.invertColors)?'\n html {\n color-scheme: light !important;\n }\n /* Force light background and dark text for all elements */\n html, body {\n background-color: #ffffff !important;\n color: #1a1a1a !important;\n }\n /* Override Tailwind dark mode classes */\n .dark, [class*="dark"] {\n color-scheme: light !important;\n }\n /* Override common Grok CSS variables and classes */\n [class*="bg-"], [class*="background"] {\n background-color: #ffffff !important;\n }\n [class*="text-"], [class*="fg-"] {\n color: #1a1a1a !important;\n }\n /* Override surface and foreground colors */\n .bg-surface-base, .bg-surface, .surface {\n background-color: #f9f9f9 !important;\n }\n .text-fg-primary, .text-fg, .fg-primary {\n color: #1a1a1a !important;\n }\n /* Force borders to be visible */\n [class*="border"], hr, table, td, th {\n border-color: #d4d4d4 !important;\n }\n /* Code blocks */\n pre, code, [class*="code"] {\n background-color: #f5f5f5 !important;\n color: #1a1a1a !important;\n border-color: #d4d4d4 !important;\n }\n ':"\n /* Force light mode styling for Grok */\n html, body {\n background-color: #ffffff !important;\n color: #1a1a1a !important;\n }\n .bg-surface-base, .bg-surface {\n background-color: #f9f9f9 !important;\n }\n .text-fg-primary, .text-fg {\n color: #1a1a1a !important;\n }\n ";return o=this.injectStyles(o,{baseUrl:this.baseUrl,customCSS:a}),{provider:this.name,html:o,text:n,metadata:{isFullDocument:this.isFullDocument(o),linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1,headerRemoved:(null==t?void 0:t.removeHeader)||!1,footerRemoved:(null==t?void 0:t.removeFooter)||!1}}}}class d{constructor(){this.providers=new Map,this.providers.set("CHATGPT",new r),this.providers.set("GEMINI",new n),this.providers.set("PERPLEXITY",new o),this.providers.set("COPILOT",new a),this.providers.set("AIOVERVIEW",new i),this.providers.set("AIMODE",new s),this.providers.set("GROK",new l)}parse(t,r){const n=e.detect(t);if(!n)return this.parseGeneric(t);const o=this.providers.get(n.provider);if(!o)return null;try{const e=o.parse(t,r);return{...e,metadata:{...e.metadata,detectionConfidence:n.confidence}}}catch(e){return console.error(`Failed to parse response with ${n.provider}:`,e),null}}parseWithProvider(e,t,r){const n=this.providers.get(t);if(!n)throw new Error(`Unknown provider: ${t}`);try{return n.parse(e,r)}catch(e){return console.error(`Failed to parse response with ${t}:`,e),null}}detectProvider(t){const r=e.detect(t);return(null==r?void 0:r.provider)||null}detectAllProviders(t){return e.getAllProviders(t)}parseGeneric(e){let t="",r="";let n=e;var o;return e.result&&(n=e.result),"string"==typeof(o=n)?o.trim().startsWith("<")&&o.includes(">")?t=o:r=o:"object"==typeof o&&null!==o&&(o.html?t=o.html:o.content?o.content.trim().startsWith("<")?t=o.content:r=o.content:o.text&&(r=o.text)),t||r?(t&&(t=t.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,""),t=t.replace(/<noscript[\s\S]*?<\/noscript>/gi,"")),{provider:"CHATGPT",html:t,text:r,metadata:{isGeneric:!0}}):null}getSupportedProviders(){return Array.from(this.providers.keys())}registerProvider(e,t){this.providers.set(e,t)}}const c=new d,m=(e,t)=>c.parse(e,t),u=e=>c.detectProvider(e);export{s as AIModeProvider,i as AIOverviewProvider,d as AIResponseParser,t as BaseProvider,r as ChatGPTProvider,a as CopilotProvider,n as GeminiProvider,l as GrokProvider,o as PerplexityProvider,e as ProviderDetector,u as detectProvider,m as parseAiResponse,c as parser};
|
|
2
2
|
//# sourceMappingURL=index.esm.js.map
|