@kudoai/chatgpt.js 3.8.0 → 3.8.2

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/LICENSE.md CHANGED
@@ -1,3 +1,29 @@
1
+ <div align="center">
2
+ <h6>
3
+ <a href="docs/">
4
+ <picture>
5
+ <source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://assets.chatgptjs.org/images/icons/earth/white/icon32.svg?v=e638eac">
6
+ <img height=14 src="https://assets.chatgptjs.org/images/icons/earth/black/icon32.svg?v=e638eac">
7
+ </picture>
8
+ </a>
9
+ English |
10
+ <a href="docs/zh-cn/LICENSE.md">简体中文</a> |
11
+ <a href="docs/zh-tw/LICENSE.md">繁體中文</a> |
12
+ <a href="docs/ja/LICENSE.md">日本</a> |
13
+ <a href="docs/ko/LICENSE.md">한국인</a> |
14
+ <a href="docs/hi/LICENSE.md">हिंदी</a> |
15
+ <a href="docs/ne/LICENSE.md">नेपाली</a> |
16
+ <a href="docs/de/LICENSE.md">Deutsch</a> |
17
+ <a href="docs/es/LICENSE.md">Español</a> |
18
+ <a href="docs/fr/LICENSE.md">Français</a> |
19
+ <a href="docs/it/LICENSE.md">Italiano</a> |
20
+ <a href="docs/nl/LICENSE.md">Nederlands</a> |
21
+ <a href="docs/pt/LICENSE.md">Português</a> |
22
+ <a href="docs/ru/LICENSE.md">Английский</a> |
23
+ <a href="docs/vi/LICENSE.md">Việt</a>
24
+ </h6>
25
+ </div>
26
+
1
27
  # MIT License
2
28
 
