@cloro-dev/response-parser 0.1.3 → 0.1.4
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 +54 -28
- package/dist/core/types.d.ts +3 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +72 -8
- 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 +14 -3
- package/dist/providers/ai-mode.d.ts.map +1 -1
- package/dist/providers/ai-overview.d.ts +14 -3
- package/dist/providers/ai-overview.d.ts.map +1 -1
- package/dist/providers/base-provider.d.ts +0 -1
- package/dist/providers/base-provider.d.ts.map +1 -1
- package/dist/providers/chatgpt.d.ts +15 -3
- package/dist/providers/chatgpt.d.ts.map +1 -1
- package/dist/providers/copilot.d.ts +12 -1
- package/dist/providers/copilot.d.ts.map +1 -1
- package/dist/providers/gemini.d.ts +12 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/perplexity.d.ts +8 -1
- package/dist/providers/perplexity.d.ts.map +1 -1
- package/dist/react/core/types.d.ts +3 -1
- package/dist/react/core/types.d.ts.map +1 -1
- package/dist/react/hooks/useResponse.d.ts.map +1 -1
- package/dist/react/index.d.ts +3 -1
- package/dist/react/index.esm.js +1 -1
- package/dist/react/index.esm.js.map +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/providers/ai-mode.d.ts +14 -3
- package/dist/react/providers/ai-mode.d.ts.map +1 -1
- package/dist/react/providers/ai-overview.d.ts +14 -3
- package/dist/react/providers/ai-overview.d.ts.map +1 -1
- package/dist/react/providers/base-provider.d.ts +0 -1
- package/dist/react/providers/base-provider.d.ts.map +1 -1
- package/dist/react/providers/chatgpt.d.ts +15 -3
- package/dist/react/providers/chatgpt.d.ts.map +1 -1
- package/dist/react/providers/copilot.d.ts +12 -1
- package/dist/react/providers/copilot.d.ts.map +1 -1
- package/dist/react/providers/gemini.d.ts +12 -1
- package/dist/react/providers/gemini.d.ts.map +1 -1
- package/dist/react/providers/perplexity.d.ts +8 -1
- package/dist/react/providers/perplexity.d.ts.map +1 -1
- package/dist/react/react/hooks/useResponse.d.ts.map +1 -1
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ pnpm add @cloro-dev/response-parser
|
|
|
27
27
|
### Basic Parsing
|
|
28
28
|
|
|
29
29
|
```typescript
|
|
30
|
-
import { parseAiResponse, detectProvider } from
|
|
30
|
+
import { parseAiResponse, detectProvider } from "@cloro-dev/response-parser";
|
|
31
31
|
|
|
32
32
|
// Auto-detect provider and parse
|
|
33
33
|
const response = await fetchAIResponse();
|
|
@@ -41,7 +41,7 @@ console.log(parsed.text); // Plain text version
|
|
|
41
41
|
### React Component
|
|
42
42
|
|
|
43
43
|
```tsx
|
|
44
|
-
import { ResponseRenderer } from
|
|
44
|
+
import { ResponseRenderer } from "@cloro-dev/response-parser/react";
|
|
45
45
|
|
|
46
46
|
function MyComponent() {
|
|
47
47
|
const [aiResponse, setAiResponse] = useState(null);
|
|
@@ -54,9 +54,9 @@ function MyComponent() {
|
|
|
54
54
|
autoDetect
|
|
55
55
|
className="w-full h-96"
|
|
56
56
|
iframeProps={{
|
|
57
|
-
sandbox:
|
|
57
|
+
sandbox: "allow-popups",
|
|
58
58
|
}}
|
|
59
|
-
onProviderDetected={(provider) => console.log(
|
|
59
|
+
onProviderDetected={(provider) => console.log("Detected:", provider)}
|
|
60
60
|
/>
|
|
61
61
|
);
|
|
62
62
|
}
|
|
@@ -71,8 +71,12 @@ function MyComponent() {
|
|
|
71
71
|
Parse an AI response with auto-detected provider.
|
|
72
72
|
|
|
73
73
|
**Options:**
|
|
74
|
+
|
|
74
75
|
- `removeLinks`: `boolean` - Remove all hyperlinks from HTML (default: `false`)
|
|
75
|
-
- `invertColors`: `boolean` - Apply color inversion for dark mode
|
|
76
|
+
- `invertColors`: `boolean` - Apply color inversion for dark mode (default: `false`)
|
|
77
|
+
- `removeNavbar`: `boolean` - Remove navigation bar (default: `false`, Perplexity, Gemini & Copilot)
|
|
78
|
+
- `removeFollowup`: `boolean` - Remove follow-up input box (default: `false`, ChatGPT, Perplexity, Gemini & Copilot)
|
|
79
|
+
- `removeSidebar`: `boolean` - Remove sidebar (default: `false`, ChatGPT, Gemini & Copilot)
|
|
76
80
|
|
|
77
81
|
**Returns:** `ParsedResponse | null`
|
|
78
82
|
|
|
@@ -89,11 +93,14 @@ Detect the AI provider from a response.
|
|
|
89
93
|
Main React component for rendering AI responses.
|
|
90
94
|
|
|
91
95
|
**Props:**
|
|
96
|
+
|
|
92
97
|
- `response`: The AI response object
|
|
93
98
|
- `autoDetect`: Auto-detect provider (default: `true`)
|
|
94
99
|
- `provider`: Explicitly specify provider
|
|
95
100
|
- `removeLinks`: Remove all hyperlinks (default: `false`)
|
|
96
101
|
- `invertColors`: Apply color inversion (default: `false`)
|
|
102
|
+
- `removeNavbar`: Remove navigation bar (default: `false`, Perplexity & Gemini)
|
|
103
|
+
- `removeFollowup`: Remove follow-up input box (default: `false`, Perplexity only)
|
|
97
104
|
- `className`: CSS class for container
|
|
98
105
|
- `iframeProps`: Additional props for iframe
|
|
99
106
|
- `loadingComponent`: Custom loading component
|
|
@@ -109,14 +116,18 @@ Main React component for rendering AI responses.
|
|
|
109
116
|
React hook for parsing AI responses.
|
|
110
117
|
|
|
111
118
|
**Options:**
|
|
119
|
+
|
|
112
120
|
- `autoDetect`: Auto-detect provider (default: `true`)
|
|
113
121
|
- `provider`: Explicitly specify provider
|
|
114
122
|
- `removeLinks`: Remove all hyperlinks (default: `false`)
|
|
115
123
|
- `invertColors`: Apply color inversion (default: `false`)
|
|
124
|
+
- `removeNavbar`: Remove navigation bar (default: `false`, Perplexity & Gemini)
|
|
125
|
+
- `removeFollowup`: Remove follow-up input box (default: `false`, Perplexity only)
|
|
116
126
|
- `onProviderDetected`: Callback when provider is detected
|
|
117
127
|
- `onError`: Callback when error occurs
|
|
118
128
|
|
|
119
129
|
**Returns:**
|
|
130
|
+
|
|
120
131
|
- `parsed`: Parsed response object
|
|
121
132
|
- `provider`: Detected provider
|
|
122
133
|
- `isLoading`: Loading state
|
|
@@ -128,44 +139,56 @@ React hook for parsing AI responses.
|
|
|
128
139
|
|
|
129
140
|
## Supported Providers
|
|
130
141
|
|
|
131
|
-
| Provider
|
|
132
|
-
|
|
133
|
-
| ChatGPT
|
|
134
|
-
| Gemini
|
|
135
|
-
| Perplexity
|
|
136
|
-
| Copilot
|
|
137
|
-
| AI Overview | ✅
|
|
138
|
-
| AI Mode
|
|
142
|
+
| Provider | Status | Features |
|
|
143
|
+
| ----------- | ------ | ---------------------------------------------------- |
|
|
144
|
+
| ChatGPT | ✅ | Dark mode, sidebar hiding |
|
|
145
|
+
| Gemini | ✅ | Material Design overrides, navbar removal |
|
|
146
|
+
| Perplexity | ✅ | Color inversion, link removal, UI element removal |
|
|
147
|
+
| Copilot | ✅ | UI element hiding |
|
|
148
|
+
| AI Overview | ✅ | WIZ data extraction |
|
|
149
|
+
| AI Mode | ✅ | Google UI hiding |
|
|
139
150
|
|
|
140
151
|
## Examples
|
|
141
152
|
|
|
142
|
-
### Remove Hyperlinks
|
|
153
|
+
### Remove Hyperlinks
|
|
143
154
|
|
|
144
155
|
```typescript
|
|
145
|
-
import { parseAiResponse } from
|
|
156
|
+
import { parseAiResponse } from "@cloro-dev/response-parser";
|
|
146
157
|
|
|
147
158
|
const parsed = parseAiResponse(response, {
|
|
148
|
-
removeLinks: true
|
|
159
|
+
removeLinks: true, // Removes all <a> tags, keeps text
|
|
149
160
|
});
|
|
150
161
|
```
|
|
151
162
|
|
|
152
|
-
### Dark Mode
|
|
163
|
+
### Dark Mode
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
<ResponseRenderer
|
|
167
|
+
response={response}
|
|
168
|
+
invertColors={true} // Apply CSS filter for dark mode
|
|
169
|
+
removeLinks={true} // Optionally remove links
|
|
170
|
+
/>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Clean View (Remove UI Elements)
|
|
153
174
|
|
|
154
175
|
```tsx
|
|
155
176
|
<ResponseRenderer
|
|
156
|
-
response={
|
|
157
|
-
|
|
158
|
-
|
|
177
|
+
response={response}
|
|
178
|
+
removeNavbar={true} // Remove top navigation bar
|
|
179
|
+
removeFollowup={true} // Remove follow-up input box
|
|
180
|
+
removeLinks={true} // Remove all hyperlinks
|
|
181
|
+
invertColors={true} // Dark mode
|
|
159
182
|
/>
|
|
160
183
|
```
|
|
161
184
|
|
|
162
185
|
### Manual Provider Specification
|
|
163
186
|
|
|
164
187
|
```typescript
|
|
165
|
-
import { parseAiResponse, AIProvider } from
|
|
188
|
+
import { parseAiResponse, AIProvider } from "@cloro-dev/response-parser";
|
|
166
189
|
|
|
167
190
|
const parsed = parseAiResponse(response, {
|
|
168
|
-
provider:
|
|
191
|
+
provider: "CHATGPT",
|
|
169
192
|
});
|
|
170
193
|
```
|
|
171
194
|
|
|
@@ -179,15 +202,13 @@ const ErrorComponent = ({ error, retry }) => (
|
|
|
179
202
|
</div>
|
|
180
203
|
);
|
|
181
204
|
|
|
182
|
-
<ResponseRenderer
|
|
183
|
-
response={response}
|
|
184
|
-
errorComponent={ErrorComponent}
|
|
185
|
-
/>
|
|
205
|
+
<ResponseRenderer response={response} errorComponent={ErrorComponent} />;
|
|
186
206
|
```
|
|
187
207
|
|
|
188
208
|
## What's Changed in v0.1.3
|
|
189
209
|
|
|
190
210
|
### Simplified API
|
|
211
|
+
|
|
191
212
|
- ✅ **Always sanitizes** HTML by default (removes scripts for security)
|
|
192
213
|
- ✅ **Always includes** provider-specific styles
|
|
193
214
|
- ✅ **Always uses** provider's base URL for relative links
|
|
@@ -195,13 +216,18 @@ const ErrorComponent = ({ error, retry }) => (
|
|
|
195
216
|
- ❌ **Removed** `sanitize` option (always enabled)
|
|
196
217
|
- ❌ **Removed** `includeStyles` option (always enabled)
|
|
197
218
|
- ❌ **Removed** `baseUrl` option (uses provider default)
|
|
219
|
+
- ✅ **Added** `removeNavbar` option (removes navigation bar)
|
|
220
|
+
- ✅ **Added** `removeFollowup` option (removes follow-up input)
|
|
198
221
|
|
|
199
222
|
### Remaining Options
|
|
200
|
-
|
|
223
|
+
|
|
201
224
|
- `removeLinks`: Remove all hyperlinks from HTML
|
|
202
|
-
- `invertColors`: Apply color inversion
|
|
225
|
+
- `invertColors`: Apply color inversion
|
|
226
|
+
- `removeNavbar`: Remove navigation bar (Perplexity & Gemini)
|
|
227
|
+
- `removeFollowup`: Remove follow-up input (Perplexity only)
|
|
203
228
|
|
|
204
229
|
### Component Renaming
|
|
230
|
+
|
|
205
231
|
- `AiResponseRenderer` → `ResponseRenderer`
|
|
206
232
|
- `useAiResponse` → `useResponse`
|
|
207
233
|
|
package/dist/core/types.d.ts
CHANGED
|
@@ -9,11 +9,13 @@ export interface ParsedResponse {
|
|
|
9
9
|
export interface ParseOptions {
|
|
10
10
|
removeLinks?: boolean;
|
|
11
11
|
invertColors?: boolean;
|
|
12
|
+
removeHeader?: boolean;
|
|
13
|
+
removeFooter?: boolean;
|
|
14
|
+
removeSidebar?: boolean;
|
|
12
15
|
}
|
|
13
16
|
export interface ProviderConfig {
|
|
14
17
|
name: AIProvider;
|
|
15
18
|
baseUrl: string;
|
|
16
|
-
defaultStyles: string;
|
|
17
19
|
}
|
|
18
20
|
export interface DetectedProvider {
|
|
19
21
|
provider: AIProvider;
|
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;AAEb,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;
|
|
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;AAEb,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
|
@@ -9,11 +9,13 @@ interface ParsedResponse {
|
|
|
9
9
|
interface ParseOptions {
|
|
10
10
|
removeLinks?: boolean;
|
|
11
11
|
invertColors?: boolean;
|
|
12
|
+
removeHeader?: boolean;
|
|
13
|
+
removeFooter?: boolean;
|
|
14
|
+
removeSidebar?: boolean;
|
|
12
15
|
}
|
|
13
16
|
interface ProviderConfig {
|
|
14
17
|
name: AIProvider;
|
|
15
18
|
baseUrl: string;
|
|
16
|
-
defaultStyles: string;
|
|
17
19
|
}
|
|
18
20
|
interface DetectedProvider {
|
|
19
21
|
provider: AIProvider;
|
|
@@ -88,7 +90,6 @@ declare class ProviderDetector {
|
|
|
88
90
|
declare abstract class BaseProvider {
|
|
89
91
|
abstract readonly name: AIProvider;
|
|
90
92
|
abstract readonly baseUrl: string;
|
|
91
|
-
abstract readonly defaultStyles: string;
|
|
92
93
|
/**
|
|
93
94
|
* Parse an AI response and return structured content
|
|
94
95
|
*/
|
|
@@ -122,48 +123,111 @@ declare abstract class BaseProvider {
|
|
|
122
123
|
declare class ChatGPTProvider extends BaseProvider {
|
|
123
124
|
readonly name: AIProvider;
|
|
124
125
|
readonly baseUrl = "https://chatgpt.com";
|
|
125
|
-
readonly defaultStyles = "\n /* Force Dark Background on main containers and wrappers */\n html, body, main, article, footer, form,\n [class*=\"bg-\"], [class*=\"footer\"], [class*=\"bottom\"],\n div[class*=\"border-t\"],\n #thread-bottom-container, #thread-bottom,\n #thread, .composer-parent, [class*=\"group\\/thread\"] {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n border-color: #2a2b36 !important;\n }\n\n /* Force background on specific white artifacts in the footer */\n #thread-bottom-container .bg-clip-padding,\n #thread-bottom-container .content-fade,\n #thread-bottom-container .absolute {\n background-color: transparent !important;\n }\n\n /* Specific targeting for the composer/input box (was white) */\n form .bg-token-bg-primary, form .shadow-short {\n background-color: #2a2b36 !important;\n border-color: #3e3f4b !important;\n box-shadow: none !important;\n }\n\n /* Disclaimer Footer - Force Dark Background */\n div[class*=\"text-token-text-secondary\"] {\n color: #9ca3af !important;\n background-color: #131314 !important;\n }\n\n /* Force Text Color to Light */\n p, h1, h2, h3, h4, h5, h6, li, span, div, td, th, textarea, button {\n color: #e3e3e3 !important;\n }\n\n /* Links - Light Blue */\n a, a span {\n color: #8ab4f8 !important;\n }\n\n /* Code Blocks */\n pre, code, pre div, code span {\n background-color: #2a2b36 !important;\n color: #e3e3e3 !important;\n text-shadow: none !important;\n }\n\n /* Inputs/Textareas */\n input, textarea {\n background-color: transparent !important;\n color: #e3e3e3 !important;\n border-color: #3e3f4b !important;\n }\n\n /* Placeholder text */\n textarea::placeholder {\n color: #9ca3af !important;\n }\n\n /* Hide Sidebar */\n nav, [class*=\"sidebar\"] {\n display: none !important;\n }\n\n /* Media visibility */\n img, video {\n opacity: 1 !important;\n }\n ";
|
|
126
126
|
extractContent(response: any): ContentExtraction;
|
|
127
|
+
/**
|
|
128
|
+
* Remove links from HTML, preserving badge styling
|
|
129
|
+
* Converts <a> tags to <span> while keeping class attributes
|
|
130
|
+
*/
|
|
131
|
+
removeLinks(html: string): string;
|
|
132
|
+
/**
|
|
133
|
+
* Remove ChatGPT sidebar from HTML
|
|
134
|
+
*/
|
|
135
|
+
removeSidebar(html: string): string;
|
|
136
|
+
/**
|
|
137
|
+
* Remove ChatGPT footer/composer from HTML
|
|
138
|
+
*/
|
|
139
|
+
removeFooter(html: string): string;
|
|
127
140
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
128
141
|
}
|
|
129
142
|
|
|
130
143
|
declare class GeminiProvider extends BaseProvider {
|
|
131
144
|
readonly name: AIProvider;
|
|
132
145
|
readonly baseUrl = "https://gemini.google.com";
|
|
133
|
-
readonly defaultStyles = "\n /* Gemini Dark Mode Variable Overrides */\n :root {\n --gem-sys-color--surface: #131314 !important;\n --gem-sys-color--surface-container: #1e1f20 !important;\n --gem-sys-color--on-surface: #e3e3e3 !important;\n --bard-color-synthetic--chat-window-surface: #131314 !important;\n --bard-color-surface-dim-tmp: #131314 !important;\n }\n\n /* UI hiding - Gemini */\n bard-sidenav, mat-sidenav, .mat-drawer-backdrop, .side-nav-menu-button,\n\n /* Gemini \"About Gemini\" footer/navigation block */\n .gb_5a, .gb_5c, .gb_5d, .gb_5e,\n .gb_Uc, .gb_Vc, .gb_Wc,\n a[href*=\"about\"],\n a[href*=\"subscriptions\"],\n a[href*=\"business\"],\n div[class*=\"gb_5\"],\n .gb_Pd, .gb_Qd, .gb_Rd,\n .gb_Sd, .gb_Td, .gb_Ud, .gb_Vd,\n [aria-label*=\"About\"],\n [aria-label*=\"Gemini App\"],\n [aria-label*=\"Subscriptions\"],\n [aria-label*=\"For Business\"],\n *:contains(\"About Gemini\"),\n *:contains(\"Gemini App\"),\n *:contains(\"Subscriptions\"),\n *:contains(\"For Business\") {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n\n /* Force Dark Mode on Body and Gemini Containers */\n body, .content-container, chat-app, .main-content, .chat-container {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n ";
|
|
134
146
|
extractContent(response: any): ContentExtraction;
|
|
147
|
+
/**
|
|
148
|
+
* Remove Gemini header/navbar from HTML
|
|
149
|
+
*/
|
|
150
|
+
removeHeader(html: string): string;
|
|
151
|
+
/**
|
|
152
|
+
* Remove Gemini footer/follow-up input box from HTML
|
|
153
|
+
*/
|
|
154
|
+
removeFooter(html: string): string;
|
|
155
|
+
/**
|
|
156
|
+
* Remove Gemini sidebar from HTML
|
|
157
|
+
*/
|
|
158
|
+
removeSidebar(html: string): string;
|
|
135
159
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
136
160
|
}
|
|
137
161
|
|
|
138
162
|
declare class PerplexityProvider extends BaseProvider {
|
|
139
163
|
readonly name: AIProvider;
|
|
140
164
|
readonly baseUrl = "https://www.perplexity.ai";
|
|
141
|
-
readonly defaultStyles = "\n html {\n filter: invert(1) hue-rotate(180deg);\n background-color: white !important;\n }\n ";
|
|
142
165
|
extractContent(response: any): ContentExtraction;
|
|
166
|
+
/**
|
|
167
|
+
* Remove Perplexity header/navbar from HTML
|
|
168
|
+
*/
|
|
169
|
+
removeHeader(html: string): string;
|
|
170
|
+
/**
|
|
171
|
+
* Remove Perplexity footer/followup input from HTML
|
|
172
|
+
*/
|
|
173
|
+
removeFooter(html: string): string;
|
|
143
174
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
144
175
|
}
|
|
145
176
|
|
|
146
177
|
declare class CopilotProvider extends BaseProvider {
|
|
147
178
|
readonly name: AIProvider;
|
|
148
179
|
readonly baseUrl = "https://copilot.microsoft.com";
|
|
149
|
-
readonly defaultStyles = "\n /* Copilot Sidebar & Header */\n div:has(> [data-testid=\"sidebar-container\"]),\n [data-testid=\"sidebar-container\"],\n [data-testid=\"sticky-header\"],\n .side-nav-menu-button {\n display: none !important;\n }\n\n /* General Layout Fixes */\n main {\n width: 100% !important;\n max-width: 100% !important;\n margin: 0 !important;\n }\n ";
|
|
150
180
|
extractContent(response: any): ContentExtraction;
|
|
181
|
+
/**
|
|
182
|
+
* Remove Copilot header/navbar from HTML
|
|
183
|
+
*/
|
|
184
|
+
removeHeader(html: string): string;
|
|
185
|
+
/**
|
|
186
|
+
* Remove Copilot footer/followup input box from HTML
|
|
187
|
+
*/
|
|
188
|
+
removeFooter(html: string): string;
|
|
189
|
+
/**
|
|
190
|
+
* Remove Copilot sidebar from HTML
|
|
191
|
+
*/
|
|
192
|
+
removeSidebar(html: string): string;
|
|
151
193
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
152
194
|
}
|
|
153
195
|
|
|
154
196
|
declare class AIOverviewProvider extends BaseProvider {
|
|
155
197
|
readonly name: AIProvider;
|
|
156
198
|
readonly baseUrl = "https://www.google.com";
|
|
157
|
-
readonly defaultStyles = "\n /* UI hiding - Google Search (AI Overview) */\n header, #header, #searchform, .sfbg, #appbar,\n div[role=\"navigation\"], #leftnav, #sidetogether,\n [role=\"banner\"], .Fgvgjc, #hdtb, .hdtb-msb,\n footer, #footer, .fbar,\n .pdp-nav, [aria-label=\"Main menu\"], .gb_Td, .gb_L,\n\n /* Specific AI Mode Selectors */\n .DZ13He,\n .wYq63b,\n .eT9Cje,\n .bNg8Rb,\n .S6VXfe,\n .Lu57id {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n ";
|
|
158
199
|
extractContent(response: any): ContentExtraction;
|
|
200
|
+
/**
|
|
201
|
+
* Remove Google Search header/navbar from HTML
|
|
202
|
+
*/
|
|
203
|
+
removeHeader(html: string): string;
|
|
204
|
+
/**
|
|
205
|
+
* Remove Google Search footer from HTML
|
|
206
|
+
*/
|
|
207
|
+
removeFooter(html: string): string;
|
|
208
|
+
/**
|
|
209
|
+
* Remove Google Search sidebar from HTML
|
|
210
|
+
*/
|
|
211
|
+
removeSidebar(html: string): string;
|
|
159
212
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
160
213
|
}
|
|
161
214
|
|
|
162
215
|
declare class AIModeProvider extends BaseProvider {
|
|
163
216
|
readonly name: AIProvider;
|
|
164
217
|
readonly baseUrl = "https://www.google.com";
|
|
165
|
-
readonly defaultStyles = "\n /* UI hiding - Google Search (AI Mode) */\n header, #header, #searchform, .sfbg, #appbar,\n div[role=\"navigation\"], #leftnav, #sidetogether,\n [role=\"banner\"], .Fgvgjc, #hdtb, .hdtb-msb,\n footer, #footer, .fbar,\n .pdp-nav, [aria-label=\"Main menu\"], .gb_Td, .gb_L,\n\n /* Specific AI Mode Selectors found in analysis */\n .DZ13He, /* Main sticky top bar */\n .wYq63b, /* Accessibility links bar */\n .eT9Cje, /* History/New Search buttons */\n .bNg8Rb, /* Hidden H1 headers */\n .S6VXfe, /* Accessibility container */\n .Lu57id /* Potential other top bar */ {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n ";
|
|
166
218
|
extractContent(response: any): ContentExtraction;
|
|
219
|
+
/**
|
|
220
|
+
* Remove Google Search header/navbar from HTML
|
|
221
|
+
*/
|
|
222
|
+
removeHeader(html: string): string;
|
|
223
|
+
/**
|
|
224
|
+
* Remove Google Search footer from HTML
|
|
225
|
+
*/
|
|
226
|
+
removeFooter(html: string): string;
|
|
227
|
+
/**
|
|
228
|
+
* Remove Google Search sidebar from HTML
|
|
229
|
+
*/
|
|
230
|
+
removeSidebar(html: string): string;
|
|
167
231
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
168
232
|
}
|
|
169
233
|
|
package/dist/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
class t{static detect(t){const e={CHATGPT:0,GEMINI:0,PERPLEXITY:0,COPILOT:0,AIOVERVIEW:0,AIMODE:0};for(const[n,r]of Object.entries(this.PROVIDER_PATTERNS))for(const o of r)try{o(t)&&e[n]++}catch(t){}let n=0,r=null;for(const[t,o]of Object.entries(e))o>n&&(n=o,r=t);return 0===n?null:{provider:r,confidence:n/Object.values(e).reduce((t,e)=>Math.max(t,e),1)}}static getAllProviders(t){const e=[];for(const[n,r]of Object.entries(this.PROVIDER_PATTERNS)){let o=0;for(const e of r)try{e(t)&&o++}catch(t){}o>0&&e.push({provider:n,confidence:o/r.length})}return e.sort((t,e)=>e.confidence-t.confidence)}static validate(t,e){const n=this.detect(t);return(null==n?void 0:n.provider)===e&&n.confidence>.5}}t.PROVIDER_PATTERNS={CHATGPT:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("bg-token-bg-primary")||n.includes("text-token-text-secondary")},t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("chatgpt.com")||n.includes("openai.com")}],GEMINI:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("bard-sidenav")||n.includes("mat-sidenav")},t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("gemini.google.com")||n.includes("gem-sys-color")}],PERPLEXITY:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("perplexity.ai")||n.includes("prose")}],COPILOT:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("copilot.microsoft.com")||n.includes('data-testid="sidebar-container"')}],AIOVERVIEW:[t=>{var e,n,r,o;if(null===(n=null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.aioverview)||void 0===n?void 0:n.text)return!0;if(null===(r=null==t?void 0:t.aioverview)||void 0===r?void 0:r.text)return!0;const i=(null===(o=null==t?void 0:t.result)||void 0===o?void 0:o.html)||(null==t?void 0:t.html)||"";return i.includes("WIZ_global_data")||i.includes("DnVkpd")}],AIMODE:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("DZ13He")||n.includes("wYq63b")||n.includes("AI Mode")}]};class e{injectStyles(t,e){let n=t;(null==e?void 0:e.baseUrl)&&!t.includes("<base ")&&(n=n.includes("<head>")?n.replace("<head>",`<head><base href="${e.baseUrl}">`):n.replace(/(<html[^>]*>)/i,`$1<head><base href="${e.baseUrl}"></head>`));const r=(null==e?void 0:e.customCSS)||"";return r&&n.includes("<head>")?n=n.replace("<head>",`<head><style>${r}</style>`):r&&(n=n.replace(/(<html[^>]*>)/i,`$1<head><style>${r}</style></head>`)),n}sanitizeHtml(t){let e=t.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,"");return e=e.replace(/<noscript[\s\S]*?<\/noscript>/gi,""),e}isFullDocument(t){return/^\s*(<html|<!DOCTYPE)/i.test(t)}removeLinks(t){return t.replace(/<a\b[^>]*>([\s\S]*?)<\/a>/gim,"$1")}wrapFragment(t){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 ${t}\n</body>\n</html>`}}class n extends e{constructor(){super(...arguments),this.name="CHATGPT",this.baseUrl="https://chatgpt.com",this.defaultStyles='\n /* Force Dark Background on main containers and wrappers */\n html, body, main, article, footer, form,\n [class*="bg-"], [class*="footer"], [class*="bottom"],\n div[class*="border-t"],\n #thread-bottom-container, #thread-bottom,\n #thread, .composer-parent, [class*="group\\/thread"] {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n border-color: #2a2b36 !important;\n }\n\n /* Force background on specific white artifacts in the footer */\n #thread-bottom-container .bg-clip-padding,\n #thread-bottom-container .content-fade,\n #thread-bottom-container .absolute {\n background-color: transparent !important;\n }\n\n /* Specific targeting for the composer/input box (was white) */\n form .bg-token-bg-primary, form .shadow-short {\n background-color: #2a2b36 !important;\n border-color: #3e3f4b !important;\n box-shadow: none !important;\n }\n\n /* Disclaimer Footer - Force Dark Background */\n div[class*="text-token-text-secondary"] {\n color: #9ca3af !important;\n background-color: #131314 !important;\n }\n\n /* Force Text Color to Light */\n p, h1, h2, h3, h4, h5, h6, li, span, div, td, th, textarea, button {\n color: #e3e3e3 !important;\n }\n\n /* Links - Light Blue */\n a, a span {\n color: #8ab4f8 !important;\n }\n\n /* Code Blocks */\n pre, code, pre div, code span {\n background-color: #2a2b36 !important;\n color: #e3e3e3 !important;\n text-shadow: none !important;\n }\n\n /* Inputs/Textareas */\n input, textarea {\n background-color: transparent !important;\n color: #e3e3e3 !important;\n border-color: #3e3f4b !important;\n }\n\n /* Placeholder text */\n textarea::placeholder {\n color: #9ca3af !important;\n }\n\n /* Hide Sidebar */\n nav, [class*="sidebar"] {\n display: none !important;\n }\n\n /* Media visibility */\n img, video {\n opacity: 1 !important;\n }\n '}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in ChatGPT response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),o=this.injectStyles(o,{baseUrl:this.baseUrl,customCSS:this.defaultStyles}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}class r extends e{constructor(){super(...arguments),this.name="GEMINI",this.baseUrl="https://gemini.google.com",this.defaultStyles='\n /* Gemini Dark Mode Variable Overrides */\n :root {\n --gem-sys-color--surface: #131314 !important;\n --gem-sys-color--surface-container: #1e1f20 !important;\n --gem-sys-color--on-surface: #e3e3e3 !important;\n --bard-color-synthetic--chat-window-surface: #131314 !important;\n --bard-color-surface-dim-tmp: #131314 !important;\n }\n\n /* UI hiding - Gemini */\n bard-sidenav, mat-sidenav, .mat-drawer-backdrop, .side-nav-menu-button,\n\n /* Gemini "About Gemini" footer/navigation block */\n .gb_5a, .gb_5c, .gb_5d, .gb_5e,\n .gb_Uc, .gb_Vc, .gb_Wc,\n a[href*="about"],\n a[href*="subscriptions"],\n a[href*="business"],\n div[class*="gb_5"],\n .gb_Pd, .gb_Qd, .gb_Rd,\n .gb_Sd, .gb_Td, .gb_Ud, .gb_Vd,\n [aria-label*="About"],\n [aria-label*="Gemini App"],\n [aria-label*="Subscriptions"],\n [aria-label*="For Business"],\n *:contains("About Gemini"),\n *:contains("Gemini App"),\n *:contains("Subscriptions"),\n *:contains("For Business") {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n\n /* Force Dark Mode on Body and Gemini Containers */\n body, .content-container, chat-app, .main-content, .chat-container {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n '}extractContent(t){let e="",n="",r=[],o=t;return t.result&&(o=t.result),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?e=o:n=o:"object"==typeof o&&null!==o&&(o.html?e=o.html:o.content?o.content.trim().startsWith("<")?e=o.content:n=o.content:o.text&&(n=o.text),o.aioverview&&(o.aioverview.text&&(n=o.aioverview.text),o.aioverview.sources&&(r=o.aioverview.sources))),{html:e,text:n,sources:r}}parse(t,e){const{html:n,text:r,sources:o}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in Gemini response");let i=n||"";return!i&&r&&(i=`<div>${r.replace(/\n/g,"<br>")}</div>`),i=this.sanitizeHtml(i),i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:this.defaultStyles}),{provider:this.name,html:i,text:r,sources:o,metadata:{isFullDocument:this.isFullDocument(i)}}}}class o extends e{constructor(){super(...arguments),this.name="PERPLEXITY",this.baseUrl="https://www.perplexity.ai",this.defaultStyles="\n html {\n filter: invert(1) hue-rotate(180deg);\n background-color: white !important;\n }\n "}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in Perplexity response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),(null==e?void 0:e.removeLinks)&&(o=this.removeLinks(o)),o=this.injectStyles(o,{baseUrl:this.baseUrl,customCSS:(null==e?void 0:e.invertColors)?this.defaultStyles:""}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o),linksRemoved:(null==e?void 0:e.removeLinks)||!1,colorsInverted:(null==e?void 0:e.invertColors)||!1}}}}class i extends e{constructor(){super(...arguments),this.name="COPILOT",this.baseUrl="https://copilot.microsoft.com",this.defaultStyles='\n /* Copilot Sidebar & Header */\n div:has(> [data-testid="sidebar-container"]),\n [data-testid="sidebar-container"],\n [data-testid="sticky-header"],\n .side-nav-menu-button {\n display: none !important;\n }\n\n /* General Layout Fixes */\n main {\n width: 100% !important;\n max-width: 100% !important;\n margin: 0 !important;\n }\n '}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in Copilot response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),o=this.injectStyles(o,{baseUrl:this.baseUrl,customCSS:this.defaultStyles}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}class s extends e{constructor(){super(...arguments),this.name="AIOVERVIEW",this.baseUrl="https://www.google.com",this.defaultStyles='\n /* UI hiding - Google Search (AI Overview) */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L,\n\n /* Specific AI Mode Selectors */\n .DZ13He,\n .wYq63b,\n .eT9Cje,\n .bNg8Rb,\n .S6VXfe,\n .Lu57id {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n '}extractContent(t){let e="",n="",r=[],o=t;if(t.result&&(o=t.result),o.aioverview&&(o.aioverview.text&&(n=o.aioverview.text),o.aioverview.sources&&(r=o.aioverview.sources)),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?e=o:n=n||o:"object"==typeof o&&null!==o&&(o.html&&!n?e=o.html:o.content&&!n?o.content.trim().startsWith("<")?e=o.content:n=o.content:o.text&&!n&&(n=o.text)),e){const t=e.match(/"DnVkpd"\s*:\s*"((?:[^"\\]|\\.)*)"/);if(t&&t[1])try{let e=JSON.parse(`"${t[1]}"`);e=e.replace(/∰/g,'<hr class="gemini-separator">'),e=e.replace(/∞(https:\/\/[^ ]+\.(?:jpg|png|webp|gif|jpeg)(?:\?[^ ]*)?)/gi,'<br><img src="$1" class="gemini-image" alt="Generated Image"><br>'),e=e.replace(/∞/g,"<br>"),e=e.replace(/\n/g,"<br>"),n=e}catch(t){console.error("Failed to parse AI Overview WIZ data",t)}}return{html:e,text:n,sources:r}}parse(t,e){const{html:n,text:r,sources:o}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in AI Overview response");let i="";if(r&&!n){const t="\n body {\n font-family: 'Google Sans', Roboto, sans-serif;\n line-height: 1.5;\n padding: 20px;\n color: #e3e3e3;\n background-color: #131314;\n }\n .gemini-separator {\n border: 0;\n border-top: 1px solid #444;\n margin: 24px 0;\n }\n .gemini-image {\n max-width: 100%;\n border-radius: 8px;\n margin: 12px 0;\n border: 1px solid #333;\n }\n a { color: #8ab4f8; }\n table { border-collapse: collapse; width: 100%; margin: 16px 0; }\n th, td { border: 1px solid #444; padding: 8px; text-align: left; }\n th { background-color: #1f1f1f; }\n ";i=`<!DOCTYPE html>\n <html>\n <head>\n <base href="${this.baseUrl}">\n <style>${t}</style>\n </head>\n <body>\n ${r}\n </body>\n </html>`}else i=n||"",i=this.sanitizeHtml(i),i=this.injectStyles(i,{baseUrl:this.baseUrl,hideUI:!0,customCSS:this.defaultStyles});return{provider:this.name,html:i,text:r,sources:o,metadata:{isFullDocument:this.isFullDocument(i),hasWizData:!!r&&!n}}}}class a extends e{constructor(){super(...arguments),this.name="AIMODE",this.baseUrl="https://www.google.com",this.defaultStyles='\n /* UI hiding - Google Search (AI Mode) */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L,\n\n /* Specific AI Mode Selectors found in analysis */\n .DZ13He, /* Main sticky top bar */\n .wYq63b, /* Accessibility links bar */\n .eT9Cje, /* History/New Search buttons */\n .bNg8Rb, /* Hidden H1 headers */\n .S6VXfe, /* Accessibility container */\n .Lu57id /* Potential other top bar */ {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n '}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in AI Mode response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),o=this.injectStyles(o,{baseUrl:this.baseUrl,hideUI:!0,customCSS:this.defaultStyles}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}class l{constructor(){this.providers=new Map,this.providers.set("CHATGPT",new n),this.providers.set("GEMINI",new r),this.providers.set("PERPLEXITY",new o),this.providers.set("COPILOT",new i),this.providers.set("AIOVERVIEW",new s),this.providers.set("AIMODE",new a)}parse(e,n){const r=t.detect(e);if(!r)return this.parseGeneric(e,n);const o=this.providers.get(r.provider);if(!o)return null;try{const t=o.parse(e,n);return{...t,metadata:{...t.metadata,detectionConfidence:r.confidence}}}catch(t){return console.error(`Failed to parse response with ${r.provider}:`,t),null}}parseWithProvider(t,e,n){const r=this.providers.get(e);if(!r)throw new Error(`Unknown provider: ${e}`);try{return r.parse(t,n)}catch(t){return console.error(`Failed to parse response with ${e}:`,t),null}}detectProvider(e){const n=t.detect(e);return(null==n?void 0:n.provider)||null}detectAllProviders(e){return t.getAllProviders(e)}parseGeneric(t,e){let n="",r="";let o=t;var i;return t.result&&(o=t.result),"string"==typeof(i=o)?i.trim().startsWith("<")&&i.includes(">")?n=i:r=i:"object"==typeof i&&null!==i&&(i.html?n=i.html:i.content?i.content.trim().startsWith("<")?n=i.content:r=i.content:i.text&&(r=i.text)),n||r?(n&&(n=n.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,""),n=n.replace(/<noscript[\s\S]*?<\/noscript>/gi,"")),{provider:"CHATGPT",html:n,text:r,metadata:{isGeneric:!0}}):null}getSupportedProviders(){return Array.from(this.providers.keys())}registerProvider(t,e){this.providers.set(t,e)}}const c=new l,d=(t,e)=>c.parse(t,e),h=t=>c.detectProvider(t);export{a as AIModeProvider,s as AIOverviewProvider,l as AIResponseParser,e as BaseProvider,n as ChatGPTProvider,i as CopilotProvider,r as GeminiProvider,o as PerplexityProvider,t as ProviderDetector,h as detectProvider,d as parseAiResponse,c as parser};
|
|
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){return e.replace(/<div[^>]*class="[^"]*erp-sidecar:fixed[^"]*"[^>]*>.*?<\/div>\s*<\/div>\s*<\/div>\s*<\/div>/gis,"")}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}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),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),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+="",(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,r);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,t){let r="",o="";let n=e;var i;return e.result&&(n=e.result),"string"==typeof(i=n)?i.trim().startsWith("<")&&i.includes(">")?r=i:o=i:"object"==typeof i&&null!==i&&(i.html?r=i.html:i.content?i.content.trim().startsWith("<")?r=i.content:o=i.content:i.text&&(o=i.text)),r||o?(r&&(r=r.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,""),r=r.replace(/<noscript[\s\S]*?<\/noscript>/gi,"")),{provider:"CHATGPT",html:r,text:o,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};
|
|
2
2
|
//# sourceMappingURL=index.esm.js.map
|