1(function($) { 2 var allVoices, bootstrap, apiKey, selectedLang, selectedVoice, testAudio = document.createElement("AUDIO"); 3 $(onDomReady); 4 5 function onDomReady() { 6 apiKey = $("#sitespeaker_key").val() || ""; 7 selectedLang = $("#sitespeaker_lang").data("value") || "en-US"; 8 selectedVoice = $("#sitespeaker_voice").data("value") || ""; 9 Promise.all([loadVoices(), loadBootstrap()]).then(update); 10 $("#sitespeaker_key").change(function() { 11 apiKey = this.value; 12 loadVoices().then(update); 13 }) 14 $("#sitespeaker_lang").change(function() { 15 selectedLang = this.value; 16 update(); 17 }) 18 $("#sitespeaker_voice").change(function() { 19 selectedVoice = this.value; 20 update(); 21 }) 22 $("#sitespeaker_test").click(function() { 23 if (selectedLang && selectedVoice) { 24 $.get("https://ws.sitespeaker.link/test-voice?lang=" + selectedLang + "&voice=" + encodeURIComponent(selectedVoice), function(res) { 25 testAudio.src = res.url; 26 testAudio.play(); 27 }) 28 } 29 }) 30 } 31 32 function loadVoices() { 33 if (!apiKey) { 34 allVoices = []; 35 return Promise.resolve(); 36 } 37 return new Promise(function(fulfill) { 38 $.post({ 39 url: "https://ws.sitespeaker.link/list-voices", 40 data: JSON.stringify({key: apiKey}), 41 contentType: "application/json", 42 dataType: "json", 43 success: function(res) { 44 allVoices = res; 45 fulfill(); 46 }, 47 error: function() { 48 alert("Failed to load voice list, possibly invalid API key"); 49 allVoices = []; 50 fulfill(); 51 } 52 }) 53 }) 54 } 55 56 function loadBootstrap() { 57 return new Promise(function(fulfill) { 58 $.get("https://assets.sitespeaker.link/embed/js/bootstrap.min.js", function(res) { 59 bootstrap = res; 60 fulfill(); 61 }) 62 }) 63 } 64 65 function update() { 66 var languages = Array.from(new Set(allVoices.map(function(voice) {return voice.lang}))).sort(); 67 if (selectedLang && languages.indexOf(selectedLang) == -1) selectedLang = ""; 68 $("#sitespeaker_lang").empty(); 69 $("<option>").val("").appendTo("#sitespeaker_lang");
70 languages.forEach(function(lang) { 71 $("<option>").val(lang) 72 .text(lang) 73 .appendTo("#sitespeaker_lang"); 74 }) 75 $("#sitespeaker_lang").val(selectedLang); 76 77 var voices = allVoices.filter(function(voice) {return voice.lang == selectedLang}).sort(function(a,b) {return a.desc.localeCompare(b.desc)}); 78 if (selectedVoice && !voices.some(function(voice) {return voice.name == selectedVoice})) selectedVoice = ""; 79 $("#sitespeaker_voice").empty(); 80 $("<option>").val("").appendTo("#sitespeaker_voice"); 81 voices.forEach(function(voice) { 82 $("<option>").val(voice.name) 83 .text((voice.desc||voice.name) + " (" + voice.gender[0].toLowerCase() + ")") 84 .appendTo("#sitespeaker_voice"); 85 }) 86 $("#sitespeaker_voice").val(selectedVoice); 87 88 var apiKey = $("#sitespeaker_key").val(); 89 if (apiKey && selectedLang && selectedVoice) { 90 var code = ""; 91 code += '<style>#ra-player {margin-bottom: 1em;} .ra-button {padding: .3em .9em; border-radius: .25em; background: linear-gradient(#fff, #efefef); box-shadow: 0 1px .2em gray; display: inline-flex; align-items: center; cursor: pointer;} .ra-button img {height: 1em; margin: 0 .5em 0 0;}</style>\n'; 92 code += '<div id="ra-player" data-skin="https://assets.sitespeaker.link/embed/skins/default">'; 93 code += '<div class="ra-button" onclick="readAloud(document.getElementById(\'ra-audio\'), document.getElementById(\'ra-player\'))">'; 94 code += '<img src="https://assets.sitespeaker.link/embed/skins/default/play-icon.png"/> Listen to this article'; 95 code += '</div>'; 96 code += '</div>\n'; 97 code += '<audio id="ra-audio" data-lang="' + selectedLang + '" data-voice="' + selectedVoice + '" data-key="' + apiKey + '"></audio>\n'; 98 code += '<script>\n<!--\n' + bootstrap + '\n//-->\u003c/script>\n'; 99 $("#sitespeaker_code").val(code); 100 } 101 else { 102 $("#sitespeaker_code").val(""); 103 } 104 } 105}) 106(jQuery)
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.