").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
5 | //# sourceMappingURL=jquery.min.map
--------------------------------------------------------------------------------
/chrome-extension/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 | "name": "Talk-to-ChatGPT",
4 | "version": "2.9.0",
5 | "description": "Talk to ChatGPT through your microphone and hear its responses with a voice. Uses speech recognition and text-to-speech technologies",
6 | "action": {
7 | "default_popup": "popup.html",
8 | "default_icon": {
9 | "16": "images/icon-16.png",
10 | "32": "images/icon-32.png"
11 | },
12 | "default_title": "Talk-to-ChatGPT V2.9.0"
13 | },
14 | "content_scripts":[
15 | {
16 | "matches":[
17 | "https://chatgpt.com/*"
18 | ],
19 | "js": ["jquery.min.js", "fontawesome.min.js", "content.js"]
20 | }
21 | ],
22 | "icons": {
23 | "16": "images/icon-16.png",
24 | "32": "images/icon-32.png",
25 | "48": "images/icon-48.png",
26 | "128": "images/icon-128.png"
27 | },
28 | "background": {
29 | "service_worker": "background.js"
30 | },
31 | "permissions": [
32 | "offscreen"
33 | ]
34 | }
--------------------------------------------------------------------------------
/chrome-extension/offscreen.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/chrome-extension/offscreen.js:
--------------------------------------------------------------------------------
1 | let MESSAGES_PLAYED = new Set();
2 | let AUDIO_PLAYER = null;
3 |
4 | // Listen for messages from the extension
5 | chrome.runtime.onMessage.addListener(msg => {
6 | if (msg.type === "playSound" && 'data' in msg)
7 | playAudio(msg.data);
8 | });
9 |
10 | // Play sound with access to DOM APIs
11 | function playAudio(source) {
12 | const messageId = `${source.messageId}${source.onEnded}`;
13 |
14 | if (MESSAGES_PLAYED.has(messageId)) {
15 | console.log(`offscreen.js: Message ${messageId} already played once`);
16 | return;
17 | }
18 |
19 | // Save ID to avoid replaying it
20 | MESSAGES_PLAYED.add(messageId);
21 | console.log(`offscreen.js: Going to play the following message (#${messageId}): ${source.transcript}`);
22 |
23 | if (AUDIO_PLAYER === null) {
24 | AUDIO_PLAYER = new Audio();
25 | } else {
26 | try {
27 | AUDIO_PLAYER.onended = null;
28 | AUDIO_PLAYER.stop();
29 | } catch (e) {
30 | console.log(e);
31 | }
32 | }
33 |
34 | // Set source and attributes
35 | AUDIO_PLAYER.src = source.audio;
36 | AUDIO_PLAYER.volume = 1;
37 |
38 | if (source.onEnded === "elevenlabs") {
39 | AUDIO_PLAYER.onended = function () {
40 | console.log(`offscreen.js: playback #${messageId} ended, sending message to continueElevenLabs. Transcript = ${source.transcript}`);
41 | chrome.runtime.sendMessage({
42 | type: 'continueElevenLabs',
43 | target: 'ttgpt',
44 | data: {
45 | transcript: source.transcript
46 | }
47 | });
48 | };
49 | }
50 |
51 | AUDIO_PLAYER.play();
52 | }
53 |
--------------------------------------------------------------------------------
/chrome-extension/popup.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
TALK-TO-ChatGPT
8 |
9 |
10 | To start using this extension,
11 | you need to open the ChatGPT home page.
12 |
13 | Once you are logged in, a box will display at the top right corner of your screen with a 'START' button.
14 | Click START to start talking.
15 |
16 |
17 |
18 | This extension allows you to talk to ChatGPT with your microphone, using your browser's voice recognition API.
19 | Then, when your browser receives the reply, it is read out loud with a voice of your choosing.
20 |
21 | • When the box's bottom border is red, your microphone is listening
22 | • When the box's bottom border is green, the bot is talking
23 | • Access the settings by clicking the settings icon: change voice/language, bot talking speed, and more.
24 |
25 |
26 |
27 | If something doesn't appear to work, click here for status and troubleshooting.
28 | Thank you for not instantly posting a 1-star review on the extension store if something doesn't work as expected :-) This is a free program I do in my spare time and I appreciate constructive criticism. Make sure to tell me what's wrong and I will look into it.
29 |
30 |
31 |
32 |
33 |
34 |
Credits
35 |
36 |
39 |
40 |
41 |
42 |
43 | Author: C. Nedelcu
44 | GUI: pixelsoda, S. James
45 | Icons: FontAwesome
46 |
47 |
48 |
49 | Project home page and source code: GitHub
50 | Demontration video on Youtube: click here
51 |
52 |
53 |
54 | Donations
55 | Are you enjoying Talk-To-ChatGPT and want me to continue improving it?
56 | You can help by making a donation to the project.
57 | Please click the Donate button to proceed.
58 |
59 |
60 |
61 |
62 |
Having trouble getting it to work?
63 |
64 |
65 | Is the extension no longer working for you?
66 | The box isn't appearing where it should,
67 | or something appears to be off?
68 | Make sure to check the project page for the latest status information.
69 | Sometimes OpenAI update their user interface and break the extension, but I can usually get it fixed quickly.
70 |
71 |
72 |
73 | 1. This extension is only designed for Chromium-based desktop browsers such as Google Chrome or Microsoft Edge.
74 | If it doesn't work in your specific browser, it's because your browser doesn't support the necessary APIs.
75 | There is no need to contact us to add support to another browser, we can't do anything about it.
76 | Support for these APIs must be implemented by the browser itself.
77 |
78 |
79 | 2. What to do if the computer isn't recognizing text when you speak?
80 | Did you make sure to give permission to use your microphone?
81 | Is the microphone recording volume high enough?
82 | Check this
83 | speech recognition test page.
84 | If the speech recognition isn't working on that page, then it won't work on Talk-to-ChatGPT.
85 | Also, for Mac users, make sure your laptop's lid isn't in a closed state
86 | (because of this).
87 |
88 |
89 |
90 | 3. What to do if the bot's voice is scrambled, jammed, or not working at all?
91 | Try opening the settings and changing the bot's voice to a different option. Also make sure the talking speed is set to 1.
92 | Sometimes, voices listed in the text-to-speech API don't work correctly, for some reason.
93 |
94 |
95 |
96 | 4. What if it worked well for a bit, and suddenly nothing works correctly anymore?
97 | In that case, try restarting your browser.
98 | There is sometimes a bug with Chromium's voice API,
99 | when the bug occurs, it can completely jam the API until you restart your browser.
100 |
101 |
102 |
103 |
104 | 5. Do you have another problem that isn't listed here?
105 | Please visit the project page,
106 | read the FAQ section, and if you answer still isn't in there,
107 | please ask your questions by clicking on the 'Issues' tab at the top of the page.
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/images/260-main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C-Nedelcu/talk-to-chatgpt/851519fa4b07617c257ad8f5053d729b09656863/images/260-main.png
--------------------------------------------------------------------------------
/images/260-settings-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C-Nedelcu/talk-to-chatgpt/851519fa4b07617c257ad8f5053d729b09656863/images/260-settings-1.png
--------------------------------------------------------------------------------
/images/260-settings-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C-Nedelcu/talk-to-chatgpt/851519fa4b07617c257ad8f5053d729b09656863/images/260-settings-2.png
--------------------------------------------------------------------------------
/legacy/NOTES.md:
--------------------------------------------------------------------------------
1 | This is the legacy version that needs to be ran manually in the javascript console or as a bookmarklet. Features go up to version 1.4.
2 |
3 | To get the latest features, please use the Google Chrome extension, which can be downloaded from the web store here:
4 | https://chrome.google.com/webstore/detail/talk-to-chatgpt/hodadfhfagpiemkeoliaelelfbboamlk
5 |
--------------------------------------------------------------------------------
/legacy/bookmarklet.js:
--------------------------------------------------------------------------------
1 | javascript:(function()%7B%2F%2F%20TALK%20TO%20CHATGPT%0A%2F%2F%20---------------%0A%2F%2F%20Author%09%09%3A%20C.%20NEDELCU%0A%2F%2F%20Version%09%09%3A%201.4%0A%2F%2F%20Git%20repo%20%09%3A%20https%3A%2F%2Fgithub.com%2FC-Nedelcu%2Ftalk-to-chatgpt%0A%2F%2F%20Chat%20GPT%20URL%09%3A%20https%3A%2F%2Fchat.openai.com%2Fchat%0A%2F%2F%20How%20to%20use%20%20%20%3A%20https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DgOagK0r5syM%0A%0A%0A%2F%2F%20----------------------------%0A%2F%2F%20SETTINGS%20(FEEL%20FREE%20TO%20EDIT)%0A%2F%2F%20----------------------------%0A%2F%2F%20These%20are%20the%20default%20settings.%20Since%20v1.3%2C%20a%20'settings'%20menu%20allows%20to%20change%20most%20of%20the%20below%20values%20in%20the%20UI%0A%2F%2F%20Since%20v1.4%2C%20these%20settings%20are%20saved.%20So%20there%20is%20no%20need%20to%20edit%20them%20out%20anymore.%0A%0A%2F%2F%20Settings%20for%20the%20text-to-speech%20functionality%20(the%20bot's%20voice)%0Avar%20CN_TEXT_TO_SPEECH_RATE%20%3D%201.2%3B%20%2F%2F%20The%20higher%20the%20rate%2C%20the%20faster%20the%20bot%20will%20speak%0Avar%20CN_TEXT_TO_SPEECH_PITCH%20%3D%201%3B%20%2F%2F%20This%20will%20alter%20the%20pitch%20for%20the%20bot's%20voice%0A%0A%2F%2F%20Indicate%20a%20locale%20code%20such%20as%20'fr-FR'%2C%20'en-US'%2C%20to%20use%20a%20particular%20language%20for%20the%20speech%20recognition%20functionality%20(when%20you%20speak%20into%20the%20mic)%0A%2F%2F%20If%20you%20leave%20this%20blank%2C%20the%20system's%20default%20language%20will%20be%20used%0Avar%20CN_WANTED_LANGUAGE_SPEECH_REC%20%3D%20%22%22%3B%20%2F%2F%22fr-FR%22%3B%0A%0A%2F%2F%20Determine%20which%20word%20will%20cause%20this%20scrip%20to%20stop.%0Avar%20CN_SAY_THIS_WORD_TO_STOP%20%3D%20%22stop%22%3B%0A%0A%2F%2F%20Determine%20which%20word%20will%20cause%20this%20script%20to%20temporarily%20pause%0Avar%20CN_SAY_THIS_WORD_TO_PAUSE%20%3D%20%22pause%22%3B%0A%0A%2F%2F%20Indicate%20%22locale-voice%20name%22%20(the%20possible%20values%20are%20difficult%20to%20determine%2C%20you%20should%20just%20ignore%20this%20and%20use%20the%20settings%20menu%20instead)%0Avar%20CN_WANTED_VOICE_NAME%20%3D%20%22%22%3B%0A%0A%2F%2F%20----------------------------%0A%0A%0A%2F%2F%20-------------------%0A%2F%2F%20CODE%20(DO%20NOT%20ALTER)%0A%2F%2F%20-------------------%0Avar%20CN_MESSAGE_COUNT%20%3D%200%3B%0Avar%20CN_CURRENT_MESSAGE%20%3D%20null%3B%0Avar%20CN_CURRENT_MESSAGE_SENTENCES%20%3D%20%5B%5D%3B%0Avar%20CN_SPEECHREC%20%3D%20null%3B%0Avar%20CN_IS_READING%20%3D%20false%3B%0Avar%20CN_IS_LISTENING%20%3D%20false%3B%0Avar%20CN_FINISHED%20%3D%20false%3B%0Avar%20CN_PAUSED%20%3D%20false%3B%0Avar%20CN_WANTED_VOICE%20%3D%20null%3B%0Avar%20CN_TIMEOUT_KEEP_SYNTHESIS_WORKING%20%3D%20null%3B%0Avar%20CN_TIMEOUT_KEEP_SPEECHREC_WORKING%20%3D%20null%3B%0Avar%20CN_SPEECH_REC_SUPPORTED%20%3D%20false%3B%0Avar%20CN_SPEAKING_DISABLED%20%3D%20false%3B%0Avar%20CN_SPEECHREC_DISABLED%20%3D%20false%3B%0A%0A%2F%2F%20This%20function%20will%20say%20the%20given%20text%20out%20loud%20using%20the%20browser's%20speech%20synthesis%20API%0Afunction%20CN_SayOutLoud(text)%20%7B%0A%09if%20(!text%20%7C%7C%20CN_SPEAKING_DISABLED)%20%7B%0A%09%09if%20(CN_SPEECH_REC_SUPPORTED%20%26%26%20CN_SPEECHREC%20%26%26%20!CN_IS_LISTENING%20%26%26%20!CN_PAUSED%20%26%26%20!CN_SPEECHREC_DISABLED)%20CN_SPEECHREC.start()%3B%0A%09%09clearTimeout(CN_TIMEOUT_KEEP_SPEECHREC_WORKING)%3B%0A%09%09CN_TIMEOUT_KEEP_SPEECHREC_WORKING%20%3D%20setTimeout(CN_KeepSpeechRecWorking%2C%20100)%3B%0A%09%09return%3B%0A%09%7D%0A%09%0A%09%2F%2F%20Let's%20speak%20out%20loud%0A%09console.log(%22Saying%20out%20loud%3A%20%22%2Btext)%3B%0A%09var%20msg%20%3D%20new%20SpeechSynthesisUtterance()%3B%0A%09msg.text%20%3D%20text%3B%0A%09%0A%09if%20(CN_WANTED_VOICE)%20msg.voice%20%3D%20CN_WANTED_VOICE%3B%0A%09msg.rate%20%3D%20CN_TEXT_TO_SPEECH_RATE%3B%0A%09msg.pitch%20%3D%20CN_TEXT_TO_SPEECH_PITCH%3B%0A%09msg.onstart%20%3D%20()%20%3D%3E%20%7B%0A%09%09%2F%2F%20Make%20border%20green%0A%09%09%24(%22%23TTGPTSettings%22).css(%22border%22%2C%20%222px%20solid%20lightgreen%22)%3B%0A%09%09%0A%09%09%2F%2F%20If%20speech%20recognition%20is%20active%2C%20disable%20it%0A%09%09if%20(CN_IS_LISTENING)%20CN_SPEECHREC.stop()%3B%0A%09%09%0A%09%09if%20(CN_FINISHED)%20return%3B%0A%09%09CN_IS_READING%20%3D%20true%3B%0A%09%09clearTimeout(CN_TIMEOUT_KEEP_SYNTHESIS_WORKING)%3B%0A%09%09CN_TIMEOUT_KEEP_SYNTHESIS_WORKING%20%3D%20setTimeout(CN_KeepSpeechSynthesisActive%2C%205000)%3B%0A%09%7D%3B%0A%09msg.onend%20%3D%20()%20%3D%3E%20%7B%0A%09%09%2F%2F%20Make%20border%20grey%20again%0A%09%09%24(%22%23TTGPTSettings%22).css(%22border%22%2C%20%222px%20solid%20%23888%22)%3B%0A%09%09%0A%09%09if%20(CN_FINISHED)%20return%3B%0A%09%09%0A%09%09%2F%2F%20Finished%20speaking%0A%09%09clearTimeout(CN_TIMEOUT_KEEP_SYNTHESIS_WORKING)%3B%0A%09%09console.log(%22Finished%20speaking%20out%20loud%22)%3B%0A%09%09%0A%09%09%2F%2F%20restart%20listening%0A%09%09CN_IS_READING%20%3D%20false%3B%0A%09%09setTimeout(function()%20%7B%0A%09%09%09if%20(!window.speechSynthesis.speaking)%20%7B%0A%09%09%09%09if%20(CN_SPEECH_REC_SUPPORTED%20%26%26%20CN_SPEECHREC%20%26%26%20!CN_IS_LISTENING%20%26%26%20!CN_PAUSED%20%26%26%20!CN_SPEECHREC_DISABLED)%20CN_SPEECHREC.start()%3B%0A%09%09%09%09clearTimeout(CN_TIMEOUT_KEEP_SPEECHREC_WORKING)%3B%0A%09%09%09%09CN_TIMEOUT_KEEP_SPEECHREC_WORKING%20%3D%20setTimeout(CN_KeepSpeechRecWorking%2C%20100)%3B%0A%09%09%09%7D%0A%09%09%7D%2C%20500)%3B%0A%09%7D%0A%09CN_IS_READING%20%3D%20true%3B%0A%09window.speechSynthesis.speak(msg)%3B%0A%7D%0A%0A%2F%2F%20This%20is%20a%20workaround%20for%20Chrome's%20bug%20in%20the%20speech%20synthesis%20API%20(https%3A%2F%2Fstackoverflow.com%2Fquestions%2F21947730%2Fchrome-speech-synthesis-with-longer-texts)%0Afunction%20CN_KeepSpeechSynthesisActive()%20%7B%0A%09console.log(%22Keeping%20speech%20synthesis%20active...%22)%3B%0A%09window.speechSynthesis.pause()%3B%0A%09window.speechSynthesis.resume()%3B%0A%09CN_TIMEOUT_KEEP_SYNTHESIS_WORKING%20%3D%20setTimeout(CN_KeepSpeechSynthesisActive%2C%205000)%3B%0A%7D%0A%0A%2F%2F%20Split%20the%20text%20into%20sentences%20so%20the%20speech%20synthesis%20can%20start%20speaking%20as%20soon%20as%20possible%0Afunction%20CN_SplitIntoSentences(text)%20%7B%0A%09var%20sentences%20%3D%20%5B%5D%3B%0A%09var%20currentSentence%20%3D%20%22%22%3B%0A%09%0A%09for(var%20i%3D0%3B%20i%3Ctext.length%3B%20i%2B%2B)%20%7B%0A%09%09%2F%2F%0A%09%09var%20currentChar%20%3D%20text%5Bi%5D%3B%0A%09%09%0A%09%09%2F%2F%20Add%20character%20to%20current%20sentence%0A%09%09currentSentence%20%2B%3D%20currentChar%3B%0A%09%09%0A%09%09%2F%2F%20is%20the%20current%20character%20a%20delimiter%3F%20if%20so%2C%20add%20current%20part%20to%20array%20and%20clear%0A%09%09if%20(currentChar%20%3D%3D%20'%2C'%20%7C%7C%20currentChar%20%3D%3D%20'%3A'%20%7C%7C%20currentChar%20%3D%3D%20'.'%20%7C%7C%20currentChar%20%3D%3D%20'!'%20%7C%7C%20currentChar%20%3D%3D%20'%3F'%20%7C%7C%20currentChar%20%3D%3D%20'%3B')%20%7B%0A%09%09%09if%20(currentSentence.trim()%20!%3D%20%22%22)%20sentences.push(currentSentence.trim())%3B%0A%09%09%09currentSentence%20%3D%20%22%22%3B%0A%09%09%7D%0A%09%7D%0A%09%0A%09return%20sentences%3B%0A%7D%0A%0A%2F%2F%20Check%20for%20new%20messages%20the%20bot%20has%20sent.%20If%20a%20new%20message%20is%20found%2C%20it%20will%20be%20read%20out%20loud%0Afunction%20CN_CheckNewMessages()%20%7B%0A%09%2F%2F%20Any%20new%20messages%3F%0A%09var%20currentMessageCount%20%3D%20jQuery(%22.text-base%22).length%3B%0A%09if%20(currentMessageCount%20%3E%20CN_MESSAGE_COUNT)%20%7B%0A%09%09%2F%2F%20New%20message!%0A%09%09CN_MESSAGE_COUNT%20%3D%20currentMessageCount%3B%0A%09%09CN_CURRENT_MESSAGE%20%3D%20jQuery(%22.text-base%3Alast%22)%3B%0A%09%09CN_CURRENT_MESSAGE_SENTENCES%20%3D%20%5B%5D%3B%20%2F%2F%20Reset%20list%20of%20parts%20already%20spoken%0A%09%7D%0A%09%0A%09%2F%2F%20Split%20current%20message%20into%20parts%0A%09if%20(CN_CURRENT_MESSAGE%20%26%26%20CN_CURRENT_MESSAGE.length)%20%7B%0A%09%09var%20currentText%20%3D%20CN_CURRENT_MESSAGE.text()%2B%22%22%3B%0A%09%09var%20newSentences%20%3D%20CN_SplitIntoSentences(currentText)%3B%0A%09%09if%20(newSentences%20!%3D%20null%20%26%26%20newSentences.length%20!%3D%20CN_CURRENT_MESSAGE_SENTENCES.length)%20%7B%0A%09%09%09%2F%2F%20There%20is%20a%20new%20part%20of%20a%20sentence!%0A%09%09%09CN_CURRENT_MESSAGE_SENTENCES%20%3D%20newSentences%3B%0A%09%09%09var%20lastPart%20%3D%20newSentences%5BnewSentences.length-1%5D%3B%0A%09%09%09CN_SayOutLoud(lastPart)%3B%0A%09%09%7D%0A%09%7D%0A%09%0A%09setTimeout(CN_CheckNewMessages%2C%20100)%3B%0A%7D%0A%0A%2F%2F%20Send%20a%20message%20to%20the%20bot%20(will%20simply%20put%20text%20in%20the%20textarea%20and%20simulate%20a%20send%20button%20click)%0Afunction%20CN_SendMessage(text)%20%7B%0A%09%2F%2F%20Send%20the%20message%0A%09jQuery(%22textarea%22).val(text)%3B%0A%09jQuery(%22textarea%22).closest(%22div%22).find(%22button%22).click()%3B%0A%09%0A%09%2F%2F%20Stop%20speech%20recognition%20until%20the%20answer%20is%20received%0A%09if%20(CN_SPEECHREC)%20%7B%0A%09%09clearTimeout(CN_TIMEOUT_KEEP_SPEECHREC_WORKING)%3B%0A%09%09CN_SPEECHREC.stop()%3B%0A%09%7D%0A%7D%0A%0A%2F%2F%20Start%20speech%20recognition%20using%20the%20browser's%20speech%20recognition%20API%0Afunction%20CN_StartSpeechRecognition()%20%7B%0A%09if%20(CN_IS_READING)%20%7B%0A%09%09clearTimeout(CN_TIMEOUT_KEEP_SPEECHREC_WORKING)%3B%0A%09%09CN_TIMEOUT_KEEP_SPEECHREC_WORKING%20%3D%20setTimeout(CN_KeepSpeechRecWorking%2C%20100)%3B%0A%09%09return%3B%0A%09%7D%0A%09if%20(!CN_SPEECH_REC_SUPPORTED)%20return%3B%0A%09CN_SPEECHREC%20%3D%20('webkitSpeechRecognition'%20in%20window)%20%3F%20new%20webkitSpeechRecognition()%20%3A%20new%20SpeechRecognition()%3B%0A%09CN_SPEECHREC.continuous%20%3D%20true%3B%0A%09CN_SPEECHREC.lang%20%3D%20CN_WANTED_LANGUAGE_SPEECH_REC%3B%0A%09CN_SPEECHREC.onstart%20%3D%20()%20%3D%3E%20%7B%0A%09%09%2F%2F%20Make%20border%20red%0A%09%09%24(%22%23TTGPTSettings%22).css(%22border%22%2C%20%222px%20solid%20red%22)%3B%0A%09%09%0A%09%09CN_IS_LISTENING%20%3D%20true%3B%0A%09%09console.log(%22I'm%20listening%22)%3B%0A%09%7D%3B%0A%09CN_SPEECHREC.onend%20%3D%20()%20%3D%3E%20%7B%0A%09%09%2F%2F%20Make%20border%20grey%20again%0A%09%09%24(%22%23TTGPTSettings%22).css(%22border%22%2C%20%222px%20solid%20%23888%22)%3B%0A%09%09%0A%09%09CN_IS_LISTENING%20%3D%20false%3B%0A%09%09console.log(%22I've%20stopped%20listening%22)%3B%0A%09%7D%3B%0A%09CN_SPEECHREC.onerror%20%3D%20()%20%3D%3E%20%7B%0A%09%09CN_IS_LISTENING%20%3D%20false%3B%0A%09%09console.log(%22Error%20while%20listening%22)%3B%0A%09%7D%3B%0A%09CN_SPEECHREC.onresult%20%3D%20(event)%20%3D%3E%20%7B%0A%09%09var%20final_transcript%20%3D%20%22%22%3B%0A%09%09for%20(let%20i%20%3D%20event.resultIndex%3B%20i%20%3C%20event.results.length%3B%20%2B%2Bi)%20%7B%0A%09%09%09if%20(event.results%5Bi%5D.isFinal)%0A%09%09%09%09final_transcript%20%2B%3D%20event.results%5Bi%5D%5B0%5D.transcript%3B%0A%09%09%7D%0A%09%09console.log(%22You%20have%20said%20the%20following%20words%3A%20%22%2Bfinal_transcript)%3B%0A%09%09if%20(final_transcript.toLowerCase()%20%3D%3D%20CN_SAY_THIS_WORD_TO_STOP)%20%7B%0A%09%09%09console.log(%22You%20said%20'%22%2B%20CN_SAY_THIS_WORD_TO_STOP%2B%22'.%20Conversation%20ended%22)%3B%0A%09%09%09CN_FINISHED%20%3D%20true%3B%0A%09%09%09CN_PAUSED%20%3D%20false%3B%0A%09%09%09CN_SPEECHREC.stop()%3B%0A%09%09%09CN_SayOutLoud(%22Bye%20bye%22)%3B%0A%09%09%09alert(%22Conversation%20ended.%20Reload%20the%20script%20to%20restart%20conversation%22)%3B%0A%09%09%09return%3B%0A%09%09%7D%20else%20if%20(final_transcript.toLowerCase()%20%3D%3D%20CN_SAY_THIS_WORD_TO_PAUSE)%20%7B%0A%09%09%09console.log(%22You%20said%20'%22%2B%20CN_SAY_THIS_WORD_TO_PAUSE%2B%22'%20Conversation%20paused%22)%3B%0A%09%09%09CN_PAUSED%20%3D%20true%3B%0A%09%09%09if%20(CN_SPEECHREC)%20CN_SPEECHREC.stop()%3B%0A%09%09%09alert(%22Conversation%20paused%2C%20the%20browser%20is%20no%20longer%20listening.%20Click%20OK%20to%20resume%22)%3B%0A%09%09%09CN_PAUSED%20%3D%20false%3B%0A%09%09%09console.log(%22Conversation%20resumed%22)%3B%0A%09%09%09return%3B%0A%09%09%7D%0A%09%09%0A%09%09CN_SendMessage(final_transcript)%3B%0A%09%7D%3B%0A%09if%20(!CN_IS_LISTENING%20%26%26%20CN_SPEECH_REC_SUPPORTED%20%26%26%20!CN_SPEECHREC_DISABLED)%20CN_SPEECHREC.start()%3B%0A%09clearTimeout(CN_TIMEOUT_KEEP_SPEECHREC_WORKING)%3B%0A%09CN_TIMEOUT_KEEP_SPEECHREC_WORKING%20%3D%20setTimeout(CN_KeepSpeechRecWorking%2C%20100)%3B%0A%7D%0A%0A%2F%2F%20Make%20sure%20the%20speech%20recognition%20is%20turned%20on%20when%20the%20bot%20is%20not%20speaking%0Afunction%20CN_KeepSpeechRecWorking()%20%7B%0A%09if%20(CN_FINISHED)%20return%3B%20%2F%2F%20Conversation%20finished%0A%09clearTimeout(CN_TIMEOUT_KEEP_SPEECHREC_WORKING)%3B%0A%09CN_TIMEOUT_KEEP_SPEECHREC_WORKING%20%3D%20setTimeout(CN_KeepSpeechRecWorking%2C%20100)%3B%0A%09if%20(!CN_IS_READING%20%26%26%20!CN_IS_LISTENING%20%26%26%20!CN_PAUSED)%20%7B%0A%09%09if%20(!CN_SPEECHREC)%0A%09%09%09CN_StartSpeechRecognition()%3B%0A%09%09else%20%7B%0A%09%09%09if%20(!CN_IS_LISTENING)%20%7B%0A%09%09%09%09try%20%7B%0A%09%09%09%09%09if%20(CN_SPEECH_REC_SUPPORTED%20%26%26%20!window.speechSynthesis.speaking%20%26%26%20!CN_SPEECHREC_DISABLED)%0A%09%09%09%09%09%09CN_SPEECHREC.start()%3B%0A%09%09%09%09%7D%20catch(e)%20%7B%20%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%7D%0A%0A%2F%2F%20Toggle%20button%20clicks%3A%20settings%2C%20pause%2C%20skip...%0Afunction%20CN_ToggleButtonClick()%20%7B%0A%09var%20action%20%3D%20%24(this).data(%22cn%22)%3B%0A%09switch(action)%20%7B%0A%09%0A%09%09%2F%2F%20Open%20settings%20menu%0A%09%09case%20%22settings%22%3A%0A%09%09%09CN_OnSettingsIconClick()%3B%0A%09%09%09return%3B%0A%09%09%0A%09%09%2F%2F%20The%20microphone%20is%20on.%20Turn%20it%20off%0A%09%09case%20%22micon%22%3A%0A%09%09%09%2F%2F%20Show%20other%20icon%20and%20hide%20this%20one%0A%09%09%09%24(this).css(%22display%22%2C%20%22none%22)%3B%0A%09%09%09%24(%22.CNToggle%5Bdata-cn%3Dmicoff%5D%22).css(%22display%22%2C%20%22%22)%3B%0A%09%09%09%0A%09%09%09%2F%2F%20Disable%20speech%20rec%0A%09%09%09CN_SPEECHREC_DISABLED%20%3D%20true%3B%0A%09%09%09if%20(CN_SPEECHREC%20%26%26%20CN_IS_LISTENING)%20CN_SPEECHREC.stop()%3B%0A%09%09%09%0A%09%09%09return%3B%0A%09%09%0A%09%09%2F%2F%20The%20microphone%20is%20off.%20Turn%20it%20on%0A%09%09case%20%22micoff%22%3A%0A%09%09%09%2F%2F%20Show%20other%20icon%20and%20hide%20this%20one%0A%09%09%09%24(this).css(%22display%22%2C%20%22none%22)%3B%0A%09%09%09%24(%22.CNToggle%5Bdata-cn%3Dmicon%5D%22).css(%22display%22%2C%20%22%22)%3B%0A%09%09%09%0A%09%09%09%2F%2F%20Enable%20speech%20rec%0A%09%09%09CN_SPEECHREC_DISABLED%20%3D%20false%3B%0A%09%09%09if%20(CN_SPEECHREC%20%26%26%20!CN_IS_LISTENING%20%26%26%20!CN_IS_READING)%20CN_SPEECHREC.start()%3B%0A%09%09%09%0A%09%09%09return%3B%0A%09%09%0A%09%09%2F%2F%20The%20bot's%20voice%20is%20on.%20Turn%20it%20off%0A%09%09case%20%22speakon%22%3A%0A%09%09%09%2F%2F%20Show%20other%20icon%20and%20hide%20this%20one%0A%09%09%09%24(this).css(%22display%22%2C%20%22none%22)%3B%0A%09%09%09%24(%22.CNToggle%5Bdata-cn%3Dspeakoff%5D%22).css(%22display%22%2C%20%22%22)%3B%0A%09%09%09CN_SPEAKING_DISABLED%20%3D%20true%3B%0A%09%09%09%0A%09%09%09%2F%2F%20Stop%20current%20message%20(equivalent%20to%20'skip')%0A%09%09%09window.speechSynthesis.cancel()%3B%20%2F%2F%20Cancel%20everything%0A%09%09%09CN_CURRENT_MESSAGE%20%3D%20null%3B%20%2F%2F%20Remove%20current%20message%0A%09%09%09return%3B%0A%09%09%0A%09%09%2F%2F%20The%20bot's%20voice%20is%20off.%20Turn%20it%20on%0A%09%09case%20%22speakoff%22%3A%0A%09%09%09%2F%2F%20Show%20other%20icon%20and%20hide%20this%20one%0A%09%09%09%24(this).css(%22display%22%2C%20%22none%22)%3B%0A%09%09%09%24(%22.CNToggle%5Bdata-cn%3Dspeakon%5D%22).css(%22display%22%2C%20%22%22)%3B%0A%09%09%09CN_SPEAKING_DISABLED%20%3D%20false%3B%0A%09%09%09%0A%09%09%09return%3B%0A%09%09%0A%09%09%2F%2F%20Skip%20current%20message%20being%20read%0A%09%09case%20%22skip%22%3A%0A%09%09%09window.speechSynthesis.cancel()%3B%20%2F%2F%20Cancel%20everything%0A%09%09%09CN_CURRENT_MESSAGE%20%3D%20null%3B%20%2F%2F%20Remove%20current%20message%0A%09%09%09return%3B%0A%09%7D%0A%7D%0A%0A%2F%2F%20Perform%20initialization%20after%20jQuery%20is%20loaded%0Afunction%20CN_InitScript()%20%7B%0A%09if%20(typeof%20%24%20%3D%3D%3D%20null%20%7C%7C%20typeof%20%24%20%3D%3D%3D%20undefined)%20%24%20%3D%20jQuery%3B%0A%09%0A%09var%20warning%20%3D%20%22%22%3B%0A%09if%20('webkitSpeechRecognition'%20in%20window)%20%7B%0A%09%09console.log(%22Speech%20recognition%20API%20supported%22)%3B%0A%09%09CN_SPEECH_REC_SUPPORTED%20%3D%20true%3B%0A%09%7D%20else%20%7B%0A%09%09console.log(%22speech%20recognition%20API%20not%20supported.%22)%3B%0A%09%09CN_SPEECH_REC_SUPPORTED%20%3D%20false%3B%0A%09%09warning%20%3D%20%22%5Cn%5CnWARNING%3A%20speech%20recognition%20(speech-to-text)%20is%20only%20available%20in%20Google%20Chrome%20desktop%20version%20at%20the%20moment.%20If%20you%20are%20using%20another%20browser%2C%20you%20will%20not%20be%20able%20to%20dictate%20text%2C%20but%20you%20can%20still%20listen%20to%20the%20bot's%20responses.%22%3B%0A%09%7D%0A%09%0A%09%2F%2F%20Restore%20settings%0A%09CN_RestoreSettings()%3B%0A%09%0A%09%2F%2F%20Alert%20message%20on%20start%0A%09%2F%2Falert(%22After%20you%20press%20OK%2C%20I%20will%20start%20listening%20to%20your%20audio.%20To%20stop%20the%20script%2C%20just%20say%20the%20word%20'%22%20%2B%20CN_SAY_THIS_WORD_TO_STOP%20%2B%20%22'.%20To%20pause%2C%20say%20'pause'.%22%2B%20warning)%3B%0A%09%0A%09%2F%2F%20Wait%20on%20voices%20to%20be%20loaded%20before%20fetching%20list%0A%09window.speechSynthesis.onvoiceschanged%20%3D%20function%20()%20%7B%0A%09%09if%20(!CN_WANTED_VOICE_NAME)%7B%0A%09%09%09console.log(%22Reading%20with%20default%20browser%20voice%22)%3B%0A%09%09%7D%20else%20%7B%0A%09%09%09speechSynthesis.getVoices().forEach(function%20(voice)%20%7B%0A%09%09%09%09%2F%2Fconsole.log(%22Found%20possible%20voice%3A%20%22%20%2B%20voice.name%20%2B%20%22%20(%22%20%2B%20voice.lang%20%2B%20%22)%22)%3B%0A%09%09%09%09if%20(voice.lang%20%2B%20%22-%22%20%2B%20voice.name%20%3D%3D%20CN_WANTED_VOICE_NAME)%20%7B%0A%09%09%09%09%09CN_WANTED_VOICE%20%3D%20voice%3B%0A%09%09%09%09%09console.log(%22I%20will%20read%20using%20voice%20%22%20%2B%20voice.name%20%2B%20%22%20(%22%20%2B%20voice.lang%20%2B%20%22)%22)%3B%0A%09%09%09%09%09return%20false%3B%0A%09%09%09%09%7D%0A%09%09%09%7D)%3B%0A%09%09%09if%20(!CN_WANTED_VOICE)%0A%09%09%09%09console.log(%22No%20voice%20found%20for%20'%22%20%2B%20CN_WANTED_VOICE_NAME%20%2B%20%22'%2C%20reading%20with%20default%20browser%20voice%22)%3B%0A%09%09%7D%0A%09%7D%3B%0A%09%0A%09%2F%2F%20Add%20icons%20on%20the%20top%20right%20corner%0A%09jQuery(%22body%22).append(%22%3Cspan%20style%3D'position%3A%20fixed%3B%20top%3A%208px%3B%20right%3A%2012px%3B%20display%3A%20inline-block%3B%20background%3A%20%23EEE%3B%20%22%20%2B%0A%09%09%22border%3A%202px%20solid%20%23888%3B%20color%3A%20%23888%3B%20padding%3A%205px%3B%20font-size%3A%2014px%3B%20border-radius%3A%204px%3B%20text-align%3A%20center%3B%22%20%2B%0A%09%09%22font-weight%3A%20bold%3B%20z-index%3A%201111%3B'%20id%3D'TTGPTSettings'%3E%3Ca%20href%3D'https%3A%2F%2Fgithub.com%2FC-Nedelcu%2Ftalk-to-chatgpt'%20target%3D_blank%20title%3D'Visit%20project%20website'%3ETalk-to-GPT%20V1.4%3C%2Fa%3E%3Cbr%20%2F%3E%22%20%2B%0A%09%09%22%3Cspan%20style%3D'font-size%3A%2020px%3B'%3E%22%20%2B%0A%09%09%22%3Cspan%20class%3D'CNToggle'%20title%3D'Voice%20recognition%20enabled.%20Click%20to%20disable'%20data-cn%3D'micon'%3E%F0%9F%8E%99%EF%B8%8F%20%3C%2Fspan%3E%20%20%22%20%2B%20%2F%2F%20Microphone%20enabled%0A%09%09%22%3Cspan%20class%3D'CNToggle'%20title%3D'Voice%20recognition%20disabled.%20Click%20to%20enable'%20style%3D'display%3Anone%3B'%20data-cn%3D'micoff'%3E%F0%9F%A4%AB%20%3C%2Fspan%3E%20%20%22%20%2B%20%2F%2F%20Microphone%20disabled%0A%09%09%22%3Cspan%20class%3D'CNToggle'%20title%3D'Text-to-speech%20(bot%20voice)%20enabled.%20Click%20to%20disable.%20This%20will%20skip%20the%20current%20message%20entirely.'%20data-cn%3D'speakon'%3E%F0%9F%94%8A%20%3C%2Fspan%3E%20%20%22%20%2B%20%2F%2F%20Speak%20out%20loud%0A%09%09%22%3Cspan%20class%3D'CNToggle'%20title%3D'Text-to-speech%20(bot%20voice)%20disabled.%20Click%20to%20enable'%20style%3D'display%3Anone%3B'%20data-cn%3D'speakoff'%3E%F0%9F%94%87%20%3C%2Fspan%3E%20%20%22%20%2B%20%2F%2F%20Mute%0A%09%09%22%3Cspan%20class%3D'CNToggle'%20title%3D'Skip%20the%20message%20currently%20being%20read%20by%20the%20bot.'%20data-cn%3D'skip'%3E%E2%8F%A9%20%3C%2Fspan%3E%20%20%22%20%2B%20%2F%2F%20Skip%0A%09%09%22%3Cspan%20class%3D'CNToggle'%20title%3D'Open%20settings%20menu%20to%20change%20bot%20voice%2C%20language%2C%20and%20other%20settings'%20data-cn%3D'settings'%3E%E2%9A%99%EF%B8%8F%3C%2Fspan%3E%20%22%20%2B%20%2F%2F%20Settings%0A%09%09%22%3C%2Fspan%3E%3C%2Fspan%3E%22)%3B%0A%09%0A%09%2F%2F%20Try%20and%20get%20voices%0A%09speechSynthesis.getVoices()%3B%0A%09%0A%09setTimeout(function%20()%20%7B%0A%09%09%2F%2F%20Make%20icons%20clickable%0A%09%09jQuery(%22.CNToggle%22).css(%22cursor%22%2C%20%22pointer%22)%3B%0A%09%09jQuery(%22.CNToggle%22).on(%22click%22%2C%20CN_ToggleButtonClick)%3B%0A%09%09%0A%09%09%2F%2F%20Check%20for%20new%20messages%0A%09%09CN_CheckNewMessages()%3B%0A%09%09%0A%09%09%2F%2F%20Start%20speech%20rec%0A%09%09CN_StartSpeechRecognition()%3B%09%09%0A%09%09%0A%09%09%2F%2F%20Say%20OK%20to%20confirm%20it%20has%20started%0A%09%09setTimeout(function()%20%7B%0A%09%09%09CN_SayOutLoud(%22OK%22)%3B%0A%09%09%7D%2C%20500)%3B%0A%09%7D%2C%20100)%3B%0A%7D%0A%0A%2F%2F%20Open%20settings%20menu%0Afunction%20CN_OnSettingsIconClick()%20%7B%0A%09console.log(%22Opening%20settings%20menu%22)%3B%0A%09%0A%09%2F%2F%20Stop%20listening%0A%09CN_PAUSED%20%3D%20true%3B%0A%09if%20(CN_SPEECHREC)%20CN_SPEECHREC.stop()%3B%0A%09%0A%09%2F%2F%20Prepare%20settings%20row%0A%09var%20rows%20%3D%20%22%22%3B%0A%09%20%20%0A%09%2F%2F%201.%20Bot's%20voice%0A%09var%20voices%20%3D%20%22%22%3B%0A%09var%20n%20%3D%200%3B%0A%09speechSynthesis.getVoices().forEach(function%20(voice)%20%7B%0A%09%09var%20label%20%3D%20%60%24%7Bvoice.name%7D%20(%24%7Bvoice.lang%7D)%60%3B%0A%09%09if%20(voice.default)%20label%20%2B%3D%20'%20%E2%80%94%20DEFAULT'%3B%0A%09%09var%20SEL%20%3D%20(CN_WANTED_VOICE%20%26%26%20CN_WANTED_VOICE.lang%20%3D%3D%20voice.lang%20%26%26%20CN_WANTED_VOICE.name%20%3D%3D%20voice.name)%20%3F%20%22selected%3Dselected%22%3A%20%22%22%3B%0A%09%09voices%20%2B%3D%20%22%3Coption%20value%3D'%22%2Bn%2B%22'%20%22%2BSEL%2B%22%3E%22%2Blabel%2B%22%3C%2Foption%3E%22%3B%0A%09%09n%2B%2B%3B%0A%09%7D)%3B%0A%09rows%20%2B%3D%20%22%3Ctr%3E%3Ctd%3EAI%20voice%20and%20language%3A%3C%2Ftd%3E%3Ctd%3E%3Cselect%20id%3D'TTGPTVoice'%20style%3D'width%3A%20300px%3B%20color%3A%20black'%3E%22%2Bvoices%2B%22%3C%2Fselect%3E%3C%2Ftd%3E%3C%2Ftr%3E%22%3B%0A%09%0A%09%2F%2F%202.%20AI%20talking%20speed%0A%09rows%20%2B%3D%20%22%3Ctr%3E%3Ctd%3EAI%20talking%20speed%20(speech%20rate)%3A%3C%2Ftd%3E%3Ctd%3E%3Cinput%20type%3Dnumber%20step%3D'.1'%20id%3D'TTGPTRate'%20style%3D'color%3A%20black%3B%20width%3A%20100px%3B'%20value%3D'%22%2BCN_TEXT_TO_SPEECH_RATE%2B%22'%20%2F%3E%3C%2Ftd%3E%3C%2Ftr%3E%22%3B%0A%09%0A%09%2F%2F%203.%20AI%20voice%20pitch%0A%09rows%20%2B%3D%20%22%3Ctr%3E%3Ctd%3EAI%20voice%20pitch%3A%3C%2Ftd%3E%3Ctd%3E%3Cinput%20type%3Dnumber%20step%3D'.1'%20id%3D'TTGPTPitch'%20style%3D'width%3A%20100px%3B%20color%3A%20black%3B'%20value%3D'%22%2BCN_TEXT_TO_SPEECH_PITCH%2B%22'%20%2F%3E%3C%2Ftd%3E%3C%2Ftr%3E%22%3B%0A%09%0A%09%2F%2F%204.%20Speech%20recognition%20language%20CN_WANTED_LANGUAGE_SPEECH_REC%0A%09var%20languages%20%3D%20%22%3Coption%20value%3D''%3E%3C%2Foption%3E%22%3B%0A%09for(var%20i%20in%20CN_SPEECHREC_LANGS)%20%7B%0A%09%09var%20languageName%20%3D%20CN_SPEECHREC_LANGS%5Bi%5D%5B0%5D%3B%0A%09%09for(var%20j%20in%20CN_SPEECHREC_LANGS%5Bi%5D)%20%7B%0A%09%09%09if%20(j%20%3D%3D%200)%20continue%3B%0A%09%09%09var%20languageCode%20%3D%20CN_SPEECHREC_LANGS%5Bi%5D%5Bj%5D%5B0%5D%3B%0A%09%09%09var%20SEL%20%3D%20languageCode%20%3D%3D%20CN_WANTED_LANGUAGE_SPEECH_REC%20%3F%20%22selected%3D'selected'%22%3A%20%22%22%3B%0A%09%09%09languages%20%2B%3D%20%22%3Coption%20value%3D'%22%2BlanguageCode%2B%22'%20%22%2BSEL%2B%22%3E%22%2BlanguageName%2B%22%20-%20%22%2BlanguageCode%2B%22%3C%2Foption%3E%22%3B%0A%09%09%7D%0A%09%7D%0A%09rows%20%2B%3D%20%22%3Ctr%3E%3Ctd%3ESpeech%20recognition%20language%3A%3C%2Ftd%3E%3Ctd%3E%3Cselect%20id%3D'TTGPTRecLang'%20style%3D'width%3A%20300px%3B%20color%3A%20black%3B'%20%3E%22%2Blanguages%2B%22%3C%2Fselect%3E%3C%2Ftd%3E%3C%2Ftr%3E%22%3B%0A%09%0A%09%2F%2F%205.%20'Stop'%20word%0A%09rows%20%2B%3D%20%22%3Ctr%3E%3Ctd%3E'Stop'%20word%3A%3C%2Ftd%3E%3Ctd%3E%3Cinput%20type%3Dtext%20id%3D'TTGPTStopWord'%20style%3D'width%3A%20100px%3B%20color%3A%20black%3B'%20value%3D'%22%2BCN_SAY_THIS_WORD_TO_STOP%2B%22'%20%2F%3E%3C%2Ftd%3E%3C%2Ftr%3E%22%3B%0A%09%0A%09%2F%2F%206.%20'Pause'%20word%0A%09rows%20%2B%3D%20%22%3Ctr%3E%3Ctd%3E'Pause'%20word%3A%3C%2Ftd%3E%3Ctd%3E%3Cinput%20type%3Dtext%20id%3D'TTGPTPauseWord'%20style%3D'width%3A%20100px%3B%20color%3A%20black%3B'%20value%3D'%22%2BCN_SAY_THIS_WORD_TO_PAUSE%2B%22'%20%2F%3E%3C%2Ftd%3E%3C%2Ftr%3E%22%3B%0A%09%0A%09%0A%09%2F%2F%20Prepare%20save%2Fclose%20buttons%0A%09var%20closeRow%20%3D%20%22%3Ctr%3E%3Ctd%20colspan%3D2%20style%3D'text-align%3A%20center'%3E%3Cbr%20%2F%3E%3Cbutton%20id%3D'TTGPTSave'%20style%3D'font-weight%3A%20bold%3B'%3E%E2%9C%93%20Save%3C%2Fbutton%3E%26nbsp%3B%3Cbutton%20id%3D'TTGPTCancel'%20style%3D'margin-left%3A%2020px%3B'%3E%E2%9C%97%20Cancel%3C%2Fbutton%3E%3C%2Ftd%3E%3C%2Ftr%3E%22%3B%0A%09%0A%09%2F%2F%20Prepare%20settings%20table%0A%09var%20table%20%3D%20%22%3Ctable%20cellpadding%3D6%20cellspacing%3D0%20style%3D'margin%3A%2030px%3B'%3E%22%2Brows%2BcloseRow%2B%22%3C%2Ftable%3E%22%3B%0A%09%0A%09%2F%2F%20Open%20a%20whole%20screenful%20of%20settings%0A%09jQuery(%22body%22).append(%22%3Cdiv%20style%3D'background%3A%20rgba(0%2C0%2C0%2C0.7)%3B%20position%3A%20absolute%3B%20top%3A%200%3B%20right%3A%200%3B%20left%3A%200%3B%20bottom%3A%200%3B%20z-index%3A%20999999%3B%20padding%3A%2020px%3B%20color%3A%20white%3B%20font-size%3A%2014px%3B'%20id%3D'TTGPTSettingsArea'%3E%3Ch1%3E%E2%9A%99%EF%B8%8F%20Talk-to-GPT%20settings%3C%2Fh1%3E%22%2Btable%2B%22%3C%2Fdiv%3E%22)%3B%0A%09%0A%09%2F%2F%20Assign%20events%0A%09setTimeout(function()%20%7B%0A%09%09jQuery(%22%23TTGPTSave%22).on(%22click%22%2C%20CN_SaveSettings)%3B%0A%09%09jQuery(%22%23TTGPTCancel%22).on(%22click%22%2C%20CN_CloseSettingsDialog)%3B%0A%09%7D%2C%20100)%3B%0A%7D%0A%0A%2F%2F%20Save%20settings%20and%20close%20dialog%20box%0Afunction%20CN_SaveSettings()%20%7B%0A%09%0A%09%2F%2F%20Save%20settings%0A%09try%20%7B%0A%09%09%2F%2F%20AI%20voice%20settings%3A%20voice%2Flanguage%2C%20rate%2C%20pitch%0A%09%09var%20wantedVoiceIndex%20%3D%20jQuery(%22%23TTGPTVoice%22).val()%3B%0A%09%09var%20allVoices%20%3D%20speechSynthesis.getVoices()%3B%0A%09%09CN_WANTED_VOICE%20%3D%20allVoices%5BwantedVoiceIndex%5D%3B%0A%09%09CN_WANTED_VOICE_NAME%20%3D%20CN_WANTED_VOICE.lang%2B%22-%22%2BCN_WANTED_VOICE.name%3B%0A%09%09CN_TEXT_TO_SPEECH_RATE%20%3D%20Number(%20jQuery(%22%23TTGPTRate%22).val()%20)%3B%0A%09%09CN_TEXT_TO_SPEECH_PITCH%20%3D%20Number(%20jQuery(%22%23TTGPTPitch%22).val()%20)%3B%0A%09%09%0A%09%09%2F%2F%20Speech%20recognition%20settings%3A%20language%2C%20stop%2C%20pause%0A%09%09CN_WANTED_LANGUAGE_SPEECH_REC%20%3D%20jQuery(%22%23TTGPTRecLang%22).val()%3B%0A%09%09CN_SAY_THIS_WORD_TO_STOP%20%3D%20jQuery(%22%23TTGPTStopWord%22).val()%3B%0A%09%09CN_SAY_THIS_WORD_TO_PAUSE%20%3D%20jQuery(%22%23TTGPTPauseWord%22).val()%3B%0A%09%09%0A%09%09%2F%2F%20Apply%20language%20to%20speech%20recognition%20instance%0A%09%09if%20(CN_SPEECHREC)%20CN_SPEECHREC.lang%20%3D%20CN_WANTED_LANGUAGE_SPEECH_REC%3B%0A%09%09%0A%09%09%2F%2F%20Save%20settings%20in%20cookie%0A%09%09var%20settings%20%3D%20%5B%0A%09%09%09CN_WANTED_VOICE_NAME%2C%0A%09%09%09CN_TEXT_TO_SPEECH_RATE%2C%0A%09%09%09CN_TEXT_TO_SPEECH_PITCH%2C%0A%09%09%09CN_WANTED_LANGUAGE_SPEECH_REC%2C%0A%09%09%09CN_SAY_THIS_WORD_TO_STOP%2C%0A%09%09%09CN_SAY_THIS_WORD_TO_PAUSE%0A%09%09%5D%3B%0A%09%09CN_SetCookie(%22CN_TTGPT%22%2C%20JSON.stringify(settings))%3B%0A%09%7D%20catch(e)%20%7B%20alert('Invalid%20settings%20values')%3B%20return%3B%20%7D%0A%09%0A%09%2F%2F%20Close%20dialog%0A%09console.log(%22Closing%20settings%20dialog%22)%3B%0A%09jQuery(%22%23TTGPTSettingsArea%22).remove()%3B%0A%09%0A%09%2F%2F%20Resume%20listening%0A%09CN_PAUSED%20%3D%20false%3B%0A%7D%0A%0A%2F%2F%20Restore%20settings%20from%20cookie%0Afunction%20CN_RestoreSettings()%20%7B%0A%09var%20settingsRaw%20%3D%20CN_GetCookie(%22CN_TTGPT%22)%3B%0A%09try%20%7B%0A%09%09var%20settings%20%3D%20JSON.parse(settingsRaw)%3B%0A%09%09if%20(typeof%20settings%20%3D%3D%20%22object%22)%20%7B%0A%09%09%09console.log(%22Reloading%20settings%20from%20cookie%3A%20%22%2Bsettings)%3B%0A%09%09%09CN_WANTED_VOICE_NAME%20%3D%20settings%5B0%5D%3B%0A%09%09%09CN_TEXT_TO_SPEECH_RATE%20%3D%20settings%5B1%5D%3B%0A%09%09%09CN_TEXT_TO_SPEECH_PITCH%20%3D%20settings%5B2%5D%3B%0A%09%09%09CN_WANTED_LANGUAGE_SPEECH_REC%20%3D%20settings%5B3%5D%3B%0A%09%09%09CN_SAY_THIS_WORD_TO_STOP%20%3D%20settings%5B4%5D%3B%0A%09%09%09CN_SAY_THIS_WORD_TO_PAUSE%20%3D%20settings%5B5%5D%3B%0A%09%09%7D%0A%09%7D%20catch%20(ex)%20%7B%0A%09%09console.error(ex)%3B%0A%09%7D%0A%7D%0A%0A%2F%2F%20Close%20dialog%3A%20remove%20area%20altogether%0Afunction%20CN_CloseSettingsDialog()%20%7B%0A%09console.log(%22Closing%20settings%20dialog%22)%3B%0A%09jQuery(%22%23TTGPTSettingsArea%22).remove()%3B%0A%09%0A%09%2F%2F%20Resume%20listening%0A%09CN_PAUSED%20%3D%20false%3B%0A%7D%0A%0A%2F%2F%20Sets%20a%20cookie%0Afunction%20CN_SetCookie(name%2C%20value)%20%7B%0A%09var%20days%20%3D%20365%3B%0A%09var%20date%20%3D%20new%20Date()%3B%0A%09date.setTime(date.getTime()%20%2B%20(days%20*%2024%20*%2060%20*%2060%20*%201000))%3B%0A%09var%20expires%20%3D%20%22%3B%20expires%3D%22%20%2B%20date.toGMTString()%3B%0A%09document.cookie%20%3D%20encodeURIComponent(name)%20%2B%20%22%3D%22%20%2B%20encodeURIComponent(value)%20%2B%20expires%20%2B%20%22%3B%20path%3D%2F%22%3B%0A%7D%0A%0A%2F%2F%20Reads%20a%20cookie%0Afunction%20CN_GetCookie(name)%20%7B%0A%09var%20nameEQ%20%3D%20encodeURIComponent(name)%20%2B%20%22%3D%22%3B%0A%09var%20ca%20%3D%20document.cookie.split('%3B')%3B%0A%09for%20(var%20i%20%3D%200%3B%20i%20%3C%20ca.length%3B%20i%2B%2B)%20%7B%0A%09%09var%20c%20%3D%20ca%5Bi%5D%3B%0A%09%09while%20(c.charAt(0)%20%3D%3D%3D%20'%20')%0A%09%09%09c%20%3D%20c.substring(1%2C%20c.length)%3B%0A%09%09if%20(c.indexOf(nameEQ)%20%3D%3D%3D%200)%0A%09%09%09return%20decodeURIComponent(c.substring(nameEQ.length%2C%20c.length))%3B%0A%09%7D%0A%09return%20null%3B%0A%7D%0A%0A%2F%2F%20MAIN%20ENTRY%20POINT%0A%2F%2F%20Load%20jQuery%2C%20then%20run%20initialization%20function%0A(function%20()%20%7B%0A%0A%09function%20LoadScript(url%2C%20success)%20%7B%0A%09%09var%20script%20%3D%20document.createElement(%22script%22)%3B%0A%09%09script.src%20%3D%20url%3B%0A%09%09var%20head%20%3D%20document.getElementsByTagName(%22head%22)%5B0%5D%2C%0A%09%09%09done%20%3D%20!1%3B%0A%09%09script.onload%20%3D%20script.onreadystatechange%20%3D%20function%20()%20%7B%0A%09%09%09!done%20%26%26%20(!this.readyState%20%7C%7C%20this.readyState%20%3D%3D%20%22loaded%22%20%7C%7C%20this.readyState%20%3D%3D%20%22complete%22)%20%26%26%20(done%20%3D%20!0%2C%20success()%2C%20script.onload%20%3D%20script.onreadystatechange%20%3D%20null%2C%20head.removeChild(script))%0A%09%09%09console.log(%22jQuery%20loaded%22)%3B%0A%09%09%7D%2C%20head.appendChild(script)%0A%09%7D%0A%09%0A%09%2F%2F%20Load%20the%20script%0A%09LoadScript(%22%2F%2Fcode.jquery.com%2Fjquery.min.js%22%2C%20function%20()%20%7B%0A%09%09return%20typeof%20jQuery%20%3D%3D%20%22undefined%22%20%3F%0A%09%09%09alert(%22Sorry%2C%20but%20jQuery%20was%20not%20able%20to%20load.%20The%20script%20cannot%20run.%20Try%20using%20Google%20Chrome%20on%20Windows%2011%22)%20%3A%0A%09%09%09CN_InitScript()%3B%0A%09%7D)%0A%09%0A%7D)()%3B%0A%0A%2F%2F%20List%20of%20languages%20for%20speech%20recognition%20-%20Pulled%20from%20https%3A%2F%2Fwww.google.com%2Fintl%2Fen%2Fchrome%2Fdemos%2Fspeech.html%0Avar%20CN_SPEECHREC_LANGS%20%3D%0A%5B%5B'Afrikaans'%2C%20%20%20%20%20%20%20%5B'af-ZA'%5D%5D%2C%0A%20%5B'%E1%8A%A0%E1%88%9B%E1%88%AD%E1%8A%9B'%2C%20%20%20%20%20%20%20%20%20%20%20%09%20%5B'am-ET'%5D%5D%2C%0A%20%5B'Az%C9%99rbaycanca'%2C%20%20%20%20%5B'az-AZ'%5D%5D%2C%0A%20%5B'%E0%A6%AC%E0%A6%BE%E0%A6%82%E0%A6%B2%E0%A6%BE'%2C%20%20%20%20%20%20%20%20%20%20%20%20%09%20%5B'bn-BD'%2C%20'%E0%A6%AC%E0%A6%BE%E0%A6%82%E0%A6%B2%E0%A6%BE%E0%A6%A6%E0%A7%87%E0%A6%B6'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'bn-IN'%2C%20'%E0%A6%AD%E0%A6%BE%E0%A6%B0%E0%A6%A4'%5D%5D%2C%0A%20%5B'Bahasa%20Indonesia'%2C%5B'id-ID'%5D%5D%2C%0A%20%5B'Bahasa%20Melayu'%2C%20%20%20%5B'ms-MY'%5D%5D%2C%0A%20%5B'Catal%C3%A0'%2C%20%20%20%20%20%20%20%20%20%20%5B'ca-ES'%5D%5D%2C%0A%20%5B'%C4%8Ce%C5%A1tina'%2C%20%20%20%20%20%20%20%20%20%5B'cs-CZ'%5D%5D%2C%0A%20%5B'Dansk'%2C%20%20%20%20%20%20%20%20%20%20%20%5B'da-DK'%5D%5D%2C%0A%20%5B'Deutsch'%2C%20%20%20%20%20%20%20%20%20%5B'de-DE'%5D%5D%2C%0A%20%5B'English'%2C%20%20%20%20%20%20%20%20%20%5B'en-AU'%2C%20'Australia'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-CA'%2C%20'Canada'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-IN'%2C%20'India'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-KE'%2C%20'Kenya'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-TZ'%2C%20'Tanzania'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-GH'%2C%20'Ghana'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-NZ'%2C%20'New%20Zealand'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-NG'%2C%20'Nigeria'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-ZA'%2C%20'South%20Africa'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-PH'%2C%20'Philippines'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-GB'%2C%20'United%20Kingdom'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'en-US'%2C%20'United%20States'%5D%5D%2C%0A%20%5B'Espa%C3%B1ol'%2C%20%20%20%20%20%20%20%20%20%5B'es-AR'%2C%20'Argentina'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-BO'%2C%20'Bolivia'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-CL'%2C%20'Chile'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-CO'%2C%20'Colombia'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-CR'%2C%20'Costa%20Rica'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-EC'%2C%20'Ecuador'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-SV'%2C%20'El%20Salvador'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-ES'%2C%20'Espa%C3%B1a'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-US'%2C%20'Estados%20Unidos'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-GT'%2C%20'Guatemala'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-HN'%2C%20'Honduras'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-MX'%2C%20'M%C3%A9xico'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-NI'%2C%20'Nicaragua'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-PA'%2C%20'Panam%C3%A1'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-PY'%2C%20'Paraguay'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-PE'%2C%20'Per%C3%BA'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-PR'%2C%20'Puerto%20Rico'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-DO'%2C%20'Rep%C3%BAblica%20Dominicana'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-UY'%2C%20'Uruguay'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'es-VE'%2C%20'Venezuela'%5D%5D%2C%0A%20%5B'Euskara'%2C%20%20%20%20%20%20%20%20%20%5B'eu-ES'%5D%5D%2C%0A%20%5B'Filipino'%2C%20%20%20%20%20%20%20%20%5B'fil-PH'%5D%5D%2C%0A%20%5B'Fran%C3%A7ais'%2C%20%20%20%20%20%20%20%20%5B'fr-FR'%5D%5D%2C%0A%20%5B'Basa%20Jawa'%2C%20%20%20%20%20%20%20%5B'jv-ID'%5D%5D%2C%0A%20%5B'Galego'%2C%20%20%20%20%20%20%20%20%20%20%5B'gl-ES'%5D%5D%2C%0A%20%5B'%E0%AA%97%E0%AB%81%E0%AA%9C%E0%AA%B0%E0%AA%BE%E0%AA%A4%E0%AB%80'%2C%20%20%20%20%20%20%20%20%20%20%20%09%20%5B'gu-IN'%5D%5D%2C%0A%20%5B'Hrvatski'%2C%20%20%20%20%20%20%20%20%5B'hr-HR'%5D%5D%2C%0A%20%5B'IsiZulu'%2C%20%20%20%20%20%20%20%20%20%5B'zu-ZA'%5D%5D%2C%0A%20%5B'%C3%8Dslenska'%2C%20%20%20%20%20%20%20%20%5B'is-IS'%5D%5D%2C%0A%20%5B'Italiano'%2C%20%20%20%20%20%20%20%20%5B'it-IT'%2C%20'Italia'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'it-CH'%2C%20'Svizzera'%5D%5D%2C%0A%20%5B'%E0%B2%95%E0%B2%A8%E0%B3%8D%E0%B2%A8%E0%B2%A1'%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'kn-IN'%5D%5D%2C%0A%20%5B'%E1%9E%97%E1%9E%B6%E1%9E%9F%E1%9E%B6%E1%9E%81%E1%9F%92%E1%9E%98%E1%9F%82%E1%9E%9A'%2C%20%20%20%20%20%20%20%20%20%20%20%20%5B'km-KH'%5D%5D%2C%0A%20%5B'Latvie%C5%A1u'%2C%20%20%20%20%20%20%20%20%5B'lv-LV'%5D%5D%2C%0A%20%5B'Lietuvi%C5%B3'%2C%20%20%20%20%20%20%20%20%5B'lt-LT'%5D%5D%2C%0A%20%5B'%E0%B4%AE%E0%B4%B2%E0%B4%AF%E0%B4%BE%E0%B4%B3%E0%B4%82'%2C%20%20%20%20%20%20%20%20%20%20%20%5B'ml-IN'%5D%5D%2C%0A%20%5B'%E0%A4%AE%E0%A4%B0%E0%A4%BE%E0%A4%A0%E0%A5%80'%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'mr-IN'%5D%5D%2C%0A%20%5B'Magyar'%2C%20%20%20%20%20%20%20%20%20%20%5B'hu-HU'%5D%5D%2C%0A%20%5B'%E0%BA%A5%E0%BA%B2%E0%BA%A7'%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'lo-LA'%5D%5D%2C%0A%20%5B'Nederlands'%2C%20%20%20%20%20%20%5B'nl-NL'%5D%5D%2C%0A%20%5B'%E0%A4%A8%E0%A5%87%E0%A4%AA%E0%A4%BE%E0%A4%B2%E0%A5%80%20%E0%A4%AD%E0%A4%BE%E0%A4%B7%E0%A4%BE'%2C%20%20%20%20%20%20%20%20%09%20%5B'ne-NP'%5D%5D%2C%0A%20%5B'Norsk%20bokm%C3%A5l'%2C%20%20%20%20%5B'nb-NO'%5D%5D%2C%0A%20%5B'Polski'%2C%20%20%20%20%20%20%20%20%20%20%5B'pl-PL'%5D%5D%2C%0A%20%5B'Portugu%C3%AAs'%2C%20%20%20%20%20%20%20%5B'pt-BR'%2C%20'Brasil'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'pt-PT'%2C%20'Portugal'%5D%5D%2C%0A%20%5B'Rom%C3%A2n%C4%83'%2C%20%20%20%20%20%20%20%20%20%20%5B'ro-RO'%5D%5D%2C%0A%20%5B'%E0%B7%83%E0%B7%92%E0%B6%82%E0%B7%84%E0%B6%BD'%2C%20%20%20%20%20%20%20%20%20%20%09%20%5B'si-LK'%5D%5D%2C%0A%20%5B'Sloven%C5%A1%C4%8Dina'%2C%20%20%20%20%20%5B'sl-SI'%5D%5D%2C%0A%20%5B'Basa%20Sunda'%2C%20%20%20%20%20%20%5B'su-ID'%5D%5D%2C%0A%20%5B'Sloven%C4%8Dina'%2C%20%20%20%20%20%20%5B'sk-SK'%5D%5D%2C%0A%20%5B'Suomi'%2C%20%20%20%20%20%20%20%20%20%20%20%5B'fi-FI'%5D%5D%2C%0A%20%5B'Svenska'%2C%20%20%20%20%20%20%20%20%20%5B'sv-SE'%5D%5D%2C%0A%20%5B'Kiswahili'%2C%20%20%20%20%20%20%20%5B'sw-TZ'%2C%20'Tanzania'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'sw-KE'%2C%20'Kenya'%5D%5D%2C%0A%20%5B'%E1%83%A5%E1%83%90%E1%83%A0%E1%83%97%E1%83%A3%E1%83%9A%E1%83%98'%2C%20%20%20%20%20%20%20%20%20%5B'ka-GE'%5D%5D%2C%0A%20%5B'%D5%80%D5%A1%D5%B5%D5%A5%D6%80%D5%A5%D5%B6'%2C%20%20%20%20%20%20%20%20%20%5B'hy-AM'%5D%5D%2C%0A%20%5B'%E0%AE%A4%E0%AE%AE%E0%AE%BF%E0%AE%B4%E0%AF%8D'%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'ta-IN'%2C%20'%E0%AE%87%E0%AE%A8%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%AF%E0%AE%BE'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'ta-SG'%2C%20'%E0%AE%9A%E0%AE%BF%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AF%82%E0%AE%B0%E0%AF%8D'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'ta-LK'%2C%20'%E0%AE%87%E0%AE%B2%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AF%88'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'ta-MY'%2C%20'%E0%AE%AE%E0%AE%B2%E0%AF%87%E0%AE%9A%E0%AE%BF%E0%AE%AF%E0%AE%BE'%5D%5D%2C%0A%20%5B'%E0%B0%A4%E0%B1%86%E0%B0%B2%E0%B1%81%E0%B0%97%E0%B1%81'%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'te-IN'%5D%5D%2C%0A%20%5B'Ti%E1%BA%BFng%20Vi%E1%BB%87t'%2C%20%20%20%20%20%20%5B'vi-VN'%5D%5D%2C%0A%20%5B'T%C3%BCrk%C3%A7e'%2C%20%20%20%20%20%20%20%20%20%20%5B'tr-TR'%5D%5D%2C%0A%20%5B'%D8%A7%D9%8F%D8%B1%D8%AF%D9%8F%D9%88'%2C%20%20%20%20%20%20%20%20%20%20%20%20%5B'ur-PK'%2C%20'%D9%BE%D8%A7%DA%A9%D8%B3%D8%AA%D8%A7%D9%86'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'ur-IN'%2C%20'%D8%A8%DA%BE%D8%A7%D8%B1%D8%AA'%5D%5D%2C%0A%20%5B'%CE%95%CE%BB%CE%BB%CE%B7%CE%BD%CE%B9%CE%BA%CE%AC'%2C%20%20%20%20%20%20%20%20%5B'el-GR'%5D%5D%2C%0A%20%5B'%D0%B1%D1%8A%D0%BB%D0%B3%D0%B0%D1%80%D1%81%D0%BA%D0%B8'%2C%20%20%20%20%20%20%20%5B'bg-BG'%5D%5D%2C%0A%20%5B'P%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9'%2C%20%20%20%20%20%20%20%20%20%5B'ru-RU'%5D%5D%2C%0A%20%5B'%D0%A1%D1%80%D0%BF%D1%81%D0%BA%D0%B8'%2C%20%20%20%20%20%20%20%20%20%20%5B'sr-RS'%5D%5D%2C%0A%20%5B'%D0%A3%D0%BA%D1%80%D0%B0%D1%97%D0%BD%D1%81%D1%8C%D0%BA%D0%B0'%2C%20%20%20%20%20%20%5B'uk-UA'%5D%5D%2C%0A%20%5B'%ED%95%9C%EA%B5%AD%EC%96%B4'%2C%20%20%20%20%20%20%20%20%20%20%20%20%5B'ko-KR'%5D%5D%2C%0A%20%5B'%E4%B8%AD%E6%96%87'%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'cmn-Hans-CN'%2C%20'%E6%99%AE%E9%80%9A%E8%AF%9D%20(%E4%B8%AD%E5%9B%BD%E5%A4%A7%E9%99%86)'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'cmn-Hans-HK'%2C%20'%E6%99%AE%E9%80%9A%E8%AF%9D%20(%E9%A6%99%E6%B8%AF)'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'cmn-Hant-TW'%2C%20'%E4%B8%AD%E6%96%87%20(%E5%8F%B0%E7%81%A3)'%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'yue-Hant-HK'%2C%20'%E7%B2%B5%E8%AA%9E%20(%E9%A6%99%E6%B8%AF)'%5D%5D%2C%0A%20%5B'%E6%97%A5%E6%9C%AC%E8%AA%9E'%2C%20%20%20%20%20%20%20%20%20%20%20%5B'ja-JP'%5D%5D%2C%0A%20%5B'%E0%A4%B9%E0%A4%BF%E0%A4%A8%E0%A5%8D%E0%A4%A6%E0%A5%80'%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B'hi-IN'%5D%5D%2C%0A%20%5B'%E0%B8%A0%E0%B8%B2%E0%B8%A9%E0%B8%B2%E0%B9%84%E0%B8%97%E0%B8%A2'%2C%20%20%20%20%20%20%20%20%20%09%20%5B'th-TH'%5D%5D%5D%3B%7D)()%3B
--------------------------------------------------------------------------------
/legacy/talk-to-chatgpt.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C-Nedelcu/talk-to-chatgpt/851519fa4b07617c257ad8f5053d729b09656863/legacy/talk-to-chatgpt.js
--------------------------------------------------------------------------------