3
29
  **Copyright © 2023–2025 [KudoAI](https://github.com/KudoAI) & [contributors](.#-contributors).**
package/README.md CHANGED
@@ -51,18 +51,20 @@
51
51
  <img src="https://img.shields.io/badge/License-MIT-fc4f2d.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
52
52
  <a href="https://www.npmjs.com/package/@kudoai/chatgpt.js/v/latest" target="_blank" rel="noopener">
53
53
  <img src="https://img.shields.io/npm/v/%40kudoai%2Fchatgpt.js?logo=npm&logoColor=white&labelColor=464646&color=blue&style=for-the-badge&label=Latest+Release"></a>
54
- <a href="https://github.com/KudoAI/chatgpt.js/tree/v3.8.0/dist/chatgpt.min.js" target="_blank" rel="noopener">
55
- <img src="https://img.shields.io/github/size/KudoAI/chatgpt.js/dist/chatgpt.min.js?branch=v3.8.0&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge"></a>
54
+ <a href="https://github.com/KudoAI/chatgpt.js/tree/v3.8.2/dist/chatgpt.min.js" target="_blank" rel="noopener">
55
+ <img src="https://img.shields.io/github/size/KudoAI/chatgpt.js/dist/chatgpt.min.js?branch=v3.8.2&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge"></a>
56
56
  <a href="https://www.codefactor.io/repository/github/kudoai/chatgpt.js" target="_blank" rel="noopener">
57
57
  <img src="https://img.shields.io/codefactor/grade/github/kudoai/chatgpt.js?label=Code+Quality&logo=codefactor&logoColor=white&labelColor=464646&color=1acc6c&style=for-the-badge"></a>
58
58
  <a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=kudoai_chatgpt.js" target="_blank" rel="noopener">
59
59
  <img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dkudoai_chatgpt.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
60
60
  <a href="https://github.com/sindresorhus/awesome-chatgpt#javascript" target="_blank" rel="noopener">
61
61
  <img src="https://img.shields.io/badge/Mentioned_in-Awesome-cca8c4?logo=awesomelists&logoColor=white&labelColor=464646&style=for-the-badge"></a>
62
+ <a href="https://opentools.ai/tools/chatgptjs">
63
+ <img alt="[Voted Top Tool on OpenTools.ai]" src="https://img.shields.io/badge/Voted_Top_Tool-OpenTools.ai-f43f5e?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTAiIGhlaWdodD0iMzUwIiBzdHlsZT0ic2hhcGUtcmVuZGVyaW5nOmdlb21ldHJpY1ByZWNpc2lvbjt0ZXh0LXJlbmRlcmluZzpnZW9tZXRyaWNQcmVjaXNpb247aW1hZ2UtcmVuZGVyaW5nOm9wdGltaXplUXVhbGl0eTtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZCI+PHBhdGggZmlsbD0iI2ZlZmZmZSIgZD0iTTM2LjUgMzAuNWM5My44MzItMSAxODcuODMyLTEuMzMzIDI4Mi0xIC4xNjcgOTQuMDAxIDAgMTg4LjAwMS0uNSAyODJsLTc4LTc4Yy0uNS00MS42NjUtLjY2Ny04My4zMzItLjUtMTI1LTQxLjY2OC4xNjctODMuMzM1IDAtMTI1LS41YTg1MzcuOTUgODUzNy45NSAwIDAgMC03OC03Ny41WiIgc3R5bGU9Im9wYWNpdHk6Ljk4NCIvPjxwYXRoIGZpbGw9IiNmZWZmZmUiIGQ9Ik0yOS41IDM1LjVhMjkyNC4wMjQgMjkyNC4wMjQgMCAwIDEgNzguNSA3OWMuNSA0MS42NjUuNjY3IDgzLjMzMi41IDEyNSA0Mi4wMDEtLjE2NyA4NC4wMDEgMCAxMjYgLjVhODQzMy4xNiA4NDMzLjE2IDAgMCAxIDc3IDc3LjVjLTkzLjk5OCAxLTE4Ny45OTggMS4zMzMtMjgyIDF2LTI4M1oiIHN0eWxlPSJvcGFjaXR5Oi45ODEiLz48L3N2Zz4=&logoColor=white&labelColor=464646&style=for-the-badge"></a>
62
64
  <a href="https://www.producthunt.com/posts/chatgpt-js" target="_blank" rel="noopener">
63
65
  <img src="https://img.shields.io/badge/Featured_on-Product_Hunt-ff6154?logo=producthunt&logoColor=white&labelColor=464646&style=for-the-badge"></a>
64
66
  <a href="https://trendshift.io/repositories/2896" target="_blank" rel="noopener">
65
- <img src="https://img.shields.io/badge/GitHub-Trended_Top_20-869da0?logo=github&logoColor=white&labelColor=464646&style=for-the-badge"></a>
67
+ <img src="https://img.shields.io/badge/Trended-Top_20_Repository-869da0?logo=github&logoColor=white&labelColor=464646&style=for-the-badge"></a>
66
68
  <a href="#">
67
69
  <img src="https://img.shields.io/badge/jsDelivr_Requests-2,000,000+-2bbbd8.svg?logo=jsdelivr&logoColor=white&labelColor=464646&style=for-the-badge"></a>
68
70
 
@@ -118,7 +120,7 @@
118
120
 
119
121
  ```js
120
122
  (async () => {
121
- await import('https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.8.0/dist/chatgpt.min.js');
123
+ await import('https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.8.2/dist/chatgpt.min.js');
122
124
  // Your code here...
123
125
  })();
124
126
  ```
@@ -127,7 +129,7 @@
127
129
 
128
130
  ```js
129
131
  var xhr = new XMLHttpRequest();
130
- xhr.open('GET', 'https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.8.0/dist/chatgpt.min.js');
132
+ xhr.open('GET', 'https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.8.2/dist/chatgpt.min.js');
131
133
  xhr.onload = function () {
132
134
  if (xhr.status === 200) {
133
135
  var chatgptJS = document.createElement('script');
@@ -150,7 +152,7 @@ function yourCode() {
150
152
 
151
153
  ```js
152
154
  ...
153
- // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.8.0/dist/chatgpt.min.js
155
+ // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.8.2/dist/chatgpt.min.js
154
156
  // ==/UserScript==
155
157
 
156
158
  // Your code here...
@@ -220,7 +222,7 @@ chatgpt.get('reply', 'last');
220
222
 
221
223
  Each call equally fetches the last response. If you think it works, it probably will... so just type it!
222
224
 
223
- If it didn't, check out the extended [userguide](https://github.com/KudoAI/chatgpt.js/blob/v3.8.0/docs/USERGUIDE.md), or simply submit an [issue](https://github.com/KudoAI/chatgpt.js/issues) or [PR](https://github.com/KudoAI/chatgpt.js/pulls) and it will be integrated, ezpz!
225
+ If it didn't, check out the extended [userguide](https://github.com/KudoAI/chatgpt.js/blob/v3.8.2/docs/USERGUIDE.md), or simply submit an [issue](https://github.com/KudoAI/chatgpt.js/issues) or [PR](https://github.com/KudoAI/chatgpt.js/pulls) and it will be integrated, ezpz!
224
226
 
225
227
  <img height=8px width="100%" src="https://assets.chatgptjs.org/images/separators/gradient-aqua.png?v=e638eac">
226
228
 
@@ -241,7 +243,7 @@ https://github.com/KudoAI/chatgpt.js/assets/10906554/f53c740f-d5e0-49b6-ae02-3b3
241
243
  [Readme](https://amazongpt.kudoai.com/#readme) /
242
244
  [Discuss](https://github.com/KudoAI/amazongpt/discussions)
243
245
 
244
- ### <picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://assets.autoclearchatgpt.com/images/icons/openai/white/icon48.png?cece513"><img width=21 src="https://assets.autoclearchatgpt.com/images/icons/openai/black/icon48.png?cece513"></picture> [Autoclear ChatGPT History](https://autoclearchatgpt.com) &nbsp;<a href="https://github.com/awesome-scripts/awesome-userscripts#chatgpt" target="_blank" rel="noopener"><img src="https://assets.autoclearchatgpt.com/images/badges/awesome/badge.svg?2c0d9fc" style="margin:0 0 -2px 5px"></a>
246
+ ### <picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://assets.autoclearchatgpt.com/images/icons/openai/white/icon48.png?cece513"><img width=21 src="https://assets.autoclearchatgpt.com/images/icons/openai/black/icon48.png?cece513"></picture> [Autoclear ChatGPT History](https://autoclearchatgpt.com) &nbsp;<a href="https://github.com/awesome-scripts/awesome-userscripts#-chatgpt" target="_blank" rel="noopener"><img src="https://assets.autoclearchatgpt.com/images/badges/awesome/badge.svg?2c0d9fc" style="margin:0 0 -2px 5px"></a>
245
247
 
246
248
  > Auto-clear your ChatGPT query history for maximum privacy.
247
249
  <br>[Install](https://docs.autoclearchatgpt.com/#-installation) /
@@ -255,7 +257,7 @@ https://github.com/KudoAI/chatgpt.js/assets/10906554/f53c740f-d5e0-49b6-ae02-3b3
255
257
  [Readme](https://docs.bravegpt.com/#readme) /
256
258
  [Discuss](https://github.com/KudoAI/bravegpt/discussions)
257
259
 
258
- ### <picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://assets.chatgptautocontinue.com/images/icons/continue-symbol/white/icon48.png?v=61c4f16"><img width=21 src="https://assets.chatgptautocontinue.com/images/icons/continue-symbol/black/icon48.png?v=61c4f16"></picture> [ChatGPT Auto-Continue ⏩](https://chatgptautocontinue.com) &nbsp;<a href="https://github.com/awesome-scripts/awesome-userscripts#chatgpt" target="_blank" rel="noopener"><img src="https://assets.chatgptautocontinue.com/images/badges/awesome/badge.svg?3c80c0c" style="margin:0 0 -3px 3px"></a>
260
+ ### <picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://assets.chatgptautocontinue.com/images/icons/continue-symbol/white/icon48.png?v=61c4f16"><img width=21 src="https://assets.chatgptautocontinue.com/images/icons/continue-symbol/black/icon48.png?v=61c4f16"></picture> [ChatGPT Auto-Continue ⏩](https://chatgptautocontinue.com) &nbsp;<a href="https://github.com/awesome-scripts/awesome-userscripts#-chatgpt" target="_blank" rel="noopener"><img src="https://assets.chatgptautocontinue.com/images/badges/awesome/badge.svg?3c80c0c" style="margin:0 0 -3px 3px"></a>
259
261
 
260
262
  > Automatically continue generating answers when ChatGPT responses get cut-off.
261
263
  <br>[Install](https://docs.chatgptautocontinue.com/#-installation) /
@@ -269,7 +271,7 @@ https://github.com/KudoAI/chatgpt.js/assets/10906554/f53c740f-d5e0-49b6-ae02-3b3
269
271
  [Readme](https://github.com/adamlui/chatgpt-auto-talk#readme) /
270
272
  [Discuss](https://github.com/adamlui/chatgpt-auto-talk/discussions)
271
273
 
272
- ### <picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://assets.chatgptautorefresh.com/images/icons/openai/white/icon48.png?a45cf1e"><img width=21 src="https://assets.chatgptautorefresh.com/images/icons/openai/black/icon48.png?a45cf1e"></picture> [ChatGPT Auto Refresh ↻](https://chatgptautorefresh.com) &nbsp;<a href="https://github.com/awesome-scripts/awesome-userscripts#chatgpt" target="_blank" rel="noopener"><img src="https://assets.chatgptautorefresh.com/images/badges/awesome/badge.svg?1080f44" style="margin:0 0 -2px 5px"></a>
274
+ ### <picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://assets.chatgptautorefresh.com/images/icons/openai/white/icon48.png?a45cf1e"><img width=21 src="https://assets.chatgptautorefresh.com/images/icons/openai/black/icon48.png?a45cf1e"></picture> [ChatGPT Auto Refresh ↻](https://chatgptautorefresh.com) &nbsp;<a href="https://github.com/awesome-scripts/awesome-userscripts#-chatgpt" target="_blank" rel="noopener"><img src="https://assets.chatgptautorefresh.com/images/badges/awesome/badge.svg?1080f44" style="margin:0 0 -2px 5px"></a>
273
275
 
274
276
  > Keeps ChatGPT sessions fresh to eliminate network errors + Cloudflare checks.
275
277
  <br>[Install](https://docs.chatgptautorefresh.com/#-installation) /
@@ -283,7 +285,7 @@ https://github.com/KudoAI/chatgpt.js/assets/10906554/f53c740f-d5e0-49b6-ae02-3b3
283
285
  [Readme](https://docs.ddgpt.com/#readme) /
284
286
  [Discuss](https://github.com/KudoAI/duckduckgpt/discussions)
285
287
 
286
- ### <picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://assets.googlegpt.io/images/icons/app/white/icon48.png"><img width=21 src="https://assets.googlegpt.io/images/icons/app/black/icon48.png"></picture> [GoogleGPT](https://googlegpt.io) &nbsp;<a href="https://github.com/awesome-scripts/awesome-userscripts#chatgpt" target="_blank" rel="noopener"><img src="https://assets.googlegpt.io/images/badges/awesome/badge.svg?699c63d" style="margin:0 0 -2px 5px"></a>
288
+ ### <picture><source type="image/png" media="(prefers-color-scheme: dark)" srcset="https://assets.googlegpt.io/images/icons/app/white/icon48.png"><img width=21 src="https://assets.googlegpt.io/images/icons/app/black/icon48.png"></picture> [GoogleGPT](https://googlegpt.io) &nbsp;<a href="https://github.com/awesome-scripts/awesome-userscripts#-chatgpt" target="_blank" rel="noopener"><img src="https://assets.googlegpt.io/images/badges/awesome/badge.svg?699c63d" style="margin:0 0 -2px 5px"></a>
287
289
 
288
290
  > Add AI chat & search summaries to Google Search, powered by the latest LLMs!
289
291
  <br>[Install](https://greasyfork.googlegpt.io) /
@@ -413,6 +415,8 @@ This library exists thanks to code, translations, issues & ideas from the follow
413
415
  <img title="@AliasUruz" src="https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/130197125?first-contrib=2024.12.1-new-chat-selector-outdated-report&h=47&w=47&mask=circle&maxage=7d"></a>
414
416
  <a href="https://github.com/ericdachen" target="_blank" rel="noopener">
415
417
  <img title="@ericdachen" src="https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54382303?first-contrib=2025.3.20-implement-warp-to-golden-sponsors&h=47&w=47&mask=circle&maxage=7d"></a>
418
+ <a href="https://github.com/m-k8s" target="_blank" rel="noopener">
419
+ <img title="@m-k8s" src="https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/42094254?first-contrib=2025.7.26-fixed-hand,ling-of-intermediate-msgs-by-getchatdata&h=47&w=47&mask=circle&maxage=7d"></a>
416
420
  <a href="https://github.com/dependabot" target="_blank" rel="noopener">
417
421
  <img title="Dependabot" src="https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/29110&h=47&w=47&mask=circle&maxage=7d"></a>
418
422
  <a href="https://chatgpt.com" target="_blank" rel="noopener">
@@ -476,7 +480,7 @@ This library exists thanks to code, translations, issues & ideas from the follow
476
480
  <div align="center">
477
481
 
478
482
  **[Releases](https://github.com/KudoAI/chatgpt.js/releases)** /
479
- [Userguide](https://github.com/KudoAI/chatgpt.js/blob/v3.8.0/docs/USERGUIDE.md) /
483
+ [Userguide](https://github.com/KudoAI/chatgpt.js/blob/v3.8.2/docs/USERGUIDE.md) /
480
484
  [Discuss](https://github.com/KudoAI/chatgpt.js/discussions) /
481
485
  [Back to top ↑](#top)
482
486
 
package/chatgpt.js CHANGED
@@ -25,8 +25,8 @@ const chatgpt = {
25
25
  selectors: {
26
26
  btns: {
27
27
  continue: 'button:has(svg[class*=rotate] > path[d^="M4.47189"])',
28
- createImage: 'button[data-testid="composer-create-image"]',
29
- deepResearch: 'button[data-testid="composer-deep-research"]',
28
+ createImage: 'button[data-testid=composer-create-image]',
29
+ deepResearch: 'button[data-testid=composer-deep-research]',
30
30
  login: 'button[data-testid*=login]',
31
31
  newChat: 'a[href="/"]:has(svg),' // Pencil button (when logged in)
32
32
  + 'button:has([d^="M3.06957"])', // Cycle Arrows button (in temp chat logged out)
@@ -34,10 +34,10 @@ const chatgpt = {
34
34
  // 'Try Again' entry of model selector below msg
35
35
  + 'div[role=menuitem] div:has(svg):has(path[d^="M3.06957"])',
36
36
  scroll: 'button:has(> svg > path[d^="M12 21C11.7348"])',
37
- search: 'button[data-testid="composer-button-search"]',
38
- reason: 'button[data-testid="composer-button-reason"]',
37
+ search: 'button[data-testid=composer-button-search]',
38
+ reason: 'button[data-testid=composer-button-reason]',
39
39
  send: 'button[data-testid=send-button]',
40
- sidebar: 'button[data-testid*=sidebar-button]',
40
+ sidebar: 'div[style*=-sidebar-width] button[data-testid=close-sidebar-button], div[style*=-sidebar-rail-width] button[aria-controls=stage-slideover-sidebar]',
41
41
  stop: 'button[data-testid=stop-button]',
42
42
  upload: 'button:has(> svg > path[d^="M12 3C12.5523"])',
43
43
  voice: 'button[data-testid*=composer-speech-button]'
@@ -49,9 +49,9 @@ const chatgpt = {
49
49
  chatHistory: 'div#history',
50
50
  errors: { toast: 'div.toast-root', txt: 'div[class*=text-error]' },
51
51
  footer: 'div#thread-bottom-container > div:last-of-type > div, span.text-sm.leading-none',
52
- header: 'div#page-header, main div.sticky:first-of-type',
52
+ header: 'header#page-header',
53
53
  links: { newChat: 'nav a[href="/"]', sidebarItem: 'nav a' },
54
- sidebar: 'div[class*=sidebar]:has(nav > div#sidebar-header)',
54
+ sidebar: 'div#stage-slideover-sidebar, div.bg-token-sidebar-surface-primary',
55
55
  ssgManifest: 'script[src*="_ssgManifest.js"]'
56
56
  },
57
57
 
@@ -69,14 +69,14 @@ const chatgpt = {
69
69
  console.log('\n%c🤖 chatgpt.js personas\n',
70
70
  'font-family: sans-serif ; font-size: xxx-large ; font-weight: bold')
71
71
  for (const prompt of data) // list personas
72
- console.log(`%c${ prompt.title }`, 'font-family: monospace ; font-size: larger ;')
72
+ console.log(`%c${prompt.title}`, 'font-family: monospace ; font-size: larger ;')
73
73
  return resolve()
74
74
  }
75
75
  const selectedPrompt = data.find(obj => obj.title.toLowerCase() == persona.toLowerCase())
76
76
  if (!selectedPrompt)
77
- return reject(`🤖 chatgpt.js >> Persona '${ persona }' was not found!`)
77
+ return reject(`🤖 chatgpt.js >> Persona '${persona}' was not found!`)
78
78
  chatgpt.send(selectedPrompt.prompt, 'click')
79
- console.info(`Loading ${ persona } persona...`)
79
+ console.info(`Loading ${persona} persona...`)
80
80
  chatgpt.isIdle().then(() => console.info('Persona activated!'))
81
81
  return resolve()
82
82
  }
@@ -128,15 +128,16 @@ const chatgpt = {
128
128
  drag: {
129
129
  mousedown(event) { // find modal, update styles, attach listeners, init XY offsets
130
130
  if (event.button != 0) return // prevent non-left-click drag
131
- if (getComputedStyle(event.target).cursor == 'pointer') return // prevent drag on interactive elems
131
+ if (!/auto|default/.test(getComputedStyle(event.target).cursor))
132
+ return // prevent drag on interactive elems
132
133
  chatgpt.draggingModal = event.currentTarget
133
134
  event.preventDefault() // prevent sub-elems like icons being draggable
134
135
  Object.assign(chatgpt.draggingModal.style, {
135
136
  transition: '0.1s', willChange: 'transform', transform: 'scale(1.05)' })
136
- document.body.style.cursor = 'grabbing'; // update cursor
137
- [...chatgpt.draggingModal.children] // prevent hover FX if drag lags behind cursor
138
- .forEach(child => child.style.pointerEvents = 'none');
139
- ['mousemove', 'mouseup'].forEach(eventType => // add listeners
137
+ document.body.style.cursor = 'grabbing' // update cursor
138
+ ;[...chatgpt.draggingModal.children] // prevent hover FX if drag lags behind cursor
139
+ .forEach(child => child.style.pointerEvents = 'none')
140
+ ;['mousemove', 'mouseup'].forEach(eventType => // add listeners
140
141
  document.addEventListener(eventType, handlers.drag[eventType]))
141
142
  const draggingModalRect = chatgpt.draggingModal.getBoundingClientRect()
142
143
  handlers.drag.offsetX = event.clientX - draggingModalRect.left +21
@@ -153,10 +154,10 @@ const chatgpt = {
153
154
  mouseup() { // restore styles/pointer events, remove listeners, reset chatgpt.draggingModal
154
155
  Object.assign(chatgpt.draggingModal.style, { // restore styles
155
156
  cursor: 'inherit', transition: 'inherit', willChange: 'auto', transform: 'scale(1)' })
156
- document.body.style.cursor = ''; // restore cursor
157
- [...chatgpt.draggingModal.children] // restore pointer events
158
- .forEach(child => child.style.pointerEvents = '');
159
- ['mousemove', 'mouseup'].forEach(eventType => // remove listeners
157
+ document.body.style.cursor = '' // restore cursor
158
+ ;[...chatgpt.draggingModal.children] // restore pointer events
159
+ .forEach(child => child.style.pointerEvents = '')
160
+ ;['mousemove', 'mouseup'].forEach(eventType => // remove listeners
160
161
  document.removeEventListener(eventType, handlers.drag[eventType]))
161
162
  chatgpt.draggingModal = null
162
163
  }
@@ -180,13 +181,13 @@ const chatgpt = {
180
181
  modalStyle.setAttribute('last-updated', thisUpdated.toString())
181
182
  document.head.append(modalStyle)
182
183
  }
183
- modalStyle.innerText = ( // update prev/new style contents
184
+ modalStyle.textContent = ( // update prev/new style contents
184
185
  `.chatgpt-modal { /* vars */
185
- --transition: opacity 0.65s cubic-bezier(.165,.84,.44,1), /* for fade-in */
186
- transform 0.55s cubic-bezier(.165,.84,.44,1) ; /* for move-in */
187
- --bg-transition: background-color 0.25s ease ; /* for bg dim */
188
- --btn-transition: transform 0.1s ease-in-out, box-shadow 0.1s ease-in-out ; /* for smooth zoom */
189
- --btn-shadow: 2px 1px ${ scheme == 'dark' ? '54px #00cfff' : '30px #9cdaff' }}`
186
+ --transition: opacity 0.65s cubic-bezier(.165,.84,.44,1), /* for fade-in */
187
+ transform 0.55s cubic-bezier(.165,.84,.44,1) ; /* for move-in */
188
+ --bg-transition: background-color 0.25s ease ; /* for bg dim */
189
+ --btn-transition: transform 0.1s ease-in-out, box-shadow 0.1s ease-in-out ; /* for smooth zoom */
190
+ --btn-shadow: 2px 1px ${ scheme == 'dark' ? '54px #00cfff' : '30px #9cdaff' }}`
190
191
 
191
192
  + '.no-mobile-tap-outline { outline: none ; -webkit-tap-highlight-color: transparent }'
192
193
 
@@ -196,8 +197,8 @@ const chatgpt = {
196
197
  position: fixed ; top: 0 ; left: 0 ; width: 100% ; height: 100% ; /* expand to full view-port */
197
198
  display: flex ; justify-content: center ; align-items: center ; z-index: 9999 ; /* align */
198
199
  transition: var(--bg-transition) ; /* for bg dim */
199
- -webkit-transition: var(--bg-transition) ; -moz-transition: var(--bg-transition) ;
200
- -o-transition: var(--bg-transition) ; -ms-transition: var(--bg-transition) }`
200
+ -webkit-transition: var(--bg-transition) ; -moz-transition: var(--bg-transition) ;
201
+ -o-transition: var(--bg-transition) ; -ms-transition: var(--bg-transition) }`
201
202
 
202
203
  // Alert styles
203
204
  + `.chatgpt-modal > div {
@@ -211,13 +212,13 @@ const chatgpt = {
211
212
  border: 1px solid ${ scheme == 'dark' ? 'white' : '#b5b5b5' };
212
213
  transform: translateX(-3px) translateY(7px) ; /* offset to move-in from */
213
214
  max-width: 75vw ; word-wrap: break-word ; border-radius: 15px ;
214
- --shadow: 0 30px 60px rgba(0,0,0,0.12) ; box-shadow: var(--shadow) ;
215
- -webkit-box-shadow: var(--shadow) ; -moz-box-shadow: var(--shadow) ;
215
+ --shadow: 0 30px 60px rgba(0,0,0,0.12) ; box-shadow: var(--shadow) ;
216
+ -webkit-box-shadow: var(--shadow) ; -moz-box-shadow: var(--shadow) ;
216
217
  user-select: none ; -webkit-user-select: none ; -moz-user-select: none ;
217
- -o-user-select: none ; -ms-user-select: none ;
218
+ -o-user-select: none ; -ms-user-select: none ;
218
219
  transition: var(--transition) ; /* for fade-in + move-in */
219
- -webkit-transition: var(--transition) ; -moz-transition: var(--transition) ;
220
- -o-transition: var(--transition) ; -ms-transition: var(--transition) }
220
+ -webkit-transition: var(--transition) ; -moz-transition: var(--transition) ;
221
+ -o-transition: var(--transition) ; -ms-transition: var(--transition) }
221
222
  .chatgpt-modal h2 { font-weight: bold ; font-size: 24px ; margin-bottom: 9px }
222
223
  .chatgpt-modal a { color: ${ scheme == 'dark' ? '#00cfff' : '#1e9ebb' }}
223
224
  .chatgpt-modal a:hover { text-decoration: underline }
@@ -232,13 +233,13 @@ const chatgpt = {
232
233
  display: flex ; justify-content: flex-end ; margin: 20px -5px -3px 0 ;
233
234
  ${ isMobile ? 'flex-direction: column-reverse' : '' }}
234
235
  .chatgpt-modal button {
235
- font-size: 14px ; text-transform: uppercase ;
236
+ font-size: 14px ; text-transform: uppercase ; cursor: crosshair ;
236
237
  margin-left: ${ isMobile ? 0 : 10 }px ; padding: ${ isMobile ? 15 : 8 }px 18px ;
237
238
  ${ isMobile ? 'margin-top: 5px ; margin-bottom: 3px ;' : '' }
238
239
  border-radius: 0 ; border: 1px solid ${ scheme == 'dark' ? 'white' : 'black' };
239
240
  transition: var(--btn-transition) ;
240
- -webkit-transition: var(--btn-transition) ; -moz-transition: var(--btn-transition) ;
241
- -o-transition: var(--btn-transition) ; -ms-transition: var(--btn-transition) }
241
+ -webkit-transition: var(--btn-transition) ; -moz-transition: var(--btn-transition) ;
242
+ -o-transition: var(--btn-transition) ; -ms-transition: var(--btn-transition) }
242
243
  .chatgpt-modal button:hover {
243
244
  transform: scale(1.055) ; color: black ;
244
245
  background-color: #${ scheme == 'dark' ? '00cfff' : '9cdaff' };
@@ -270,7 +271,7 @@ const chatgpt = {
270
271
  }
271
272
 
272
273
  // Insert text into elems
273
- modalTitle.innerText = title || '' ; modalMessage.innerText = msg || '' ; chatgpt.renderHTML(modalMessage)
274
+ modalTitle.textContent = title || '' ; modalMessage.innerText = msg || '' ; chatgpt.renderHTML(modalMessage)
274
275
 
275
276
  // Create/append buttons (if provided) to buttons div
276
277
  const modalButtons = document.createElement('div')
@@ -421,7 +422,7 @@ const chatgpt = {
421
422
  this.toggle.refreshFrame()
422
423
  document.removeEventListener('visibilitychange', this.toggle.beacons)
423
424
  clearTimeout(this.isActive) ; this.isActive = null
424
- console.log(`↻ ChatGPT >> [${ chatgpt.autoRefresh.nowTimeStamp()}] Auto refresh de-activated`)
425
+ console.log(`↻ ChatGPT >> [${chatgpt.autoRefresh.nowTimeStamp()}] Auto refresh de-activated`)
425
426
  } else
426
427
  console.log(`↻ ChatGPT >> [${chatgpt.autoRefresh.nowTimeStamp()}] Auto refresh already inactive!`)
427
428
  },
@@ -647,7 +648,7 @@ const chatgpt = {
647
648
  year = now.getFullYear(),
648
649
  hour = now.getHours().toString().padStart(2, '0'),
649
650
  minute = now.getMinutes().toString().padStart(2, '0')
650
- filename = `ChatGPT_${ day }-${ month }-${ year }_${ hour }-${ minute }.txt`
651
+ filename = `ChatGPT_${day}-${month}-${year}_${hour}-${minute}.txt`
651
652
 
652
653
  // Create transcript from active chat
653
654
  if (chatToGet == 'active' && /\/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$/.test(window.location.href)) {
@@ -691,13 +692,13 @@ const chatgpt = {
691
692
  }
692
693
 
693
694
  // Export transcript
694
- console.info(`Exporting transcript as ${ format.toUpperCase() }...`)
695
+ console.info(`Exporting transcript as ${format.toUpperCase()}...`)
695
696
  if (format == 'pdf') { // convert SVGs + launch PDF printer
696
697
 
697
698
  // Convert SVG icons to data URLs for proper PDF rendering
698
699
  transcript = transcript.replace(/<svg.*?<\/svg>/g, (match) => {
699
700
  const dataURL = 'data:image/svg+xml,' + encodeURIComponent(match)
700
- return `<img src="${ dataURL }">`
701
+ return `<img src="${dataURL}">`
701
702
  })
702
703
 
703
704
  // Launch PDF printer
@@ -885,7 +886,7 @@ const chatgpt = {
885
886
  (chatToGet == 'active' && !new RegExp(`\/${re_chatID.source}$`).test(location.href))) {
886
887
  chatToGet = Number.isInteger(chatToGet) ? chatToGet : 0 // preserve index, otherwise get latest
887
888
  if (chatToGet > data.length) // reject if index out-of-bounds
888
- return reject(`🤖 chatgpt.js >> Chat with index ${ chatToGet + 1 }`
889
+ return reject(`🤖 chatgpt.js >> Chat with index ${ chatToGet +1 }`
889
890
  + ` is out of bounds. Only ${data.length} chats exist!`)
890
891
  for (const detail of detailsToGet) detailsToReturn[detail] = data[chatToGet][detail]
891
892
  return resolve(detailsToReturn)
@@ -930,7 +931,7 @@ const chatgpt = {
930
931
  userMessages.sort((a, b) => a.msg.create_time - b.msg.create_time) // sort in chronological order
931
932
 
932
933
  if (parseInt(msgToGet, 10) + 1 > userMessages.length) // reject if index out of bounds
933
- return reject(`🤖 chatgpt.js >> Message/response with index ${ msgToGet + 1 }`
934
+ return reject(`🤖 chatgpt.js >> Message/response with index ${ msgToGet +1 }`
934
935
  + ` is out of bounds. Only ${userMessages.length} messages/responses exist!`)
935
936
 
936
937
  // Fill [chatGPTMessages]
@@ -938,8 +939,9 @@ const chatgpt = {
938
939
  let sub = []
939
940
  for (const key in data) {
940
941
  if (data[key].message != null && data[key].message.author.role == 'assistant'
941
- && data[key].parent == userMessage.id)
942
+ && isUserMsgAncestor(key, userMessage.id)) {
942
943
  sub.push(data[key].message)
944
+ }
943
945
  }
944
946
  sub.sort((a, b) => a.create_time - b.create_time) // sort in chronological order
945
947
  sub = sub.map(x => { // pull out msgs after sorting
@@ -972,6 +974,17 @@ const chatgpt = {
972
974
  return resolve(msgToGet == 'all' ? msgsToReturn // if 'all' passed, return array
973
975
  : msgToGet == 'latest' ? msgsToReturn[msgsToReturn.length - 1] // else if 'latest' passed, return latest
974
976
  : msgsToReturn[msgToGet] ) // else return element of array
977
+
978
+ function isUserMsgAncestor(msgID, targetUserID) {
979
+ let currentID = msgID ; const maxDepth = 10 ; let depth = 0
980
+ while (currentID && depth < maxDepth) {
981
+ const currentMsg = data[currentID]
982
+ if (!currentMsg?.message) return false
983
+ if (currentMsg.id == targetUserID) return true
984
+ currentID = currentMsg.parent ; depth++
985
+ }
986
+ return false
987
+ }
975
988
  }
976
989
  xhr.send()
977
990
  })})}
@@ -1104,7 +1117,7 @@ const chatgpt = {
1104
1117
  const validMethods = ['POST', 'GET']
1105
1118
  method = (method || '').trim().toUpperCase()
1106
1119
  if (!method || !validMethods.includes(method)) // reject if not valid method
1107
- return console.error(`Valid methods are ${ validMethods }`)
1120
+ return console.error(`Valid methods are ${validMethods}`)
1108
1121
  if (!token) return console.error('Please provide a valid access token!')
1109
1122
  if (body && typeof body != 'object') // reject if body is passed but not an object
1110
1123
  return console.error(`Invalid body data type. Got ${ typeof body }, expected object`)
@@ -1125,7 +1138,7 @@ const chatgpt = {
1125
1138
  return reject('🤖 chatgpt.js >> ' + responseData.detail.description)
1126
1139
  else if (xhr.status != 200)
1127
1140
  return reject('🤖 chatgpt.js >> Request failed. Cannot contact custom instructions endpoint.')
1128
- console.info(`Custom instructions successfully contacted with method ${ method }`)
1141
+ console.info(`Custom instructions successfully contacted with method ${method}`)
1129
1142
  return resolve(responseData || {}) // return response data no matter what the method is
1130
1143
  }
1131
1144
  xhr.send(JSON.stringify(body) || '') // if body is passed send it, else just send the request
@@ -1290,7 +1303,12 @@ const chatgpt = {
1290
1303
 
1291
1304
  minify() { chatgpt.code.minify(); },
1292
1305
 
1293
- notify(msg, position, notifDuration, shadow) {
1306
+ notify(...args) {
1307
+ const scheme = chatgpt.isDarkMode() ? 'dark' : 'light'
1308
+ let msg, position, notifDuration, shadow, toast
1309
+ if (typeof args[0] == 'object' && !Array.isArray(args[0]))
1310
+ ({ msg, position, notifDuration, shadow, toast } = args[0])
1311
+ else [msg, position, notifDuration, shadow] = args
1294
1312
  notifDuration = notifDuration ? +notifDuration : 1.75; // sec duration to maintain notification visibility
1295
1313
  const fadeDuration = 0.35, // sec duration of fade-out
1296
1314
  vpYoffset = 23, vpXoffset = 27 // px offset from viewport border
@@ -1299,7 +1317,7 @@ const chatgpt = {
1299
1317
  const notificationDiv = document.createElement('div') // make div
1300
1318
  notificationDiv.id = Math.floor(chatgpt.randomFloat() * 1000000) + Date.now()
1301
1319
  notificationDiv.classList.add('chatgpt-notif')
1302
- notificationDiv.innerText = msg // insert msg
1320
+ notificationDiv.textContent = msg // insert msg
1303
1321
  document.body.append(notificationDiv) // insert into DOM
1304
1322
 
1305
1323
  // Create/append close button
@@ -1324,7 +1342,7 @@ const chatgpt = {
1324
1342
  + (notificationDiv.isRight ? 'Right' : 'Left')
1325
1343
 
1326
1344
  // Create/append/update notification style (if missing or outdated)
1327
- const thisUpdated = 1735767823541 // timestamp of last edit for this file's `notifStyle`
1345
+ const thisUpdated = 1746996635555 // timestamp of last edit for this file's `notifStyle`
1328
1346
  let notifStyle = document.querySelector('#chatgpt-notif-style') // try to select existing style
1329
1347
  if (!notifStyle || parseInt(notifStyle.getAttribute('last-updated'), 10) < thisUpdated) { // if missing or outdated
1330
1348
  if (!notifStyle) { // outright missing, create/id/attr/append it first
@@ -1332,7 +1350,7 @@ const chatgpt = {
1332
1350
  notifStyle.setAttribute('last-updated', thisUpdated.toString())
1333
1351
  document.head.append(notifStyle)
1334
1352
  }
1335
- notifStyle.innerText = ( // update prev/new style contents
1353
+ notifStyle.textContent = ( // update prev/new style contents
1336
1354
  '.chatgpt-notif {'
1337
1355
  + 'font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC",'
1338
1356
  + '"Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", sans-serif ;'
@@ -1355,6 +1373,13 @@ const chatgpt = {
1355
1373
  + '45% { opacity: 0.05 ; transform: rotateX(-81deg) }'
1356
1374
  + '100% { opacity: 0 ; transform: rotateX(-180deg) scale(1.15) }}'
1357
1375
  )
1376
+ if (toast) notifStyle.textContent += `
1377
+ div.chatgpt-notif {
1378
+ position: absolute ; left: 50% ; right: 21% !important ; text-align: center ;
1379
+ ${ scheme == 'dark' ? 'border: 2px solid white ;' : '' }
1380
+ margin-${ !notificationDiv.isTop ? 'bottom: 105px' : 'top: 42px' };
1381
+ transform: translate(-50%, -50%) scale(0.6) !important }
1382
+ div.chatgpt-notif > div.notif-close-btn { top: 18px ; right: 7px ; transform: scale(2) }`
1358
1383
  }
1359
1384
 
1360
1385
  // Enqueue notification
@@ -1368,7 +1393,7 @@ const chatgpt = {
1368
1393
  notificationDiv.style.right = notificationDiv.isRight ? vpXoffset.toString() + 'px' : ''
1369
1394
  notificationDiv.style.left = !notificationDiv.isRight ? vpXoffset.toString() + 'px' : ''
1370
1395
 
1371
- // Reposition old notifications
1396
+ // Re-position old notifications
1372
1397
  const thisQuadrantQueue = notifyProps.queue[notificationDiv.quadrant]
1373
1398
  if (thisQuadrantQueue.length > 1) {
1374
1399
  try { // to move old notifications
@@ -1376,9 +1401,9 @@ const chatgpt = {
1376
1401
  const oldDiv = document.getElementById(divId),
1377
1402
  offsetProp = oldDiv.style.top ? 'top' : 'bottom', // pick property to change
1378
1403
  vOffset = +parseInt(oldDiv.style[offsetProp]) +5 + oldDiv.getBoundingClientRect().height
1379
- oldDiv.style[offsetProp] = `${ vOffset }px` // change prop
1404
+ oldDiv.style[offsetProp] = `${vOffset}px` // change prop
1380
1405
  }
1381
- } catch (err) {}
1406
+ } catch (err) { console.warn('Failed to re-position notification:', err) }
1382
1407
  }
1383
1408
 
1384
1409
  // Show notification
@@ -1394,7 +1419,7 @@ const chatgpt = {
1394
1419
 
1395
1420
  // Add notification dismissal to timeout schedule + button clicks
1396
1421
  const dismissNotif = () => {
1397
- notificationDiv.style.animation = `notif-zoom-fade-out ${ fadeDuration }s ease-out`;
1422
+ notificationDiv.style.animation = `notif-zoom-fade-out ${fadeDuration}s ease-out`;
1398
1423
  clearTimeout(dismissFuncTID)
1399
1424
  }
1400
1425
  const dismissFuncTID = setTimeout(dismissNotif, hideDelay * 1000) // maintain visibility for `hideDelay` secs, then dismiss
@@ -1425,7 +1450,7 @@ const chatgpt = {
1425
1450
  }
1426
1451
  Object.keys(colors).forEach(elem => { // populate dark scheme colors if missing
1427
1452
  colors[elem][1] = colors[elem][1] ||
1428
- '#' + (Number(`0x1${ colors[elem][0].replace(/^#/, '') }`) ^ 0xFFFFFF)
1453
+ '#' + (Number(`0x1${colors[elem][0].replace(/^#/, '')}`) ^ 0xFFFFFF)
1429
1454
  .toString(16).substring(1).toUpperCase() // convert to hex
1430
1455
  })
1431
1456
 
@@ -1455,7 +1480,7 @@ const chatgpt = {
1455
1480
  : (( Object.keys(this).find(obj => Object.keys(this[obj]).includes(this[functionName[1]].name)) + '.' )
1456
1481
  + this[functionName[1]].name )),
1457
1482
  isAsync = this[functionName[1]]?.constructor.name == 'AsyncFunction'
1458
- console.log('%c>> %c' + ( isChatGptObjParent ? '' : `${ functionName[0] }.%c`) + functionName[1]
1483
+ console.log('%c>> %c' + ( isChatGptObjParent ? '' : `${functionName[0]}.%c`) + functionName[1]
1459
1484
  + ' - https://chatgptjs.org/userguide/' + /(?:.*\.)?(.*)/.exec(rootFunction)[1].toLowerCase() + ( isAsync ? '-async' : '' ) + '\n%c[%c'
1460
1485
  + ((( functionName[0] == 'chatgpt' && functionName[1] == this[functionName[1]].name ) || // parent is chatgpt + names match or
1461
1486
  !isChatGptObjParent) // parent is chatgpt.obj
@@ -1640,14 +1665,14 @@ const chatgpt = {
1640
1665
  const validValues = ['dark', 'light', 'system']
1641
1666
  if (!value) return console.error('Please specify a scheme value!')
1642
1667
  if (!validValues.includes(value))
1643
- return console.error(`Invalid scheme value. Valid values are [${ validValues }]`)
1668
+ return console.error(`Invalid scheme value. Valid values are [${validValues}]`)
1644
1669
 
1645
1670
  // Determine scheme to set
1646
1671
  let schemeToSet = value
1647
1672
  if (value == 'system')
1648
1673
  schemeToSet = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
1649
1674
  localStorage.setItem('theme', value)
1650
- console.info(`Scheme set to ${ value.toUpperCase() }.`)
1675
+ console.info(`Scheme set to ${value.toUpperCase()}.`)
1651
1676
 
1652
1677
  // Toggle scheme if necessary
1653
1678
  if (!document.documentElement.classList.contains(schemeToSet)) this.toggle()
@@ -1665,7 +1690,7 @@ const chatgpt = {
1665
1690
  for (let i = 0; i < arguments.length; i++) if (typeof arguments[i] != 'string')
1666
1691
  return console.error(`Argument ${ i + 1 } must be a string.`)
1667
1692
  chatgpt.send('What is the sentiment of the following text'
1668
- + ( entity ? ` towards the entity ${ entity },` : '')
1693
+ + ( entity ? ` towards the entity ${entity},` : '')
1669
1694
  + ' from strongly negative to strongly positive?\n\n' + text )
1670
1695
  console.info('Analyzing sentiment...')
1671
1696
  await chatgpt.isIdle()
@@ -1686,7 +1711,7 @@ const chatgpt = {
1686
1711
  return new Promise((resolve, reject) => {
1687
1712
  const xhr = new XMLHttpRequest()
1688
1713
  chatgpt.getChatData(chatToGet).then(chat => {
1689
- xhr.open('GET', `${ chatgpt.endpoints.openAI.chat }/${ chat.id }`, true)
1714
+ xhr.open('GET', `${chatgpt.endpoints.openAI.chat}/${chat.id}`, true)
1690
1715
  xhr.setRequestHeader('Content-Type', 'application/json')
1691
1716
  xhr.setRequestHeader('Authorization', 'Bearer ' + token)
1692
1717
  xhr.onload = () => {
@@ -1719,13 +1744,13 @@ const chatgpt = {
1719
1744
  const confirmShareChat = (token, data) => {
1720
1745
  return new Promise((resolve, reject) => {
1721
1746
  const xhr = new XMLHttpRequest()
1722
- xhr.open('PATCH', `${ chatgpt.endpoints.openAI.share }/${ data.share_id }`, true)
1747
+ xhr.open('PATCH', `${chatgpt.endpoints.openAI.share}/${data.share_id}`, true)
1723
1748
  xhr.setRequestHeader('Content-Type', 'application/json')
1724
1749
  xhr.setRequestHeader('Authorization', 'Bearer ' + token)
1725
1750
  xhr.onload = () => {
1726
1751
  if (xhr.status != 200)
1727
1752
  return reject('🤖 chatgpt.js >> Request failed. Cannot share chat.')
1728
- console.info(`Chat shared at '${ data.share_url }'`)
1753
+ console.info(`Chat shared at '${data.share_url}'`)
1729
1754
  return resolve() // the response has nothing useful
1730
1755
  }
1731
1756
  xhr.send(JSON.stringify({ // request body
@@ -1762,8 +1787,7 @@ const chatgpt = {
1762
1787
  activateObserver() {
1763
1788
 
1764
1789
  // Stop the previous observer to preserve resources
1765
- if (this.observer instanceof MutationObserver)
1766
- try { this.observer.disconnect() } catch (e) {}
1790
+ if (this.observer instanceof MutationObserver) this.observer.disconnect()
1767
1791
 
1768
1792
  if (!this.elems.length) return console.error('🤖 chatgpt.js >> No elems to append!')
1769
1793
 
@@ -1900,7 +1924,7 @@ const chatgpt = {
1900
1924
  for (let i = 0; i < arguments.length; i++) if (typeof arguments[i] != 'string')
1901
1925
  return console.error(`Argument ${ i + 1 } must be a string.`)
1902
1926
  chatgpt.send('Suggest some names. ' + ( details || '' ))
1903
- console.info(`Creating ${ ideaType }...`)
1927
+ console.info(`Creating ${ideaType}...`)
1904
1928
  await chatgpt.isIdle()
1905
1929
  return chatgpt.getChatData('active', 'msg', 'chatgpt', 'latest')
1906
1930
  },