@cloro-dev/response-parser 0.1.3 → 0.1.5
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 +61 -33
- package/dist/core/types.d.ts +3 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +76 -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 +16 -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/components/ResponseRenderer.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 +16 -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/components/ResponseRenderer.d.ts.map +1 -1
- package/dist/react/react/hooks/useResponse.d.ts.map +1 -1
- package/package.json +15 -12
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
|
+
- `removeHeader`: `boolean` - Remove navigation bar/header (default: `false`, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
|
|
78
|
+
- `removeFooter`: `boolean` - Remove follow-up input box/footer (default: `false`, ChatGPT, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
|
|
79
|
+
- `removeSidebar`: `boolean` - Remove sidebar (default: `false`, ChatGPT, Gemini & Copilot)
|
|
76
80
|
|
|
77
81
|
**Returns:** `ParsedResponse | null`
|
|
78
82
|
|
|
@@ -89,11 +93,15 @@ 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
|
+
- `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)
|
|
97
105
|
- `className`: CSS class for container
|
|
98
106
|
- `iframeProps`: Additional props for iframe
|
|
99
107
|
- `loadingComponent`: Custom loading component
|
|
@@ -109,14 +117,19 @@ Main React component for rendering AI responses.
|
|
|
109
117
|
React hook for parsing AI responses.
|
|
110
118
|
|
|
111
119
|
**Options:**
|
|
120
|
+
|
|
112
121
|
- `autoDetect`: Auto-detect provider (default: `true`)
|
|
113
122
|
- `provider`: Explicitly specify provider
|
|
114
123
|
- `removeLinks`: Remove all hyperlinks (default: `false`)
|
|
115
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)
|
|
116
128
|
- `onProviderDetected`: Callback when provider is detected
|
|
117
129
|
- `onError`: Callback when error occurs
|
|
118
130
|
|
|
119
131
|
**Returns:**
|
|
132
|
+
|
|
120
133
|
- `parsed`: Parsed response object
|
|
121
134
|
- `provider`: Detected provider
|
|
122
135
|
- `isLoading`: Loading state
|
|
@@ -128,44 +141,56 @@ React hook for parsing AI responses.
|
|
|
128
141
|
|
|
129
142
|
## Supported Providers
|
|
130
143
|
|
|
131
|
-
| Provider
|
|
132
|
-
|
|
133
|
-
| ChatGPT
|
|
134
|
-
| Gemini
|
|
135
|
-
| Perplexity
|
|
136
|
-
| Copilot
|
|
137
|
-
| AI Overview | ✅
|
|
138
|
-
| AI Mode
|
|
144
|
+
| Provider | Status | Features |
|
|
145
|
+
| ----------- | ------ | ------------------------------------------------- |
|
|
146
|
+
| ChatGPT | ✅ | Dark mode, sidebar hiding |
|
|
147
|
+
| Gemini | ✅ | Material Design overrides, navbar removal |
|
|
148
|
+
| Perplexity | ✅ | Color inversion, link removal, UI element removal |
|
|
149
|
+
| Copilot | ✅ | UI element hiding |
|
|
150
|
+
| AI Overview | ✅ | WIZ data extraction |
|
|
151
|
+
| AI Mode | ✅ | Google UI hiding |
|
|
139
152
|
|
|
140
153
|
## Examples
|
|
141
154
|
|
|
142
|
-
### Remove Hyperlinks
|
|
155
|
+
### Remove Hyperlinks
|
|
143
156
|
|
|
144
157
|
```typescript
|
|
145
|
-
import { parseAiResponse } from
|
|
158
|
+
import { parseAiResponse } from "@cloro-dev/response-parser";
|
|
146
159
|
|
|
147
160
|
const parsed = parseAiResponse(response, {
|
|
148
|
-
removeLinks: true
|
|
161
|
+
removeLinks: true, // Removes all <a> tags, keeps text
|
|
149
162
|
});
|
|
150
163
|
```
|
|
151
164
|
|
|
152
|
-
### Dark Mode
|
|
165
|
+
### Dark Mode
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<ResponseRenderer
|
|
169
|
+
response={response}
|
|
170
|
+
invertColors={true} // Apply CSS filter for dark mode
|
|
171
|
+
removeLinks={true} // Optionally remove links
|
|
172
|
+
/>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Clean View (Remove UI Elements)
|
|
153
176
|
|
|
154
177
|
```tsx
|
|
155
178
|
<ResponseRenderer
|
|
156
|
-
response={
|
|
157
|
-
|
|
158
|
-
|
|
179
|
+
response={response}
|
|
180
|
+
removeHeader={true} // Remove top navigation bar
|
|
181
|
+
removeFooter={true} // Remove follow-up input box
|
|
182
|
+
removeLinks={true} // Remove all hyperlinks
|
|
183
|
+
invertColors={true} // Dark mode
|
|
159
184
|
/>
|
|
160
185
|
```
|
|
161
186
|
|
|
162
187
|
### Manual Provider Specification
|
|
163
188
|
|
|
164
189
|
```typescript
|
|
165
|
-
import { parseAiResponse, AIProvider } from
|
|
190
|
+
import { parseAiResponse, AIProvider } from "@cloro-dev/response-parser";
|
|
166
191
|
|
|
167
192
|
const parsed = parseAiResponse(response, {
|
|
168
|
-
provider:
|
|
193
|
+
provider: "CHATGPT",
|
|
169
194
|
});
|
|
170
195
|
```
|
|
171
196
|
|
|
@@ -179,15 +204,22 @@ const ErrorComponent = ({ error, retry }) => (
|
|
|
179
204
|
</div>
|
|
180
205
|
);
|
|
181
206
|
|
|
182
|
-
<ResponseRenderer
|
|
183
|
-
response={response}
|
|
184
|
-
errorComponent={ErrorComponent}
|
|
185
|
-
/>
|
|
207
|
+
<ResponseRenderer response={response} errorComponent={ErrorComponent} />;
|
|
186
208
|
```
|
|
187
209
|
|
|
188
|
-
## What's Changed
|
|
210
|
+
## What's Changed
|
|
211
|
+
|
|
212
|
+
### v0.1.4
|
|
213
|
+
|
|
214
|
+
- ✅ **Renamed** `removeNavbar` → `removeHeader` (removes navigation bar/header)
|
|
215
|
+
- ✅ **Renamed** `removeFollowup` → `removeFooter` (removes follow-up input box/footer)
|
|
216
|
+
- ✅ **Extended** `removeHeader` support to AI Overview and AI Mode
|
|
217
|
+
- ✅ **Extended** `removeFooter` support to all providers (ChatGPT, Perplexity, Gemini, Copilot, AI Overview, AI Mode)
|
|
218
|
+
- ✅ **Improved** ChatGPT styling
|
|
219
|
+
- ✅ **Updated** AI Mode and AI Overview parsers
|
|
220
|
+
|
|
221
|
+
### v0.1.3
|
|
189
222
|
|
|
190
|
-
### Simplified API
|
|
191
223
|
- ✅ **Always sanitizes** HTML by default (removes scripts for security)
|
|
192
224
|
- ✅ **Always includes** provider-specific styles
|
|
193
225
|
- ✅ **Always uses** provider's base URL for relative links
|
|
@@ -196,12 +228,8 @@ const ErrorComponent = ({ error, retry }) => (
|
|
|
196
228
|
- ❌ **Removed** `includeStyles` option (always enabled)
|
|
197
229
|
- ❌ **Removed** `baseUrl` option (uses provider default)
|
|
198
230
|
|
|
199
|
-
### Remaining Options
|
|
200
|
-
Only two options remain for simple usage:
|
|
201
|
-
- `removeLinks`: Remove all hyperlinks from HTML
|
|
202
|
-
- `invertColors`: Apply color inversion (mainly for Perplexity)
|
|
203
|
-
|
|
204
231
|
### Component Renaming
|
|
232
|
+
|
|
205
233
|
- `AiResponseRenderer` → `ResponseRenderer`
|
|
206
234
|
- `useAiResponse` → `useResponse`
|
|
207
235
|
|
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,115 @@ 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 cookie banner from HTML
|
|
191
|
+
*/
|
|
192
|
+
removeCookieBanner(html: string): string;
|
|
193
|
+
/**
|
|
194
|
+
* Remove Copilot sidebar from HTML
|
|
195
|
+
*/
|
|
196
|
+
removeSidebar(html: string): string;
|
|
151
197
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
152
198
|
}
|
|
153
199
|
|
|
154
200
|
declare class AIOverviewProvider extends BaseProvider {
|
|
155
201
|
readonly name: AIProvider;
|
|
156
202
|
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
203
|
extractContent(response: any): ContentExtraction;
|
|
204
|
+
/**
|
|
205
|
+
* Remove Google Search header/navbar from HTML
|
|
206
|
+
*/
|
|
207
|
+
removeHeader(html: string): string;
|
|
208
|
+
/**
|
|
209
|
+
* Remove Google Search footer from HTML
|
|
210
|
+
*/
|
|
211
|
+
removeFooter(html: string): string;
|
|
212
|
+
/**
|
|
213
|
+
* Remove Google Search sidebar from HTML
|
|
214
|
+
*/
|
|
215
|
+
removeSidebar(html: string): string;
|
|
159
216
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
160
217
|
}
|
|
161
218
|
|
|
162
219
|
declare class AIModeProvider extends BaseProvider {
|
|
163
220
|
readonly name: AIProvider;
|
|
164
221
|
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
222
|
extractContent(response: any): ContentExtraction;
|
|
223
|
+
/**
|
|
224
|
+
* Remove Google Search header/navbar from HTML
|
|
225
|
+
*/
|
|
226
|
+
removeHeader(html: string): string;
|
|
227
|
+
/**
|
|
228
|
+
* Remove Google Search footer from HTML
|
|
229
|
+
*/
|
|
230
|
+
removeFooter(html: string): string;
|
|
231
|
+
/**
|
|
232
|
+
* Remove Google Search sidebar from HTML
|
|
233
|
+
*/
|
|
234
|
+
removeSidebar(html: string): string;
|
|
167
235
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
168
236
|
}
|
|
169
237
|
|
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){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};
|
|
2
2
|
//# sourceMappingURL=index.esm.js.map
|