maidr 2.9.2 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/maidr.js +36 -56
- package/dist/maidr.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
# maidr: Multimodal Access and Interactive Data Representation
|
|
10
10
|
|
|
11
|
-
maidr (pronounced as 'mader') is a system for non-visual access and control of statistical plots. It aims to provide an inclusive experience for users with visual impairments by offering multiple modes of interaction: braille, text, and sonification (BTS). This comprehensive approach enhances the accessibility of data visualization and encourages a multi-modal exploration on visualization. Check out the current build: [maidr Demo](https://xability.github.io/maidr/
|
|
11
|
+
maidr (pronounced as 'mader') is a system for non-visual access and control of statistical plots. It aims to provide an inclusive experience for users with visual impairments by offering multiple modes of interaction: braille, text, and sonification (BTS). This comprehensive approach enhances the accessibility of data visualization and encourages a multi-modal exploration on visualization. Check out the current build: [maidr Demo](https://xability.github.io/maidr/galleries/index.html). You may also clone or download the GitHub repo, navigate to the ./user_study_pilot folder, and open any of the html files in your browser.
|
|
12
12
|
|
|
13
13
|
## Table of Contents
|
|
14
14
|
|
package/dist/maidr.js
CHANGED
|
@@ -476,12 +476,12 @@ class Menu {
|
|
|
476
476
|
<option value="basic">Basic</option>
|
|
477
477
|
<option value="intermediate">Intermediate</option>
|
|
478
478
|
<option value="expert">Expert</option>
|
|
479
|
-
<option value="other">
|
|
479
|
+
<option value="other">Other: describe in your own words</option>
|
|
480
480
|
</select>
|
|
481
481
|
<label for="skill_level">Level of skill in statistical charts</label>
|
|
482
482
|
</p>
|
|
483
483
|
<p id="skill_level_other_container" class="hidden"><input type="text" placeholder="Very basic" id="skill_level_other"> <label for="skill_level_other">Describe your level of skill in statistical charts</label></p>
|
|
484
|
-
<p><label for="LLM_preferences">
|
|
484
|
+
<p><label for="LLM_preferences">Custom instructions for the chat response</label></p>
|
|
485
485
|
<p><textarea id="LLM_preferences" rows="4" cols="50" placeholder="I'm a stats undergrad and work with Python. I prefer a casual tone, and favor information accuracy over creative description; just the facts please!"></textarea></p>
|
|
486
486
|
</div>
|
|
487
487
|
</div>
|
|
@@ -966,7 +966,16 @@ class ChatLLM {
|
|
|
966
966
|
this.CreateComponent();
|
|
967
967
|
this.SetEvents();
|
|
968
968
|
if (constants.autoInitLLM) {
|
|
969
|
-
|
|
969
|
+
// only run if we have API keys set
|
|
970
|
+
if (
|
|
971
|
+
(constants.LLMModel == 'openai' && constants.openAIAuthKey) ||
|
|
972
|
+
(constants.LLMModel == 'gemini' && constants.geminiAuthKey) ||
|
|
973
|
+
(constants.LLMModel == 'multi' &&
|
|
974
|
+
constants.openAIAuthKey &&
|
|
975
|
+
constants.geminiAuthKey)
|
|
976
|
+
) {
|
|
977
|
+
this.InitChatMessage();
|
|
978
|
+
}
|
|
970
979
|
}
|
|
971
980
|
}
|
|
972
981
|
|
|
@@ -997,11 +1006,10 @@ class ChatLLM {
|
|
|
997
1006
|
<p><button type="button">What is the title?</button></p>
|
|
998
1007
|
<p><button type="button">What are the high and low values?</button></p>
|
|
999
1008
|
<p><button type="button">What is the general shape of the chart?</button></p>
|
|
1000
|
-
<p><button type="button" id="more_suggestions">More</button></p>
|
|
1001
1009
|
</div>
|
|
1002
|
-
<div id="more_suggestions_container" class="
|
|
1010
|
+
<div id="more_suggestions_container" class="LLM_suggestions">
|
|
1003
1011
|
<p><button type="button">Please provide the title of this visualization, then provide a description for someone who is blind or low vision. Include general overview of axes and the data at a high-level.</button></p>
|
|
1004
|
-
<p><button type="button">For the visualization I shared, please provide the following (where applicable): mean, standard deviation,
|
|
1012
|
+
<p><button type="button">For the visualization I shared, please provide the following (where applicable): mean, standard deviation, extreme, correlations, relational comparisons like greater than OR lesser than.</button></p>
|
|
1005
1013
|
<p><button type="button">Based on the visualization shared, address the following: Do you observe any unforeseen trends? If yes, what? Please convey any complex multi-faceted patterns present. Can you identify any noteworthy exceptions that aren't readily apparent through non-visual methods of analysis?</button></p>
|
|
1006
1014
|
<p><button type="button">Provide context to help explain the data depicted in this visualization based on domain-specific insight.</button></p>
|
|
1007
1015
|
</div>
|
|
@@ -1080,21 +1088,6 @@ class ChatLLM {
|
|
|
1080
1088
|
]);
|
|
1081
1089
|
|
|
1082
1090
|
// ChatLLM suggestion events
|
|
1083
|
-
// the more button
|
|
1084
|
-
constants.events.push([
|
|
1085
|
-
document.getElementById('more_suggestions'),
|
|
1086
|
-
'click',
|
|
1087
|
-
function (e) {
|
|
1088
|
-
document
|
|
1089
|
-
.getElementById('more_suggestions_container')
|
|
1090
|
-
.classList.toggle('hidden');
|
|
1091
|
-
// focus on button right after the more button
|
|
1092
|
-
document
|
|
1093
|
-
.querySelector('#more_suggestions_container > p > button')
|
|
1094
|
-
.focus();
|
|
1095
|
-
document.getElementById('more_suggestions').remove();
|
|
1096
|
-
},
|
|
1097
|
-
]);
|
|
1098
1091
|
// actual suggestions:
|
|
1099
1092
|
let suggestions = document.querySelectorAll(
|
|
1100
1093
|
'#chatLLM .LLM_suggestions button:not(#more_suggestions)'
|
|
@@ -1205,7 +1198,7 @@ class ChatLLM {
|
|
|
1205
1198
|
markdown = markdown.replace(/\n{3,}/g, '\n\n');
|
|
1206
1199
|
|
|
1207
1200
|
try {
|
|
1208
|
-
navigator.clipboard.writeText(markdown);
|
|
1201
|
+
navigator.clipboard.writeText(markdown); // note: this fails if you're on the inspector. That's fine as it'll never happen to real users
|
|
1209
1202
|
} catch (err) {
|
|
1210
1203
|
console.error('Failed to copy: ', err);
|
|
1211
1204
|
}
|
|
@@ -1375,6 +1368,7 @@ class ChatLLM {
|
|
|
1375
1368
|
|
|
1376
1369
|
if (data.error) {
|
|
1377
1370
|
chatLLM.DisplayChatMessage(LLMName, 'Error processing request.', true);
|
|
1371
|
+
chatLLM.WaitingSound(false);
|
|
1378
1372
|
} else {
|
|
1379
1373
|
chatLLM.DisplayChatMessage(LLMName, text);
|
|
1380
1374
|
}
|
|
@@ -1385,10 +1379,12 @@ class ChatLLM {
|
|
|
1385
1379
|
} else {
|
|
1386
1380
|
if (!data.error) {
|
|
1387
1381
|
data.error = 'Error processing request.';
|
|
1382
|
+
chatLLM.WaitingSound(false);
|
|
1388
1383
|
}
|
|
1389
1384
|
}
|
|
1390
1385
|
if (data.error) {
|
|
1391
1386
|
chatLLM.DisplayChatMessage(LLMName, 'Error processing request.', true);
|
|
1387
|
+
chatLLM.WaitingSound(false);
|
|
1392
1388
|
} else {
|
|
1393
1389
|
// todo: display actual response
|
|
1394
1390
|
}
|
|
@@ -1489,7 +1485,7 @@ class ChatLLM {
|
|
|
1489
1485
|
.catch((error) => {
|
|
1490
1486
|
chatLLM.WaitingSound(false);
|
|
1491
1487
|
console.error('Error:', error);
|
|
1492
|
-
chatLLM.DisplayChatMessage(
|
|
1488
|
+
chatLLM.DisplayChatMessage('OpenAI', 'Error processing request.', true);
|
|
1493
1489
|
// also todo: handle errors somehow
|
|
1494
1490
|
});
|
|
1495
1491
|
}
|
|
@@ -1579,6 +1575,8 @@ class ChatLLM {
|
|
|
1579
1575
|
// Process the response
|
|
1580
1576
|
chatLLM.ProcessLLMResponse(result.response, 'gemini');
|
|
1581
1577
|
} catch (error) {
|
|
1578
|
+
chatLLM.WaitingSound(false);
|
|
1579
|
+
chatLLM.DisplayChatMessage('Gemini', 'Error processing request.', true);
|
|
1582
1580
|
console.error('Error in GeminiPrompt:', error);
|
|
1583
1581
|
throw error; // Rethrow the error for further handling if necessary
|
|
1584
1582
|
}
|
|
@@ -1640,11 +1638,6 @@ class ChatLLM {
|
|
|
1640
1638
|
ResetLLM() {
|
|
1641
1639
|
// clear the main chat history
|
|
1642
1640
|
document.getElementById('chatLLM_chat_history').innerHTML = '';
|
|
1643
|
-
// unhide the more button
|
|
1644
|
-
document
|
|
1645
|
-
.getElementById('more_suggestions_container')
|
|
1646
|
-
.classList.add('hidden');
|
|
1647
|
-
document.getElementById('more_suggestions').classList.remove('hidden');
|
|
1648
1641
|
|
|
1649
1642
|
// reset the data
|
|
1650
1643
|
this.requestJson = null;
|
|
@@ -2159,10 +2152,12 @@ class Tracker {
|
|
|
2159
2152
|
SaveSettings() {
|
|
2160
2153
|
// fetch all settings, push to data.settings
|
|
2161
2154
|
let settings = JSON.parse(localStorage.getItem('settings_data'));
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2155
|
+
if (settings) {
|
|
2156
|
+
// don't store their auth keys
|
|
2157
|
+
settings.openAIAuthKey = 'hidden';
|
|
2158
|
+
settings.geminiAuthKey = 'hidden';
|
|
2159
|
+
this.SetData('settings', settings);
|
|
2160
|
+
}
|
|
2166
2161
|
}
|
|
2167
2162
|
|
|
2168
2163
|
/**
|
|
@@ -2308,6 +2303,7 @@ class Tracker {
|
|
|
2308
2303
|
constants.plotOrientation == 'vert' ? position.x : position.y;
|
|
2309
2304
|
let sectionPos =
|
|
2310
2305
|
constants.plotOrientation == 'vert' ? position.y : position.x;
|
|
2306
|
+
let sectionLabel = plot.sections[sectionPos];
|
|
2311
2307
|
|
|
2312
2308
|
if (!this.isUndefinedOrNull(plot.x_group_label)) {
|
|
2313
2309
|
x_label = plot.x_group_label;
|
|
@@ -2317,42 +2313,26 @@ class Tracker {
|
|
|
2317
2313
|
}
|
|
2318
2314
|
if (constants.plotOrientation == 'vert') {
|
|
2319
2315
|
if (plotPos > -1 && sectionPos > -1) {
|
|
2320
|
-
if (
|
|
2321
|
-
|
|
2322
|
-
) {
|
|
2323
|
-
y_tickmark = plot.plotData[plotPos][sectionPos].label;
|
|
2316
|
+
if (!this.isUndefinedOrNull(sectionLabel)) {
|
|
2317
|
+
y_tickmark = sectionLabel;
|
|
2324
2318
|
}
|
|
2325
2319
|
if (!this.isUndefinedOrNull(plot.x_labels[position.x])) {
|
|
2326
2320
|
x_tickmark = plot.x_labels[position.x];
|
|
2327
2321
|
}
|
|
2328
|
-
if (
|
|
2329
|
-
|
|
2330
|
-
) {
|
|
2331
|
-
value = plot.plotData[plotPos][sectionPos].values;
|
|
2332
|
-
} else if (
|
|
2333
|
-
!this.isUndefinedOrNull(plot.plotData[plotPos][sectionPos].y)
|
|
2334
|
-
) {
|
|
2335
|
-
value = plot.plotData[plotPos][sectionPos].y;
|
|
2322
|
+
if (!this.isUndefinedOrNull(plot.plotData[plotPos][sectionLabel])) {
|
|
2323
|
+
value = plot.plotData[plotPos][sectionLabel];
|
|
2336
2324
|
}
|
|
2337
2325
|
}
|
|
2338
2326
|
} else {
|
|
2339
2327
|
if (plotPos > -1 && sectionPos > -1) {
|
|
2340
|
-
if (
|
|
2341
|
-
|
|
2342
|
-
) {
|
|
2343
|
-
x_tickmark = plot.plotData[plotPos][sectionPos].label;
|
|
2328
|
+
if (!this.isUndefinedOrNull(sectionLabel)) {
|
|
2329
|
+
x_tickmark = sectionLabel;
|
|
2344
2330
|
}
|
|
2345
2331
|
if (!this.isUndefinedOrNull(plot.y_labels[position.y])) {
|
|
2346
2332
|
y_tickmark = plot.y_labels[position.y];
|
|
2347
2333
|
}
|
|
2348
|
-
if (
|
|
2349
|
-
|
|
2350
|
-
) {
|
|
2351
|
-
value = plot.plotData[plotPos][sectionPos].values;
|
|
2352
|
-
} else if (
|
|
2353
|
-
!this.isUndefinedOrNull(plot.plotData[plotPos][sectionPos].x)
|
|
2354
|
-
) {
|
|
2355
|
-
value = plot.plotData[plotPos][sectionPos].x;
|
|
2334
|
+
if (!this.isUndefinedOrNull(plot.plotData[plotPos][sectionLabel])) {
|
|
2335
|
+
value = plot.plotData[plotPos][sectionLabel];
|
|
2356
2336
|
}
|
|
2357
2337
|
}
|
|
2358
2338
|
}
|
package/dist/maidr.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class Constants{chart_container_id="chart-container";main_container_id="maidr-container";braille_container_id="braille-div";braille_input_id="braille-input";info_id="info";announcement_container_id="announcements";end_chime_id="end_chime";container_id="container";project_id="maidr";review_id_container="review_container";review_id="review";reviewSaveSpot;reviewSaveBrailleMode;chartId="";events=[];postLoadEvents=[];constructor(){}textMode="verbose";brailleMode="off";sonifMode="on";reviewMode="off";minX=0;maxX=0;minY=0;maxY=0;plotId="";chartType="";navigation=1;MAX_FREQUENCY=1e3;MIN_FREQUENCY=200;NULL_FREQUENCY=100;combinedVolMin=.25;combinedVolMax=1.25;MAX_SPEED=500;MIN_SPEED=50;DEFAULT_SPEED=250;INTERVAL=20;AUTOPLAY_DURATION=5e3;vol=.5;MAX_VOL=30;autoPlayRate=this.DEFAULT_SPEED;colorSelected="#03C809";brailleDisplayLength=32;showRect=1;hasRect=1;hasSmooth=1;duration=.3;outlierDuration=.06;autoPlayOutlierRate=50;autoPlayPointsRate=50;colorUnselected="#595959";canTrack=1;isTracking=1;visualBraille=!1;globalMinMax=!0;ariaMode="assertive";userSettingsKeys=["vol","autoPlayRate","brailleDisplayLength","colorSelected","MIN_FREQUENCY","MAX_FREQUENCY","keypressInterval","ariaMode","openAIAuthKey","geminiAuthKey","skillLevel","skillLevelOther","LLMModel","LLMPreferences","LLMOpenAiMulti","LLMGeminiMulti","autoInitLLM"];openAIAuthKey=null;geminiAuthKey=null;LLMmaxResponseTokens=1e3;playLLMWaitingSound=!0;LLMDetail="high";LLMModel="openai";LLMSystemMessage="You are a helpful assistant describing the chart to a blind person. ";skillLevel="basic";skillLevelOther="";autoInitLLM=!0;verboseText="";showDisplay=1;showDisplayInBraille=1;showDisplayInAutoplay=0;outlierInterval=null;isMac=navigator.userAgent.toLowerCase().includes("mac");control=this.isMac?"Cmd":"Ctrl";alt=this.isMac?"option":"Alt";home=this.isMac?"fn + Left arrow":"Home";end=this.isMac?"fn + Right arrow":"End";keypressInterval=2e3;tabMovement=null;debugLevel=3;canPlayEndChime=!1;manualData=!0;KillAutoplay(){this.autoplayId&&(clearInterval(this.autoplayId),this.autoplayId=null)}KillSepPlay(){this.sepPlayId&&(clearInterval(this.sepPlayId),this.sepPlayId=null)}SpeedUp(){constants.autoPlayRate-this.INTERVAL>this.MIN_SPEED&&(constants.autoPlayRate-=this.INTERVAL)}SpeedDown(){constants.autoPlayRate+this.INTERVAL<=this.MAX_SPEED&&(constants.autoPlayRate+=this.INTERVAL)}SpeedReset(){constants.autoPlayRate=constants.DEFAULT_SPEED}ConvertHexToRGBString(t){return"rgb("+parseInt(t.slice(1,3),16)+","+parseInt(t.slice(3,5),16)+","+parseInt(t.slice(5,7),16)+")"}ConvertRGBStringToHex(t){let e=t.replace(/[^\d,]/g,"").split(",");return"#"+e[0].toString(16).padStart(2,"0")+e[1].toString(16).padStart(2,"0")+e[2].toString(16).padStart(2,"0")}ColorInvert(t){let e=t.replace(/[^\d,]/g,"").split(",");return"rgb("+(255-e[0])+","+(255-e[1])+","+(255-e[2])+")"}GetBetterColor(t){-1!==t.indexOf("#")&&(t=this.ConvertHexToRGBString(t));let e=this.ColorInvert(t),n=e.replace(/[^\d,]/g,"").split(",");return n[1]<n[0]+10&&n[1]>n[0]-10&&n[2]<n[0]+10&&n[2]>n[0]-10&&(n[0]>86||n[0]<169)&&(e=this.colorSelected),e}GetStyleArrayFromString(t){return t.replaceAll(" ","").split(/[:;]/)}GetStyleStringFromArray(t){let e="";for(let n=0;n<t.length;n++)n%2==0?n!==t.length-1?e+=t[n]+": ":e+=t[n]:e+=t[n]+"; ";return e}}class Resources{constructor(){}language="en";knowledgeLevel="basic";strings={en:{basic:{upper_outlier:"Upper Outlier",lower_outlier:"Lower Outlier",min:"Minimum",max:"Maximum",25:"25%",50:"50%",75:"75%",q1:"25%",q2:"50%",q3:"75%",son_on:"Sonification on",son_off:"Sonification off",son_des:"Sonification descrete",son_comp:"Sonification compare",son_ch:"Sonification chord",son_sep:"Sonification separate",son_same:"Sonification combined",empty:"Empty",openai:"OpenAI Vision",gemini:"Gemini Pro Vision",multi:"Multiple AI",processing:"Processing Chart..."}}};GetString(t){return this.strings[this.language][this.knowledgeLevel][t]}}class Menu{whereWasMyFocus=null;constructor(){this.CreateMenu(),this.LoadDataFromLocalStorage()}menuHtml=`\n <div id="menu" class="modal hidden" role="dialog" tabindex="-1">\n <div class="modal-dialog" role="document" tabindex="0">\n <div class="modal-content">\n <div class="modal-header">\n <h2 class="modal-title">Menu</h2>\n <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n <div class="modal-body">\n <div>\n <h5 class="modal-title">Keyboard Shortcuts</h5>\n <table>\n <caption class="sr-only">Keyboard Shortcuts</caption>\n <thead>\n <tr>\n <th scope="col">Function</th>\n <th scope="col">Key</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>Move around plot</td>\n <td>Arrow keys</td>\n </tr>\n <tr>\n <td>Go to the very left right up down</td>\n <td>${constants.control} + Arrow key</td>\n </tr>\n <tr>\n <td>Select the first element</td>\n <td>${constants.control} + ${constants.home}</td>\n </tr>\n <tr>\n <td>Select the last element</td>\n <td>${constants.control} + ${constants.end}</td>\n </tr>\n <tr>\n <td>Toggle Braille Mode</td>\n <td>b</td>\n </tr>\n <tr>\n <td>Toggle Sonification Mode</td>\n <td>s</td>\n </tr>\n <tr>\n <td>Toggle Text Mode</td>\n <td>t</td>\n </tr>\n <tr>\n <td>Repeat current sound</td>\n <td>Space</td>\n </tr>\n <tr>\n <td>Auto-play outward in direction of arrow</td>\n <td>${constants.control} + Shift + Arrow key</td>\n </tr>\n <tr>\n <td>Auto-play inward in direction of arrow</td>\n <td>${constants.alt} + Shift + Arrow key</td>\n </tr>\n <tr>\n <td>Stop Auto-play</td>\n <td>${constants.control}</td>\n </tr>\n <tr>\n <td>Auto-play speed up</td>\n <td>Period</td>\n </tr>\n <tr>\n <td>Auto-play speed down</td>\n <td>Comma</td>\n </tr>\n <tr>\n <td>Open GenAI Chat</td>\n <td>${constants.isMac?constants.alt:constants.control} + Shift + ?</td>\n </tr>\n <tr>\n <td>Copy last chat message</td>\n <td>${constants.alt} + Shift + C</td>\n </tr>\n <tr>\n <td>Copy full chat history</td>\n <td>${constants.alt} + Shift + A</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <div>\n <h5 class="modal-title">Settings</h5>\n <p><input type="range" id="vol" name="vol" min="0" max="1" step=".05"><label for="vol">Volume</label></p>\n \x3c!-- <p><input type="checkbox" id="show_rect" name="show_rect"><label for="show_rect">Show Outline</label></p> //--\x3e\n <p><input type="number" min="4" max="2000" step="1" id="braille_display_length" name="braille_display_length"><label for="braille_display_length">Braille Display Size</label></p>\n <p><input type="number" min="${constants.MIN_SPEED}" max="500" step="${constants.INTERVAL}" id="autoplay_rate" name="autoplay_rate"><label for="autoplay_rate">Autoplay Rate</label></p>\n <p><input type="color" id="color_selected" name="color_selected"><label for="color_selected">Outline Color</label></p>\n <p><input type="number" min="10" max="2000" step="10" id="min_freq" name="min_freq"><label for="min_freq">Min Frequency (Hz)</label></p>\n <p><input type="number" min="20" max="2010" step="10" id="max_freq" name="max_freq"><label for="max_freq">Max Frequency (Hz)</label></p>\n <p><input type="number" min="500" max="5000" step="500" id="keypress_interval" name="keypress_interval"><label for="keypress_interval">Keypress Interval (ms)</label></p>\n <div><fieldset>\n <legend>Aria Mode</legend>\n <p><input type="radio" id="aria_mode_assertive" name="aria_mode" value="assertive" ${"assertive"==constants.ariaMode?"checked":""}><label for="aria_mode_assertive">Assertive</label></p>\n <p><input type="radio" id="aria_mode_polite" name="aria_mode" value="polite" ${"polite"==constants.ariaMode?"checked":""}><label for="aria_mode_polite">Polite</label></p>\n </fieldset></div>\n <h5 class="modal-title">LLM Settings</h5>\n <p>\n <select id="LLM_model">\n <option value="openai">OpenAI Vision</option>\n <option value="gemini">Gemini Pro Vision</option>\n <option value="multi">Multiple</option>\n </select>\n <label for="LLM_model">LLM Model</label>\n </p>\n <p id="openai_auth_key_container" class="multi_container hidden">\n <span id="openai_multi_container" class="hidden"><input type="checkbox" id="openai_multi" name="openai_multi" aria-label="Use OpenAI in Multi modal mode"></span>\n <input type="password" id="openai_auth_key"><button aria-label="Delete OpenAI key" title="Delete OpenAI key" id="delete_openai_key" class="invis_button">×</button><label for="openai_auth_key">OpenAI Authentication Key</label>\n </p>\n <p id="gemini_auth_key_container" class="multi_container hidden">\n <span id="gemini_multi_container" class="hidden"><input type="checkbox" id="gemini_multi" name="gemini_multi" aria-label="Use Gemini in Multi modal mode"></span>\n <input type="password" id="gemini_auth_key"><button aria-label="Delete Gemini key" title="Delete Gemini key" id="delete_gemini_key" class="invis_button">×</button><label for="gemini_auth_key">Gemini Authentication Key</label>\n </p>\n <p><input type="checkbox" ${constants.autoInitLLM?"checked":""} id="init_llm_on_load" name="init_llm_on_load"><label for="init_llm_on_load">Start first LLM chat chart load</label></p>\n <p>\n <select id="skill_level">\n <option value="basic">Basic</option>\n <option value="intermediate">Intermediate</option>\n <option value="expert">Expert</option>\n <option value="other">other</option>\n </select>\n <label for="skill_level">Level of skill in statistical charts</label>\n </p>\n <p id="skill_level_other_container" class="hidden"><input type="text" placeholder="Very basic" id="skill_level_other"> <label for="skill_level_other">Describe your level of skill in statistical charts</label></p>\n <p><label for="LLM_preferences">LLM Preferences</label></p>\n <p><textarea id="LLM_preferences" rows="4" cols="50" placeholder="I'm a stats undergrad and work with Python. I prefer a casual tone, and favor information accuracy over creative description; just the facts please!"></textarea></p>\n </div>\n </div>\n <div class="modal-footer">\n <p>\n <button type="button" id="save_and_close_menu" aria-labelledby="save_and_close_text"><span id="save_and_close_text">Save and Close</span></button>\n <button type="button" id="close_menu">Close</button>\n </p>\n </div>\n </div>\n </div>\n </div>\n <div id="menu_modal_backdrop" class="modal-backdrop hidden"></div>\n `;CreateMenu(){document.querySelector("body").insertAdjacentHTML("beforeend",this.menuHtml);let t=document.querySelectorAll("#close_menu, #menu .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){menu.Toggle(!1)}]);constants.events.push([document.getElementById("save_and_close_menu"),"click",function(t){menu.SaveData(),menu.Toggle(!1)}]),constants.events.push([document.getElementById("menu"),"keyup",function(t){"Esc"==t.key&&menu.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){"input"!=t.target.tagName.toLowerCase()&&"textarea"!=t.target.tagName.toLowerCase()&&"h"==t.key&&menu.Toggle(!0)}]),constants.events.push([document.getElementById("LLM_model"),"change",function(t){"openai"==t.target.value?(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.add("hidden"),document.getElementById("openai_multi_container").classList.add("hidden"),document.getElementById("gemini_multi_container").classList.add("hidden"),document.getElementById("openai_multi").checked=!0,document.getElementById("gemini_multi").checked=!1):"gemini"==t.target.value?(document.getElementById("openai_auth_key_container").classList.add("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.add("hidden"),document.getElementById("gemini_multi_container").classList.add("hidden"),document.getElementById("openai_multi").checked=!1,document.getElementById("gemini_multi").checked=!0):"multi"==t.target.value&&(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.remove("hidden"),document.getElementById("gemini_multi_container").classList.remove("hidden"),document.getElementById("openai_multi").checked=!0,document.getElementById("gemini_multi").checked=!0)}]),constants.events.push([document.getElementById("skill_level"),"change",function(t){"other"==t.target.value?document.getElementById("skill_level_other_container").classList.remove("hidden"):document.getElementById("skill_level_other_container").classList.add("hidden")}]);let e=["LLM_model","openai_multi","gemini_multi","skill_level","LLM_preferences"];for(let t=0;t<e.length;t++)constants.events.push([document.getElementById(e[t]),"change",function(t){menu.NotifyOfLLMReset()}])}Destroy(){let t=document.getElementById("menu");t&&t.remove();let e=document.getElementById("menu_modal_backdrop");e&&e.remove()}Toggle(t=!1){void 0===t&&(t=!!document.getElementById("menu").classList.contains("hidden")),t&&document.getElementById("chatLLM")&&!document.getElementById("chatLLM").classList.contains("hidden")||(t?(this.whereWasMyFocus=document.activeElement,this.PopulateData(),constants.tabMovement=0,document.getElementById("menu").classList.remove("hidden"),document.getElementById("menu_modal_backdrop").classList.remove("hidden"),document.querySelector("#menu .close").focus()):(document.getElementById("menu").classList.add("hidden"),document.getElementById("menu_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null))}PopulateData(){document.getElementById("vol").value=constants.vol,document.getElementById("autoplay_rate").value=constants.autoPlayRate,document.getElementById("braille_display_length").value=constants.brailleDisplayLength,document.getElementById("color_selected").value=constants.colorSelected,document.getElementById("min_freq").value=constants.MIN_FREQUENCY,document.getElementById("max_freq").value=constants.MAX_FREQUENCY,document.getElementById("keypress_interval").value=constants.keypressInterval,"string"==typeof constants.openAIAuthKey&&(document.getElementById("openai_auth_key").value=constants.openAIAuthKey),"string"==typeof constants.geminiAuthKey&&(document.getElementById("gemini_auth_key").value=constants.geminiAuthKey),document.getElementById("skill_level").value=constants.skillLevel,constants.skillLevelOther&&(document.getElementById("skill_level_other").value=constants.skillLevelOther),document.getElementById("LLM_model").value=constants.LLMModel,"assertive"==constants.ariaMode?(document.getElementById("aria_mode_assertive").checked=!0,document.getElementById("aria_mode_polite").checked=!1):(document.getElementById("aria_mode_polite").checked=!0,document.getElementById("aria_mode_assertive").checked=!1),"openai"==constants.LLMModel?(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.add("hidden")):"gemini"==constants.LLMModel?(document.getElementById("openai_auth_key_container").classList.add("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden")):"multi"==constants.LLMModel&&(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.remove("hidden"),document.getElementById("gemini_multi_container").classList.remove("hidden"),document.getElementById("openai_multi").checked=!1,constants.LLMOpenAiMulti&&(document.getElementById("openai_multi").checked=!0),document.getElementById("gemini_multi").checked=!1,constants.LLMGeminiMulti&&(document.getElementById("gemini_multi").checked=!0)),"other"==constants.skillLevel&&document.getElementById("skill_level_other_container").classList.remove("hidden"),constants.LLMPreferences&&(document.getElementById("LLM_preferences").value=constants.LLMPreferences),document.getElementById("LLM_reset_notification")&&document.getElementById("LLM_reset_notification").remove()}SaveData(){let t=this.ShouldLLMReset();constants.vol=document.getElementById("vol").value,constants.autoPlayRate=document.getElementById("autoplay_rate").value,constants.brailleDisplayLength=document.getElementById("braille_display_length").value,constants.colorSelected=document.getElementById("color_selected").value,constants.MIN_FREQUENCY=document.getElementById("min_freq").value,constants.MAX_FREQUENCY=document.getElementById("max_freq").value,constants.keypressInterval=document.getElementById("keypress_interval").value,constants.openAIAuthKey=document.getElementById("openai_auth_key").value,constants.geminiAuthKey=document.getElementById("gemini_auth_key").value,constants.skillLevel=document.getElementById("skill_level").value,constants.skillLevelOther=document.getElementById("skill_level_other").value,constants.LLMModel=document.getElementById("LLM_model").value,constants.LLMPreferences=document.getElementById("LLM_preferences").value,constants.LLMOpenAiMulti=document.getElementById("openai_multi").checked,constants.LLMGeminiMulti=document.getElementById("gemini_multi").checked,constants.autoInitLLM=document.getElementById("init_llm_on_load").checked,document.getElementById("aria_mode_assertive").checked?constants.ariaMode="assertive":document.getElementById("aria_mode_polite").checked&&(constants.ariaMode="polite"),this.SaveDataToLocalStorage(),this.UpdateHtml(),t&&chatLLM&&chatLLM.ResetLLM()}UpdateHtml(){constants.infoDiv.setAttribute("aria-live",constants.ariaMode),document.getElementById(constants.announcement_container_id).setAttribute("aria-live",constants.ariaMode),document.getElementById("init_llm_on_load").checked=constants.autoInitLLM}NotifyOfLLMReset(){document.getElementById("LLM_reset_notification")&&document.getElementById("LLM_reset_notification").remove(),document.getElementById("save_and_close_menu").parentElement.insertAdjacentHTML("afterend",'<p id="LLM_reset_notification">Note: Changes in LLM settings will reset any existing conversation.</p>'),document.getElementById("save_and_close_menu").setAttribute("aria-labelledby","save_and_close_text LLM_reset_notification")}ShouldLLMReset(){let t=!1;return t||constants.skillLevel==document.getElementById("skill_level").value||(t=!0),t||constants.LLMPreferences==document.getElementById("LLM_preferences").value||(t=!0),t||constants.LLMModel==document.getElementById("LLM_model").value||(t=!0),t||constants.LLMOpenAiMulti==document.getElementById("openai_multi").checked&&constants.LLMGeminiMulti==document.getElementById("gemini_multi").checked||(t=!0),t}SaveDataToLocalStorage(){let t={};for(let e=0;e<constants.userSettingsKeys.length;e++)t[constants.userSettingsKeys[e]]=constants[constants.userSettingsKeys[e]];localStorage.setItem("settings_data",JSON.stringify(t)),constants.isTracking&&(t.openAIAuthKey="hidden",t.geminiAuthKey="hidden",t.timestamp=(new Date).toISOString(),tracker.SetData("settings",t))}LoadDataFromLocalStorage(){let t=JSON.parse(localStorage.getItem("settings_data"));if(t)for(let e=0;e<constants.userSettingsKeys.length;e++)constants[constants.userSettingsKeys[e]]=t[constants.userSettingsKeys[e]];this.PopulateData(),this.UpdateHtml()}}class ChatLLM{constructor(){this.firstTime=!0,this.firstMulti=!0,this.firstOpen=!0,this.shown=!1,this.CreateComponent(),this.SetEvents(),constants.autoInitLLM&&this.InitChatMessage()}CreateComponent(){let t=`\n <div id="chatLLM" class="modal hidden" role="dialog" tabindex="-1">\n <div class="modal-dialog" role="document" tabindex="0">\n <div class="modal-content">\n <div class="modal-header">\n <h2 id="chatLLM_title" class="modal-title">Ask a Question</h2>\n <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n <div class="modal-body">\n <div id="chatLLM_chat_history_wrapper">\n <div id="chatLLM_chat_history" aria-live="${constants.ariaMode}" aria-relevant="additions">\n </div>\n <p id="chatLLM_copy_all_wrapper"><button id="chatLLM_copy_all">Copy all to clipboard</button></p>\n </div>\n <div id="chatLLM_content">\n <p><input type="text" id="chatLLM_input" class="form-control" name="chatLLM_input" aria-labelledby="chatLLM_title" size="50"></p>\n <div class="LLM_suggestions">\n <p><button type="button">What is the title?</button></p>\n <p><button type="button">What are the high and low values?</button></p>\n <p><button type="button">What is the general shape of the chart?</button></p>\n <p><button type="button" id="more_suggestions">More</button></p>\n </div>\n <div id="more_suggestions_container" class="hidden LLM_suggestions">\n <p><button type="button">Please provide the title of this visualization, then provide a description for someone who is blind or low vision. Include general overview of axes and the data at a high-level.</button></p>\n <p><button type="button">For the visualization I shared, please provide the following (where applicable): mean, standard deviation, extrema, correlations, relational comparisons like greater than OR lesser than.</button></p>\n <p><button type="button">Based on the visualization shared, address the following: Do you observe any unforeseen trends? If yes, what? Please convey any complex multi-faceted patterns present. Can you identify any noteworthy exceptions that aren't readily apparent through non-visual methods of analysis?</button></p>\n <p><button type="button">Provide context to help explain the data depicted in this visualization based on domain-specific insight.</button></p>\n </div>\n <p><button type="button" id="chatLLM_submit">Submit</button></p>\n </div>\n </div>\n <div class="modal-footer">\n <button type="button" id="reset_chatLLM">Reset</button>\n <button type="button" id="close_chatLLM">Close</button>\n </div>\n </div>\n </div>\n </div>\n <div id="chatLLM_modal_backdrop" class="modal-backdrop hidden"></div>\n `;document.querySelector("body").insertAdjacentHTML("beforeend",t)}SetEvents(){let t=document.querySelectorAll("#close_chatLLM, #chatLLM .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){chatLLM.Toggle(!1)}]);constants.events.push([document.getElementById("chatLLM"),"keyup",function(t){"Esc"==t.key&&chatLLM.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){("?"==t.key&&(t.ctrlKey||t.metaKey)||"¿"==t.key)&&chatLLM.Toggle()}]),constants.events.push([document.getElementById("chatLLM_submit"),"click",function(t){let e=document.getElementById("chatLLM_input").value;chatLLM.DisplayChatMessage("User",e),chatLLM.Submit(e)}]),constants.events.push([document.getElementById("chatLLM_input"),"keyup",function(t){if("Enter"==t.key&&!t.shiftKey){let t=document.getElementById("chatLLM_input").value;chatLLM.DisplayChatMessage("User",t),chatLLM.Submit(t)}}]),constants.events.push([document.getElementById("more_suggestions"),"click",function(t){document.getElementById("more_suggestions_container").classList.toggle("hidden"),document.querySelector("#more_suggestions_container > p > button").focus(),document.getElementById("more_suggestions").remove()}]);let e=document.querySelectorAll("#chatLLM .LLM_suggestions button:not(#more_suggestions)");for(let t=0;t<e.length;t++)constants.events.push([e[t],"click",function(t){let e=t.target.innerHTML;chatLLM.DisplayChatMessage("User",e),chatLLM.Submit(e)}]);constants.events.push([document.getElementById("delete_openai_key"),"click",function(t){document.getElementById("openai_auth_key").value=""}]),constants.events.push([document.getElementById("delete_gemini_key"),"click",function(t){document.getElementById("gemini_auth_key").value=""}]),constants.events.push([document.getElementById("reset_chatLLM"),"click",function(t){chatLLM.ResetLLM()}]),constants.events.push([document.getElementById("chatLLM"),"click",function(t){chatLLM.CopyChatHistory(t)}]),constants.events.push([document.getElementById("chatLLM"),"keyup",function(t){chatLLM.CopyChatHistory(t)}])}CopyChatHistory(t){let e="";if(void 0===t)e=document.getElementById("chatLLM_chat_history").innerHTML;else if("click"==t.type)"chatLLM_copy_all"==t.target.id?e=document.getElementById("chatLLM_chat_history").innerHTML:t.target.classList.contains("chatLLM_message_copy_button")&&(e=t.target.closest("p").previousElementSibling.innerHTML);else if("keyup"==t.type)if("C"==t.key&&(t.ctrlKey||t.metaKey||t.altKey)&&t.shiftKey){t.preventDefault();let n=document.querySelector("#chatLLM_chat_history > .chatLLM_message_other:last-of-type");n&&(e=n.innerHTML)}else"A"==t.key&&(t.ctrlKey||t.metaKey||t.altKey)&&t.shiftKey&&(t.preventDefault(),e=document.getElementById("chatLLM_chat_history").innerHTML);if(""!=e){let t=document.createElement("div");t.innerHTML=e,t.querySelectorAll(".chatLLM_message_copy").forEach((t=>t.remove()));let n=this.htmlToMarkdown(t);n=n.replace(/\n{3,}/g,"\n\n");try{navigator.clipboard.writeText(n)}catch(t){console.error("Failed to copy: ",t)}return n}}htmlToMarkdown(t){let e="";const n=t=>{switch(t.tagName){case"H1":return`# ${t.textContent}`;case"H2":return`## ${t.textContent}`;case"H3":return`### ${t.textContent}`;case"H4":return`#### ${t.textContent}`;case"H5":return`##### ${t.textContent}`;case"H6":return`###### ${t.textContent}`;case"P":return t.textContent;case"DIV":return Array.from(t.childNodes).map((t=>n(t))).join("\n")+"\n\n";default:return Array.from(t.childNodes).map((t=>n(t))).join("")}};return t.nodeType===Node.ELEMENT_NODE?e+=n(t):t.nodeType===Node.TEXT_NODE&&""!==t.textContent.trim()&&(e+=t.textContent.trim()),e.trim()}async Submit(t,e=!1){let n=null;this.firstMulti=!0,(this.firstOpen||"gemini"==constants.LLMModel)&&!e&&constants.verboseText.length>0&&(t="Here is the current position in the chart; no response necessarily needed, use this info only if it's relevant to future questions: "+constants.verboseText+". My question is: "+t,this.firstOpen=!1),constants.playLLMWaitingSound&&this.WaitingSound(!0),(constants.LLMOpenAiMulti||"openai"==constants.LLMModel)&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"openai")),chatLLM.OpenAIPrompt(t,n)),(constants.LLMGeminiMulti||"gemini"==constants.LLMModel)&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"gemini")),chatLLM.GeminiPrompt(t,n))}WaitingSound(t=!0){if(constants.waitingInterval&&(clearInterval(constants.waitingInterval),constants.waitingSound=null),constants.waitingSoundOverride&&(clearTimeout(constants.waitingSoundOverride),constants.waitingSoundOverride=null),t){let t=1e3,e=440;constants.waitingInterval=setInterval((function(){audio&&chatLLM.shown&&audio.playOscillator(e,.2,0)}),t),constants.waitingSoundOverride=setTimeout((function(){chatLLM.WaitingSound(!1)}),3e4)}}InitChatMessage(){let t=resources.GetString(constants.LLMModel);this.firstTime=!1,this.DisplayChatMessage(t,resources.GetString("processing"),!0);let e=this.GetDefaultPrompt();this.Submit(e,!0)}ProcessLLMResponse(t,e){chatLLM.WaitingSound(!1);let n="",s=resources.GetString(e);if("openai"==e){n=t.choices[0].message.content;let e=this.requestJson.messages.length;this.requestJson.messages[e]={},this.requestJson.messages[e].role="assistant",this.requestJson.messages[e].content=n,t.error?chatLLM.DisplayChatMessage(s,"Error processing request.",!0):chatLLM.DisplayChatMessage(s,n)}else"gemini"==e&&(t.text()?(n=t.text(),chatLLM.DisplayChatMessage(s,n)):t.error||(t.error="Error processing request."),t.error&&chatLLM.DisplayChatMessage(s,"Error processing request.",!0));if(constants.isTracking){let t=chatLLM.CopyChatHistory();tracker.SetData("ChatHistory",t)}}fakeLLMResponseData(){let t={};return t=this.requestJson.messages.length>2?{id:"chatcmpl-8Y44iRCRrohYbAqm8rfBbJqTUADC7",object:"chat.completion",created:1703129508,model:"gpt-4-1106-vision-preview",usage:{prompt_tokens:451,completion_tokens:16,total_tokens:467},choices:[{message:{role:"assistant",content:"A fake response from the LLM. Nice."},finish_reason:"length",index:0}]}:{id:"chatcmpl-8Y44iRCRrohYbAqm8rfBbJqTUADC7",object:"chat.completion",created:1703129508,model:"gpt-4-1106-vision-preview",usage:{prompt_tokens:451,completion_tokens:16,total_tokens:467},choices:[{message:{role:"assistant",content:"The chart you're referring to is a bar graph titled \"The Number of Diamonds"},finish_reason:"length",index:0}]},t}OpenAIPrompt(t,e=null){let n=constants.openAIAuthKey,s=chatLLM.OpenAIJson(t,e);console.log("LLM request: ",s),fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+n},body:JSON.stringify(s)}).then((t=>t.json())).then((t=>{chatLLM.ProcessLLMResponse(t,"openai")})).catch((t=>{chatLLM.WaitingSound(!1),console.error("Error:",t),chatLLM.DisplayChatMessage(LLMName,"Error processing request.",!0)}))}OpenAIJson(t,e=null){let n=constants.LLMSystemMessage;singleMaidr.type;this.requestJson||(this.requestJson={},this.requestJson.model="gpt-4-vision-preview",this.requestJson.max_tokens=constants.LLMmaxResponseTokens,this.requestJson.messages=[],this.requestJson.messages[0]={},this.requestJson.messages[0].role="system",this.requestJson.messages[0].content=n,constants.LLMPreferences&&(this.requestJson.messages[1]={},this.requestJson.messages[1].role="system",this.requestJson.messages[1].content=constants.LLMPreferences));let s=this.requestJson.messages.length;return this.requestJson.messages[s]={},this.requestJson.messages[s].role="user",this.requestJson.messages[s].content=e?[{type:"text",text:t},{type:"image_url",image_url:{url:e}}]:t,this.requestJson}async GeminiPrompt(t,e=null){try{null==e?e=constants.LLMImage:constants.LLMImage=e,constants.LLMImage=e;const{GoogleGenerativeAI:n}=await import("https://esm.run/@google/generative-ai"),s=constants.geminiAuthKey,o=new n(s).getGenerativeModel({model:"gemini-pro-vision"});let i=constants.LLMSystemMessage;constants.LLMPreferences&&(i+=constants.LLMPreferences),i+="\n\n"+t;const a={inlineData:{data:e,mimeType:"image/png"}};console.log("LLM request: ",i,a);const l=await o.generateContent([i,a]);console.log(l.response.text()),chatLLM.ProcessLLMResponse(l.response,"gemini")}catch(t){throw console.error("Error in GeminiPrompt:",t),t}}DisplayChatMessage(t="User",e="",n=!1){let s="h3";if(!n&&"multi"==constants.LLMModel&&"User"!=t){if(this.firstMulti){let t=`\n <div class="chatLLM_message chatLLM_message_other">\n <h3 class="chatLLM_message_user">${resources.GetString("multi")} Responses</h3>\n </div>\n `;this.RenderChatMessage(t),this.firstMulti=!1}s="h4"}let o=`\n <div class="chatLLM_message ${"User"==t?"chatLLM_message_self":"chatLLM_message_other"}">\n <${s} class="chatLLM_message_user">${t}</${s}>\n <p class="chatLLM_message_text">${e}</p>\n </div>\n `;"User"!=t&&e!=resources.GetString("processing")&&(o+='\n <p class="chatLLM_message_copy"><button class="chatLLM_message_copy_button">Copy</button></p>\n '),this.RenderChatMessage(o)}RenderChatMessage(t){document.getElementById("chatLLM_chat_history").insertAdjacentHTML("beforeend",t),document.getElementById("chatLLM_input").value="",document.getElementById("chatLLM_chat_history").scrollTop=document.getElementById("chatLLM_chat_history").scrollHeight}ResetLLM(){document.getElementById("chatLLM_chat_history").innerHTML="",document.getElementById("more_suggestions_container").classList.add("hidden"),document.getElementById("more_suggestions").classList.remove("hidden"),this.requestJson=null,this.firstTime=!0,(constants.autoInitLLM||chatLLM.shown)&&chatLLM.InitChatMessage()}Destroy(){let t=document.getElementById("chatLLM");t&&t.remove();let e=document.getElementById("chatLLM_modal_backdrop");e&&e.remove()}Toggle(t){void 0===t&&(t=!!document.getElementById("chatLLM").classList.contains("hidden")),chatLLM.shown=t,t?(this.whereWasMyFocus=document.activeElement,constants.tabMovement=0,document.getElementById("chatLLM").classList.remove("hidden"),document.getElementById("chatLLM_modal_backdrop").classList.remove("hidden"),document.querySelector("#chatLLM .close").focus(),this.firstTime&&this.InitChatMessage()):(document.getElementById("chatLLM").classList.add("hidden"),document.getElementById("chatLLM_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null,this.firstOpen=!0)}async ConvertSVGtoJPG(t,e){let n=document.getElementById(t);return new Promise(((t,s)=>{var o=document.createElement("canvas"),i=o.getContext("2d"),a=(new XMLSerializer).serializeToString(n);a.startsWith("<svg xmlns")||(a=`<svg xmlns="http://www.w3.org/2000/svg" ${a.slice(4)}`);var l=n.viewBox.baseVal||n.getBoundingClientRect();o.width=l.width,o.height=l.height;var r=new Image;r.onload=function(){i.drawImage(r,0,0,l.width,l.height);var n=o.toDataURL("image/jpeg",.9);if("openai"==e)t(n);else if("gemini"==e){let e=n.split(",")[1];t(e)}URL.revokeObjectURL(p)},r.onerror=function(){s(new Error("Error loading SVG"))};var c=new Blob([a],{type:"image/svg+xml;charset=utf-8"}),p=URL.createObjectURL(c);r.src=p}))}GetDefaultPrompt(){let t="Describe this chart to a blind person";return constants.skillLevel?"other"==constants.skillLevel&&constants.skillLevelOther?t+=" who has a "+constants.skillLevelOther+" understanding of statistical charts. ":t+=" who has a "+constants.skillLevel+" understanding of statistical charts. ":t+=" who has a basic understanding of statistical charts. ",t+="Here is chart in png format",singleMaidr&&(t+=" and raw data in json format: \n",t+=JSON.stringify(singleMaidr)),t}}class Description{constructor(){}CreateComponent(){document.querySelector("body").insertAdjacentHTML("beforeend",'\n <div id="description" class="modal hidden" role="dialog" tabindex="-1">\n <div class="modal-dialog" role="document" tabindex="0">\n <div class="modal-content">\n <div class="modal-header">\n <h2 id="desc_title" class="modal-title">Description</h2>\n <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n <div class="modal-body">\n <div id="desc_content">\n content here\n </div>\n <div id="desc_table">\n </div>\n </div>\n <div class="modal-footer">\n <button type="button" id="close_desc">Close</button>\n </div>\n </div>\n </div>\n </div>\n <div id="desc_modal_backdrop" class="modal-backdrop hidden"></div>\n\n ');let t=document.querySelectorAll("#close_desc, #description .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){description.Toggle(!1)}]);constants.events.push([document.getElementById("description"),"keyup",function(t){"Esc"==t.key&&description.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){"d"==t.key&&description.Toggle(!0)}])}Destroy(){let t=document.getElementById("menu");t&&t.remove();let e=document.getElementById("desc_modal_backdrop");e&&e.remove()}Toggle(t=!1){void 0===t&&(t=!!document.getElementById("description").classList.contains("hidden")),t?(this.whereWasMyFocus=document.activeElement,constants.tabMovement=0,this.PopulateData(),document.getElementById("description").classList.remove("hidden"),document.getElementById("desc_modal_backdrop").classList.remove("hidden"),document.querySelector("#description .close").focus()):(document.getElementById("description").classList.add("hidden"),document.getElementById("desc_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null)}PopulateData(){let t="",e="";"bar"==constants.chartType?e="Bar chart":"heat"==constants.chartType?e="Heatmap":"box"==constants.chartType?e="Box plot":"scatter"==constants.chartType?e="Scatter plot":"line"==constants.chartType?e="Line chart":"hist"==constants.chartType&&(e="Histogram"),e&&(t+=`<p>Type: ${e}</p>`),null!=plot.title&&(t+=`<p>Title: ${plot.title}</p>`),null!=plot.subtitle&&(t+=`<p>Subtitle: ${plot.subtitle}</p>`),null!=plot.caption&&(t+=`<p>Caption: ${plot.caption}</p>`);let n="",s=null,o=null,i=null,a=null,l=0,r=0,c=0,p=0;if("bar"==constants.chartType&&(null!=plot.plotLegend.x&&(s=plot.plotLegend.x,r+=1),null!=plot.plotLegend.y&&(o=plot.plotLegend.y,p+=1),null!=plot.columnLabels&&(i=plot.columnLabels,p+=1),null!=plot.plotData&&(a=[],a[0]=plot.plotData,l=plot.plotData.length,c=1,r+=l,p+=c)),null!=a){if(n+="<table>",null!=s||null!=i){if(n+="<thead>",null!=s&&(n+="<tr>",null!=o&&(n+="<td></td>"),n+=`<th scope="col" colspan="${l}">${s}</th>`,n+="</tr>"),null!=i){n+="<tr>",null!=o&&(n+="<td></td>");for(let t=0;t<l;t++)n+=`<th scope="col">${i[t]}</th>`;n+="</tr>"}n+="</thead>"}if(c>0){n+="<tbody>";for(let t=0;t<c;t++){n+="<tr>",null!=o&&0==t&&(n+=`<th scope="row" rowspan="${c}">${o}</th>`);for(let e=0;e<l;e++)n+=`<td>${a[t][e]}</td>`;n+="</tr>"}n+="</tbody>"}n+="</table>"}document.getElementById("desc_title").innerHTML=e+" description",document.getElementById("desc_content").innerHTML=t,document.getElementById("desc_table").innerHTML=n}}class Position{constructor(t=0,e=0,n=-1){this.x=t,this.y=e,this.z=n}}class Helper{static containsObject(t,e){for(let n=0;n<e.length;n++)if(e[n]===t)return!0;return!1}}class Tracker{constructor(){this.DataSetup(),constants.isTracking=!0}DataSetup(){if(this.GetTrackerData());else{let t={};t.userAgent=Object.assign(navigator.userAgent),t.vendor=Object.assign(navigator.vendor),t.language=Object.assign(navigator.language),t.platform=Object.assign(navigator.platform),t.events=[],t.settings=[],this.SaveTrackerData(t),this.SaveSettings()}}DownloadTrackerData(){let t=document.createElement("a"),e=this.GetTrackerData(),n=new Blob([JSON.stringify(e)],{type:"text/plain"});t.href=URL.createObjectURL(n),t.download="tracking.json",t.click()}SaveTrackerData(t){localStorage.setItem(constants.project_id,JSON.stringify(t))}GetTrackerData(){return JSON.parse(localStorage.getItem(constants.project_id))}Delete(){localStorage.removeItem(constants.project_id),this.data=null,constants.debugLevel>0&&console.log("tracking data cleared"),this.DataSetup()}SaveSettings(){let t=JSON.parse(localStorage.getItem("settings_data"));t.openAIAuthKey="hidden",t.geminiAuthKey="hidden",this.SetData("settings",t)}LogEvent(t){let e={};if(e.timestamp=Object.assign(t.timeStamp),e.time=Date().toString(),e.key=Object.assign(t.key),e.altKey=Object.assign(t.altKey),e.ctrlKey=Object.assign(t.ctrlKey),e.shiftKey=Object.assign(t.shiftKey),t.path&&(e.focus=Object.assign(t.path[0].tagName)),this.isUndefinedOrNull(constants.position)||(e.position=Object.assign(constants.position)),this.isUndefinedOrNull(constants.minX)||(e.min_x=Object.assign(constants.minX)),this.isUndefinedOrNull(constants.maxX)||(e.max_x=Object.assign(constants.maxX)),this.isUndefinedOrNull(constants.minY)||(e.min_y=Object.assign(constants.minY)),this.isUndefinedOrNull(constants.MAX_FREQUENCY)||(e.max_frequency=Object.assign(constants.MAX_FREQUENCY)),this.isUndefinedOrNull(constants.MIN_FREQUENCY)||(e.min_frequency=Object.assign(constants.MIN_FREQUENCY)),this.isUndefinedOrNull(constants.NULL_FREQUENCY)||(e.null_frequency=Object.assign(constants.NULL_FREQUENCY)),this.isUndefinedOrNull(constants.MAX_SPEED)||(e.max_speed=Object.assign(constants.MAX_SPEED)),this.isUndefinedOrNull(constants.MIN_SPEED)||(e.min_speed=Object.assign(constants.MIN_SPEED)),this.isUndefinedOrNull(constants.INTERVAL)||(e.interval=Object.assign(constants.INTERVAL)),this.isUndefinedOrNull(constants.vol)||(e.volume=Object.assign(constants.vol)),this.isUndefinedOrNull(constants.autoPlayRate)||(e.autoplay_rate=Object.assign(constants.autoPlayRate)),this.isUndefinedOrNull(constants.colorSelected)||(e.color=Object.assign(constants.colorSelected)),this.isUndefinedOrNull(constants.brailleDisplayLength)||(e.braille_display_length=Object.assign(constants.brailleDisplayLength)),this.isUndefinedOrNull(constants.duration)||(e.tone_duration=Object.assign(constants.duration)),this.isUndefinedOrNull(constants.autoPlayOutlierRate)||(e.autoplay_outlier_rate=Object.assign(constants.autoPlayOutlierRate)),this.isUndefinedOrNull(constants.autoPlayPointsRate)||(e.autoplay_points_rate=Object.assign(constants.autoPlayPointsRate)),this.isUndefinedOrNull(constants.textMode)||(e.text_mode=Object.assign(constants.textMode)),this.isUndefinedOrNull(constants.sonifMode)||(e.sonification_mode=Object.assign(constants.sonifMode)),this.isUndefinedOrNull(constants.brailleMode)||(e.braille_mode=Object.assign(constants.brailleMode)),this.isUndefinedOrNull(constants.chartType)||(e.chart_type=Object.assign(constants.chartType)),!this.isUndefinedOrNull(constants.infoDiv.innerHTML)){let t=Object.assign(constants.infoDiv.innerHTML);t=t.replaceAll(/<[^>]*>?/gm,""),e.text_display=t}this.isUndefinedOrNull(location.href)||(e.location=Object.assign(location.href));let n="",s="",o="",i="",a="",l="";if("bar"==constants.chartType)this.isUndefinedOrNull(plot.columnLabels[position.x])||(n=plot.columnLabels[position.x]),this.isUndefinedOrNull(plot.plotLegend.x)||(o=plot.plotLegend.x),this.isUndefinedOrNull(plot.plotLegend.y)||(i=plot.plotLegend.y),this.isUndefinedOrNull(plot.plotData[position.x])||(a=plot.plotData[position.x]);else if("heat"==constants.chartType)this.isUndefinedOrNull(plot.x_labels[position.x])||(n=plot.x_labels[position.x].trim()),this.isUndefinedOrNull(plot.y_labels[position.y])||(s=plot.y_labels[position.y].trim()),this.isUndefinedOrNull(plot.x_group_label)||(o=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),this.isUndefinedOrNull(plot.values)||this.isUndefinedOrNull(plot.values[position.x][position.y])||(a=plot.values[position.x][position.y]),this.isUndefinedOrNull(plot.group_labels[2])||(l=plot.group_labels[2]);else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.x:position.y,e="vert"==constants.plotOrientation?position.y:position.x;this.isUndefinedOrNull(plot.x_group_label)||(o=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),"vert"==constants.plotOrientation?t>-1&&e>-1&&(this.isUndefinedOrNull(plot.plotData[t][e].label)||(s=plot.plotData[t][e].label),this.isUndefinedOrNull(plot.x_labels[position.x])||(n=plot.x_labels[position.x]),this.isUndefinedOrNull(plot.plotData[t][e].values)?this.isUndefinedOrNull(plot.plotData[t][e].y)||(a=plot.plotData[t][e].y):a=plot.plotData[t][e].values):t>-1&&e>-1&&(this.isUndefinedOrNull(plot.plotData[t][e].label)||(n=plot.plotData[t][e].label),this.isUndefinedOrNull(plot.y_labels[position.y])||(s=plot.y_labels[position.y]),this.isUndefinedOrNull(plot.plotData[t][e].values)?this.isUndefinedOrNull(plot.plotData[t][e].x)||(a=plot.plotData[t][e].x):a=plot.plotData[t][e].values)}else"point"==constants.chartType&&(this.isUndefinedOrNull(plot.x_group_label)||(o=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),this.isUndefinedOrNull(plot.x[position.x])||(n=plot.x[position.x]),this.isUndefinedOrNull(plot.y[position.x])||(s=plot.y[position.x]),a=[n,s]);e.x_tickmark=Object.assign(n),e.y_tickmark=Object.assign(s),e.x_label=Object.assign(o),e.y_label=Object.assign(i),e.value=Object.assign(a),e.fill_value=Object.assign(l),this.SetData("events",e)}SetData(t,e){let n=this.GetTrackerData();["events","ChatHistory","settings"].includes(t)?(n[t]||(n[t]=[]),n[t].push(e)):n[t]=e,this.SaveTrackerData(n)}isUndefinedOrNull(t){try{return null==t}catch{return!0}}}class Review{constructor(){}ToggleReviewMode(t=!0){t?(constants.reviewSaveSpot=document.activeElement,constants.review_container.classList.remove("hidden"),constants.reviewSaveBrailleMode=constants.brailleMode,constants.review.focus(),display.announceText("Review on")):(constants.review_container.classList.add("hidden"),"on"==constants.reviewSaveBrailleMode?display.toggleBrailleMode("on"):constants.reviewSaveSpot.focus(),display.announceText("Review off"))}}class LogError{constructor(){}LogAbsentElement(t){console.log(t,"not found. Visual highlighting is turned off.")}LogCriticalElement(t){consolelog(t,"is critical. MAIDR unable to run")}LogDifferentLengths(t,e){console.log(t,"and",e,"do not have the same length. Visual highlighting is turned off.")}LogTooManyElements(t,e){console.log("Too many",t,"elements. Only the first",e,"will be highlighted.")}LogNotArray(t){console.log(t,"is not an array. Visual highlighting is turned off.")}}class Audio{constructor(){this.AudioContext=window.AudioContext||window.webkitAudioContext,this.audioContext=new AudioContext,this.compressor=this.compressorSetup(this.audioContext)}compressorSetup(){let t=this.audioContext.createDynamicsCompressor();t.threshold.value=-50,t.knee.value=40,t.ratio.value=12,t.attack.value=0,t.release.value=.25;let e=this.audioContext.createGain();return e.gain.value=constants.vol,t.connect(e),e.connect(this.audioContext.destination),t}playTone(t=null){let e=constants.duration,n=constants.vol;null!=t&&null!=t.volScale&&(n=t.volScale*constants.vol);let s=0,o=0,i=0,a=0,l="sine";if("bar"==constants.chartType)o=plot.plotData[position.x],s=position.x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1);else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.x:position.y,e=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);o=Array.isArray(plot.plotData[t][e])?plot.plotData[t][e][position.z]:plot.plotData[t][e],null!=plot.plotData[t][e]?"vert"==constants.plotOrientation?(i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(o,constants.minY,constants.maxY,-1,1)):(i=this.SlideBetween(o,constants.minX,constants.maxX,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(o,constants.minX,constants.maxX,-1,1)):(i=constants.MIN_FREQUENCY,a=0)}else if("heat"==constants.chartType)o=plot.data[position.y][position.x],s=position.x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1);else if("point"==constants.chartType||"smooth"==constants.chartType){constants.globalMinMax=!0;let t=constants.minY,e=constants.maxY;"smooth"==constants.chartType&&(t=plot.curveMinY,e=plot.curveMaxY),constants.globalMinMax&&(t=Math.min(constants.minY,plot.curveMinY),e=Math.max(constants.maxY,plot.curveMaxY)),"point"==constants.chartType?(o=plot.y[position.x][position.z],n=1==plot.max_count?constants.vol:this.SlideBetween(plot.points_count[position.x][position.z],1,plot.max_count,constants.vol,constants.MAX_VOL),s=position.x,i=this.SlideBetween(o,t,e,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,t,e,-1,1)):"smooth"==constants.chartType&&(o=plot.curvePoints[positionL1.x],s=positionL1.x,i=this.SlideBetween(o,t,e,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,t,e,-1,1))}else if("hist"==constants.chartType)o=plot.plotData[position.x].y,s=plot.plotData[position.x].x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1);else if("line"==constants.chartType)o=plot.pointValuesY[position.x],s=position.x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1);else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType){if(o=plot.plotData[position.x][position.y],0==o)return void this.PlayNull();Array.isArray(o)&&(o=o[position.z]),s=position.x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1),l=["triangle","square","sawtooth","sine"][position.y]}if(constants.debugLevel>5&&(console.log("will play tone at freq",i),"box"==constants.chartType?console.log("based on",constants.minY,"<",o,"<",constants.maxY," | freq min",constants.MIN_FREQUENCY,"max",constants.MAX_FREQUENCY):console.log("based on",constants.minX,"<",o,"<",constants.maxX," | freq min",constants.MIN_FREQUENCY,"max",constants.MAX_FREQUENCY)),"box"==constants.chartType){let t=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);"lower_outlier"!=t&&"upper_outlier"!=t||(e=constants.outlierDuration)}if(this.playOscillator(i,e,a,n,l),"box"==constants.chartType){let t=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);if("q1"==t||"q2"==t||"q3"==t){let t=i/2;this.playOscillator(t,e,a,constants.vol/4,"triangle")}}else"heat"==constants.chartType&&0==o&&this.PlayNull()}playOscillator(t,e,n,s=1,o="sine"){const i=this.audioContext.currentTime,a=this.audioContext.createOscillator();a.type=o,a.frequency.value=parseFloat(t),a.start();const l=this.audioContext.createGain();l.gain.setValueCurveAtTime([.5*s,1*s,.5*s,.5*s,.5*s,.1*s,1e-4*s],i,e);const r=new PannerNode(this.audioContext,{panningModel:"HRTF",distanceModel:"linear",positionX:position.x,positionY:position.y,positionZ:1,plotOrientationX:0,plotOrientationY:0,plotOrientationZ:-1,refDistance:1,maxDistance:1e4,rolloffFactor:10,coneInnerAngle:40,coneOuterAngle:50,coneOuterGain:.4}),c=this.audioContext.createStereoPanner();c.pan.value=n,a.connect(l),l.connect(c),c.connect(r),r.connect(this.compressor),setTimeout((()=>{r.disconnect(),l.disconnect(),a.stop(),a.disconnect()}),1e3*e*2)}playSmooth(t=[600,500,400,300],e=2,n=[-1,0,1],s=1,o="sine"){let i=new Array(3*t.length).fill(.5*s);i.push(1e-4*s);const a=this.audioContext.currentTime,l=this.audioContext.createOscillator();l.type=o,l.frequency.setValueCurveAtTime(t,a,e),l.start(),constants.isSmoothAutoplay=!0,this.smoothGain=this.audioContext.createGain(),this.smoothGain.gain.setValueCurveAtTime(i,a,e);const r=new PannerNode(this.audioContext,{panningModel:"HRTF",distanceModel:"linear",positionX:position.x,positionY:position.y,positionZ:1,plotOrientationX:0,plotOrientationY:0,plotOrientationZ:-1,refDistance:1,maxDistance:1e4,rolloffFactor:10,coneInnerAngle:40,coneOuterAngle:50,coneOuterGain:.4}),c=this.audioContext.createStereoPanner();c.pan.setValueCurveAtTime(n,a,e),l.connect(this.smoothGain),this.smoothGain.connect(c),c.connect(r),r.connect(this.compressor),constants.smoothId=setTimeout((()=>{r.disconnect(),this.smoothGain.disconnect(),l.stop(),l.disconnect(),constants.isSmoothAutoplay=!1}),1e3*e*2)}PlayNull(){let t=constants.NULL_FREQUENCY,e=constants.duration,n=constants.vol,s="triangle";this.playOscillator(t,e,0,n,s),setTimeout((function(o){o.playOscillator(23*t/24,e,0,n,s)}),Math.round(e/5*1e3),this)}playEnd(){if(constants.canPlayEndChime){let t=constants.endChime.cloneNode(!0);t.play(),t=null}}KillSmooth(){constants.smoothId&&(this.smoothGain.gain.cancelScheduledValues(0),this.smoothGain.gain.exponentialRampToValueAtTime(1e-4,this.audioContext.currentTime+.03),clearTimeout(constants.smoothId),constants.isSmoothAutoplay=!1)}SlideBetween(t,e,n,s,o){t=Number(t),e=Number(e),n=Number(n),s=Number(s);let i=(t-e)/(n-e)*((o=Number(o))-s)+s;return 0==e&&0==n&&(i=0),i}}class Display{constructor(){this.infoDiv=constants.infoDiv,this.x={},this.x.id="x",this.x.textBase="x-value: ",this.y={},this.y.id="y",this.y.textBase="y-value: ",this.boxplotGridPlaceholders=[resources.GetString("lower_outlier"),resources.GetString("min"),resources.GetString("25"),resources.GetString("50"),resources.GetString("75"),resources.GetString("max"),resources.GetString("upper_outlier")]}toggleTextMode(){"off"==constants.textMode?constants.textMode="terse":"terse"==constants.textMode?constants.textMode="verbose":"verbose"==constants.textMode&&(constants.textMode="off"),this.announceText('<span aria-hidden="true">Text mode:</span> '+constants.textMode)}toggleBrailleMode(t){if(position.x<0&&(position.x=0),position.y<0&&(position.y=0),"point"!=constants.chartType){if(void 0===t&&(void 0===constants.brailleMode?(constants.brailleMode="off",t="on"==constants.brailleMode):(t="on"==constants.brailleMode?"off":"on",constants.brailleMode=t)),"on"==t){if("box"==constants.chartType&&("vert"!=constants.plotOrientation&&-1==position.x&&position.y==plot.plotData.length?(position.x+=1,position.y-=1):"vert"==constants.plotOrientation&&0==position.x&&(position.y,plot.plotData[0].length)),constants.brailleMode="on",document.getElementById(constants.braille_container_id).classList.remove("hidden"),constants.brailleInput.focus(),constants.brailleInput.setSelectionRange(position.x,position.x),this.SetBraille(),"heat"==constants.chartType){let t=position.y*(plot.num_cols+1)+position.x;constants.brailleInput.setSelectionRange(t,t)}-1==position.x&&-1==position.y&&constants.brailleInput.setSelectionRange(0,0)}else constants.brailleMode="off",document.getElementById(constants.braille_container_id).classList.add("hidden"),constants.review_container?constants.review_container.classList.contains("hidden")?constants.chart.focus():constants.review.focus():constants.chart.focus();this.announceText("Braille "+constants.brailleMode)}else this.announceText("Braille is not supported in point layer.")}toggleSonificationMode(){"point"==constants.chartType||"stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType?"off"==constants.sonifMode?(constants.sonifMode="on",this.announceText(resources.GetString("son_sep"))):"on"==constants.sonifMode?(constants.sonifMode="same",this.announceText(resources.GetString("son_same"))):"same"==constants.sonifMode&&(constants.sonifMode="off",this.announceText(resources.GetString("son_off"))):"off"==constants.sonifMode?(constants.sonifMode="on",this.announceText(resources.GetString("son_on"))):(constants.sonifMode="off",this.announceText(resources.GetString("son_off")))}changeChartLayer(t="down"){let e=maidr.type;if(Array.isArray(e)){let n=e.indexOf(constants.chartType);"down"==t?0==n||(constants.chartType=e[n-1],this.announceText("Switched to "+constants.chartType)):n==e.length-1||(constants.chartType=e[n+1],this.announceText("Switched to "+constants.chartType))}"point"==constants.chartType?position.x=Math.round((plot.x.length-1)*positionL1.x/(plot.curvePoints.length-1)):"smooth"==constants.chartType&&(positionL1.x=Math.round((plot.curvePoints.length-1)*position.x/(plot.x.length-1)))}announceText(t){this.displayInfo("announce",t,constants.announceContainer)}UpdateBraillePos(){if("bar"==constants.chartType||"hist"==constants.chartType||"line"==constants.chartType)constants.brailleInput.setSelectionRange(position.x,position.x);else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType){let t=null;t=position.y<plot.plotData[0].length-1?position.x:position.x*(plot.fill.length+1)+position.y,constants.brailleInput.setSelectionRange(t,t)}else if("heat"==constants.chartType){let t=position.y*(plot.num_cols+1)+position.x;constants.brailleInput.setSelectionRange(t,t)}else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.y:position.x,e=this.boxplotGridPlaceholders[t],n=!1,s=0;if(!constants.brailleData)throw"Braille data not set up, cannot move cursor in braille, sorry.";for(let t=0;t<constants.brailleData.length;t++){if("blank"!=constants.brailleData[t].type&&resources.GetString(constants.brailleData[t].type)==e){n=!0;break}s+=constants.brailleData[t].numChars}n||(s=0),constants.brailleInput.setSelectionRange(s,s)}else("smooth"==singleMaidr.type||singleMaidr.type.includes("smooth"))&&constants.brailleInput.setSelectionRange(positionL1.x,positionL1.x)}displayValues(){let t="",e="",n="";if("bar"==constants.chartType)plot.columnLabels[position.x]&&(plot.plotLegend.x.length>0&&(e+=plot.plotLegend.x+" is "),e+=plot.columnLabels[position.x]+", "),plot.plotData[position.x]&&(plot.plotLegend&&(e+=plot.plotLegend.y+" is "),e+=plot.plotData[position.x]),n+="<p>"+plot.columnLabels[position.x]+" "+plot.plotData[position.x]+"</p>\n",e="<p>"+e+"</p>\n";else if("heat"==constants.chartType)1==constants.navigation?(e+=plot.x_group_label+" "+plot.x_labels[position.x]+", "+plot.y_group_label+" "+plot.y_labels[position.y]+", "+plot.fill+" is ",e+=plot.data[position.y][position.x]):(e+=plot.y_group_label+" "+plot.y_labels[position.y]+", "+plot.x_group_label+" "+plot.x_labels[position.x]+", "+plot.fill+" is ",e+=plot.data[position.y][position.x]),1==constants.navigation?n+="<p>"+plot.x_labels[position.x]+", "+plot.data[position.y][position.x]+"</p>\n":n+="<p>"+plot.y_labels[position.y]+", "+plot.data[position.y][position.x]+"</p>\n",e="<p>"+e+"</p>\n";else if("box"==constants.chartType){let t=0,s=1,o=!1,i="vert"==constants.plotOrientation?position.x:position.y,a=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);"lower_outlier"!=a&&"upper_outlier"!=a||(o=!0),null==plot.plotData[i][a]?(t="",o&&(s=0)):o?(t=plot.plotData[i][a].join(", "),s=plot.plotData[i][a].length):t=plot.plotData[i][a],constants.navigation?plot.x_group_label&&(e+=plot.x_group_label):constants.navigation||plot.y_group_label&&(e+=plot.y_group_label),constants.navigation?plot.x_labels[i]?(e+=" is ",n+=plot.x_labels[i]+", ",e+=plot.x_labels[i]+", "):e+=", ":constants.navigation||(plot.y_labels[i]?(e+=" is ",n+=plot.y_labels[i]+", ",e+=plot.y_labels[i]+", "):e+=", "),o&&(n+=s+" ",e+=s+" "),e+=resources.GetString(a),1==s?e+=" is ":(e+="s ",s>1&&(e+=" are ")),(o||constants.navigation&&"horz"==constants.plotOrientation||!constants.navigation&&"vert"==constants.plotOrientation)&&(n+=resources.GetString(a),1!=s&&(n+="s"),n+=" "),null!=plot.plotData[i][a]||o?(n+=t,e+=t):(n+="empty",e+="empty"),e="<p>"+e+"</p>\n",n="<p>"+n+"</p>\n"}else[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")?("point"==constants.chartType?(e+=plot.x_group_label+" "+plot.x[position.x]+", "+plot.y_group_label+" ["+plot.y[position.x].join(", ")+"]",n+="<p>"+plot.x[position.x]+", ["+plot.y[position.x].join(", ")+"]</p>\n"):"smooth"==constants.chartType&&(e+=plot.x_group_label+" "+plot.curveX[positionL1.x]+", "+plot.y_group_label+" "+plot.curvePoints[positionL1.x],n+="<p>"+plot.curvePoints[positionL1.x]+"<p>\n"),e="<p>"+e+"</p>\n"):"hist"==constants.chartType?(n="<p>"+plot.plotData[position.x].x+", "+plot.plotData[position.x].y+"</p>\n",e="<p>",plot.legendX&&(e=plot.legendX+" is "),e+=plot.plotData[position.x].xmin,e+=" through "+plot.plotData[position.x].xmax+", ",plot.legendY&&(e+=plot.legendY+" is "),e+=plot.plotData[position.x].y):"line"==constants.chartType?(plot.plotLegend&&(e+=plot.plotLegend.x+" is "),e+=plot.pointValuesX[position.x]+", ",plot.plotLegend&&plot.plotLegend.y,e+=plot.pointValuesY[position.x],n+="<p>"+plot.pointValuesX[position.x]+", "+plot.pointValuesY[position.x]+"</p>\n",e="<p>"+e+"</p>\n"):"stacked_bar"!=constants.chartType&&"stacked_normalized_bar"!=constants.chartType&&"dodged_bar"!=constants.chartType||(plot.plotLegend&&(e+=plot.plotLegend.x+" is "),e+=plot.level[position.x]+", ",plot.plotLegend&&(e+=plot.plotLegend.y+" is "),e+=plot.fill[position.y]+", ",e+="value is "+plot.plotData[position.x][position.y],1==constants.navigation?n+="<p>"+plot.level[position.x]+" is "+plot.plotData[position.x][position.y]+"</p>\n":n+="<p>"+plot.fill[position.y]+" is "+plot.plotData[position.x][position.y]+"</p>\n",e="<p>"+e+"</p>\n");"verbose"==constants.textMode?t=e:"terse"==constants.textMode&&(t=n),constants.verboseText=e,constants.infoDiv&&(constants.infoDiv.innerHTML=t),constants.review&&(t.length>0?constants.review.value=t.replace(/<[^>]*>?/gm,""):constants.review.value=e)}displayInfo(t,e,n=constants.infoDiv){let s="";if("announce"==t)e&&(s=e);else if(t)if(e){if("terse"==constants.textMode)s=e;else if("verbose"==constants.textMode){s=t.charAt(0).toUpperCase()+t.slice(1)+" is "+e}}else{s="Plot does not have "+(["a","e","i","o","u"].includes(t.charAt(0))?"an":"a")+" "+t}if(s.length>0){n.innerHTML=null;let t=document.createElement("p");t.innerHTML=s,n.appendChild(t)}}SetBraille(){let t=[];if("heat"==constants.chartType){let e=(constants.maxY-constants.minY)/3,n=constants.minY+e,s=n+e;for(let e=0;e<plot.data.length;e++){for(let o=0;o<plot.data[e].length;o++)0==plot.data[e][o]?t.push("⠀"):plot.data[e][o]<=n?t.push("⠤"):plot.data[e][o]<=s?t.push("⠒"):t.push("⠉");t.push("⠳")}}else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType)if(position.y<plot.plotData[0].length-1){let e=null,n=null;for(let t=0;t<plot.plotData.length;t++)0==t?(e=plot.plotData[t][position.y],n=plot.plotData[t][position.y]):(plot.plotData[t][position.y]<e&&(e=plot.plotData[t][position.y]),plot.plotData[t][position.y]>n&&(n=plot.plotData[t][position.y]));let s=(n-e)/4,o=e+s,i=o+s,a=i+s;for(let e=0;e<plot.plotData.length;e++)0==plot.plotData[e][position.y]?t.push("⠀"):plot.plotData[e][position.y]<=o?t.push("⣀"):plot.plotData[e][position.y]<=i?t.push("⠤"):plot.plotData[e][position.y]<=a?t.push("⠒"):t.push("⠉")}else for(let e=0;e<plot.plotData.length;e++){let n=(constants.maxY-constants.minY)/4,s=constants.minY+n,o=s+n,i=o+n;for(let n=0;n<plot.plotData[e].length;n++)0==plot.plotData[e][n]?t.push("⠀"):plot.plotData[e][n]<=s?t.push("⣀"):plot.plotData[e][n]<=o?t.push("⠤"):plot.plotData[e][n]<=i?t.push("⠒"):t.push("⠉");t.push("⠳")}else if("bar"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,s=n+e,o=s+e;for(let e=0;e<plot.plotData.length;e++)plot.plotData[e]<=n?t.push("⣀"):plot.plotData[e]<=s?t.push("⠤"):plot.plotData[e]<=o?t.push("⠒"):t.push("⠉")}else if("smooth"==constants.chartType){let e=(plot.curveMaxY-plot.curveMinY)/4,n=plot.curveMinY+e,s=n+e,o=s+e,i=o+e;for(let e=0;e<plot.curvePoints.length;e++)plot.curvePoints[e]<=n?t.push("⣀"):plot.curvePoints[e]<=s?t.push("⠤"):plot.curvePoints[e]<=o?t.push("⠒"):plot.curvePoints[e]<=i&&t.push("⠉")}else if("hist"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,s=n+e,o=s+e;for(let e=0;e<plot.plotData.length;e++)plot.plotData[e].y<=n?t.push("⣀"):plot.plotData[e].y<=s?t.push("⠤"):plot.plotData[e].y<=o?t.push("⠒"):t.push("⠉")}else if("box"==constants.chartType&&position.y>-1){let e,n,s,o=plot.sections.length;"vert"==constants.plotOrientation?(e=position.x,n=constants.minY,s=constants.maxY):(e=position.y,n=constants.minX,s=constants.maxX);let i=[];i.push({type:"global_min",value:n});for(let t=0;t<o;t++){let n=plot.sections[t],s=plot.plotData[e][n],o={};if(null!=s)if("lower_outlier"==n||"upper_outlier"==n)for(let t=0;t<s.length;t++)o={type:n,value:s[t]},i.push(o);else o={type:n,value:s},i.push(o)}i.push({type:"global_max",value:s});let a=[],l=!0;for(let t=0;t<i.length;t++){let e;e=l?Math.abs(i[t+1].value-i[t].value):Math.abs(i[t].value-i[t-1].value),"global_min"==i[t].type||"global_max"==i[t].type?a.push({type:"blank",length:e}):"lower_outlier"==i[t].type?(a.push({type:i[t].type,length:0}),a.push({type:"blank",length:e})):"upper_outlier"==i[t].type?(a.push({type:"blank",length:e}),a.push({type:i[t].type,length:0})):"q2"==i[t].type?(l=!1,a.push({type:i[t].type,length:0})):a.push({type:i[t].type,length:e})}let r=-1,c=-1,p=-1,d=-1,h=0;for(let t=0;t<a.length;t++)"blank"!=a[t].type&&(a[t].length>0||"lower_outlier"==a[t].type||"upper_outlier"==a[t].type)?(a[t].numChars=1,h++):a[t].numChars=0,"min"==a[t].type&&a[t].length>0&&(r=t),"max"==a[t].type&&a[t].length>0&&(d=t),"q1"==a[t].type&&(c=t),"q3"==a[t].type&&(p=t),"q2"==a[t].type&&(a[t].numChars=2,h++);r>-1&&d>-1&&a[r].length!=a[d].length&&(a[r].length>a[d].length?(a[r].numChars++,h++):(a[d].numChars++,h++)),a[c].length!=a[p].length&&(a[c].length>a[p].length?(a[c].numChars++,h++):(a[p].numChars++,h++));let u=constants.brailleDisplayLength-h,y=this.AllocateCharacters(a,u),g=a;for(let t=0;t<y.length;t++)y[t]&&(g[t].numChars+=y[t]);constants.brailleData=g,constants.debugLevel>5&&(console.log("plotData[i]",plot.plotData[e]),console.log("valData",i),console.log("lenData",a),console.log("brailleData",g));for(let e=0;e<g.length;e++)for(let n=0;n<g[e].numChars;n++){let s="⠀";"min"==g[e].type||"max"==g[e].type?s="⠒":"q1"==g[e].type||"q3"==g[e].type?s="⠿":"q2"==g[e].type?s=0==n?"⠸":"⠇":"lower_outlier"!=g[e].type&&"upper_outlier"!=g[e].type||(s="⠂"),t.push(s)}}else if("line"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,s=n+e,o=s+e,i=o+e;for(let e=0;e<plot.pointValuesY.length;e++)plot.pointValuesY[e]<=n&&e-1>=0&&plot.pointValuesY[e-1]>n?plot.pointValuesY[e-1]<=s?t.push("⢄"):plot.pointValuesY[e-1]<=o?t.push("⢆"):plot.pointValuesY[e-1]>o&&t.push("⢇"):plot.pointValuesY[e]<=n?t.push("⣀"):e-1>=0&&plot.pointValuesY[e-1]<=n?plot.pointValuesY[e]<=s?t.push("⡠"):plot.pointValuesY[e]<=o?t.push("⡰"):plot.pointValuesY[e]>o&&t.push("⡸"):plot.pointValuesY[e]<=s&&e-1>=0&&plot.pointValuesY[e-1]>s?plot.pointValuesY[e-1]<=o?t.push("⠢"):plot.pointValuesY[e-1]>o&&t.push("⠣"):plot.pointValuesY[e]<=s?t.push("⠤"):e-1>=0&&plot.pointValuesY[e-1]<=s?plot.pointValuesY[e]<=o?t.push("⠔"):plot.pointValuesY[e]>o&&t.push("⠜"):plot.pointValuesY[e]<=o&&e-1>=0&&plot.pointValuesY[e-1]>o?t.push("⠑"):plot.pointValuesY[e]<=o?t.push("⠒"):e-1>=0&&plot.pointValuesY[e-1]<=o?t.push("⠊"):plot.pointValuesY[e]<=i&&t.push("⠉")}constants.brailleInput.value=t.join(""),constants.brailleInput.value=t.join(""),constants.debugLevel>5&&console.log("braille:",constants.brailleInput.value),this.UpdateBraillePos()}CharLenImpact(t){return t.length/t.numChars}AllocateCharacters(t,e){let n=[],s=0;for(let e=0;e<t.length;e++)s+=t[e].length;let o=["lower_outlier","upper_outlier","50"];for(let i=0;i<t.length;i++)o.includes(t[i].type)||(n[i]=Math.round(t[i].length/s*e));let i=n.reduce(((t,e)=>t+e),0),a=e-i,l=t.length;for(;0!==a&&l>0;){for(let e=0;e<t.length;e++)o.includes(t[e].type)||(n[e]+=Math.round(t[e].length/s*a));i=n.reduce(((t,e)=>t+e),0),a=e-i,l--}if(0!==a){let e=[];for(let n=0;n<t.length;n++)e.push(n);e.sort(((t,e)=>n[t]-n[e]));let s=-1;a>0&&(s=1);let o=0,i=3*e.length;for(;a>0&&i>0;)n[e[o]]+=s,a+=-s,o+=1,o>=e.length&&(o=0),i+=-1}return n}}class BarChart{constructor(){let t=null;"axes"in singleMaidr&&singleMaidr.axes.x&&singleMaidr.axes.x.level&&(t=singleMaidr.axes.x.level);let e=null;"data"in singleMaidr&&(e=singleMaidr.data);let n=null;"selector"in singleMaidr?n=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(n=singleMaidr.elements),t&&e&&n?n.length!=e.length?(constants.hasRect=0,logError.LogDifferentLengths("elements","data")):t.length!=n.length?(constants.hasRect=0,logError.LogDifferentLengths("x level","elements")):e.length!=t.length?(constants.hasRect=0,logError.LogDifferentLengths("x level","data")):(this.bars=n,constants.hasRect=1):e&&n?e.length!=n.length?(constants.hasRect=0,logError.LogDifferentLengths("data","elements")):(this.bars=n,constants.hasRect=1):t&&e?(t.length!=e.length&&(constants.hasRect=0,logError.LogDifferentLengths("x level","data")),logError.LogAbsentElement("elements")):e&&(logError.LogAbsentElement("x level"),logError.LogAbsentElement("elements")),this.columnLabels=[];let s="",o="";"labels"in singleMaidr&&("x"in singleMaidr.labels&&(s=singleMaidr.labels.x),"y"in singleMaidr.labels&&(o=singleMaidr.labels.y)),"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&""==s&&(s=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&""==o&&(o=singleMaidr.axes.y.label),singleMaidr.axes.x&&singleMaidr.axes.x.level&&(this.columnLabels=singleMaidr.axes.x.level),singleMaidr.axes.y&&singleMaidr.axes.y.level&&(this.columnLabels=singleMaidr.axes.y.level)),this.plotLegend={x:s,y:o},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),Array.isArray(singleMaidr)?this.plotData=singleMaidr:"data"in singleMaidr&&(this.plotData=singleMaidr.data),this.SetMaxMin(),this.autoplay=null}SetMaxMin(){for(let t=0;t<this.plotData.length;t++)0==t?(constants.maxY=this.plotData[t],constants.minY=this.plotData[t]):(this.plotData[t]>constants.maxY&&(constants.maxY=this.plotData[t]),this.plotData[t]<constants.minY&&(constants.minY=this.plotData[t]));constants.maxX=this.columnLabels.length,constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}PlayTones(){audio.playTone()}GetLegendFromManualData(){let t={};return t.x=barplotLegend.x,t.y=barplotLegend.y,t}GetData(){let t=[];if(this.bars)for(let e=0;e<this.bars.length;e++)t.push(this.bars[e].getAttribute("height"));return t}GetColumns(){let t=[],e=constants.chart.querySelectorAll('tspan[dy="10"]');for(var n=0;n<e.length;n++)t.push(e[n].innerHTML);return t}GetLegend(){let t={},e=constants.chart.querySelectorAll('tspan[dy="12"]');return t.x=e[1].innerHTML,t.y=e[0].innerHTML,t}ParseInnerHTML(t){let e=[];for(var n=0;n<t.length;n++)e.push(t[n].innerHTML);return e}Select(){if(this.UnSelectPrevious(),this.bars&&(this.activeElement=this.bars[position.x],this.activeElement))if(this.activeElement.hasAttribute("fill"))this.activeElementColor=this.activeElement.getAttribute("fill"),this.activeElement.setAttribute("fill",constants.GetBetterColor(this.activeElementColor));else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);this.activeElementColor=e[e.indexOf("fill")+1],e[e.indexOf("fill")+1]=constants.GetBetterColor(this.activeElementColor),t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t)}}UnSelectPrevious(){if(this.activeElement)if(this.activeElement.hasAttribute("fill"))this.activeElement.setAttribute("fill",this.activeElementColor),this.activeElement=null;else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);e[e.indexOf("fill")+1]=this.activeElementColor,t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t),this.activeElement=null}}}class BoxPlot{constructor(){if(this.sections=["lower_outlier","min","q1","q2","q3","max","upper_outlier"],constants.plotOrientation="horz","axes"in singleMaidr&&"x"in singleMaidr.axes&&"level"in singleMaidr.axes.x&&(constants.plotOrientation="vert"),this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),this.subtitle="","labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),this.caption="","labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),"labels"in singleMaidr&&(this.x_group_label||"x"in singleMaidr.labels&&(this.x_group_label=singleMaidr.labels.x),this.y_group_label||"y"in singleMaidr.labels&&(this.y_group_label=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&("label"in singleMaidr.axes.x&&(this.x_group_label||(this.x_group_label=singleMaidr.axes.x.label)),"level"in singleMaidr.axes.x?this.x_labels=singleMaidr.axes.x.level:this.x_labels=[]),"y"in singleMaidr.axes&&("label"in singleMaidr.axes.y&&(this.y_group_label||(this.y_group_label=singleMaidr.axes.y.label)),"level"in singleMaidr.axes.y?this.y_labels=singleMaidr.axes.y.level:this.y_labels=[])),this.plotData=singleMaidr.data,"selector"in singleMaidr){let t=document.querySelector(singleMaidr.selector);this.plotBounds=this.GetPlotBounds(t),constants.hasRect=!0}else"elements"in singleMaidr?(this.plotBounds=this.GetPlotBounds(singleMaidr.elements),constants.hasRect=!0):constants.hasRect=!1;this.CleanData()}CleanData(){let t,e;for(let n=0;n<this.plotData.length;n++){if(this.plotData[n].lower_outlier){let s=Math.min(...this.plotData[n].lower_outlier),o=Math.max(...this.plotData[n].lower_outlier);(null==t||s<t)&&(t=s),(null==e||o>e)&&(e=o)}if(this.plotData[n].min&&((null==t||this.plotData[n].min<t)&&(t=this.plotData[n].min),(null==e||this.plotData[n].max>e)&&(e=this.plotData[n].max)),this.plotData[n].q1&&((null==t||this.plotData[n].q1<t)&&(t=this.plotData[n].q1),(null==e||this.plotData[n].q1>e)&&(e=this.plotData[n].q1)),this.plotData[n].q2&&((null==t||this.plotData[n].q2<t)&&(t=this.plotData[n].q2),(null==e||this.plotData[n].q2>e)&&(e=this.plotData[n].q2)),this.plotData[n].q3&&((null==t||this.plotData[n].q3<t)&&(t=this.plotData[n].q3),(null==e||this.plotData[n].q3>e)&&(e=this.plotData[n].q3)),this.plotData[n].max&&((null==t||this.plotData[n].max<t)&&(t=this.plotData[n].max),(null==e||this.plotData[n].max>e)&&(e=this.plotData[n].max)),this.plotData[n].upper_outlier){let s=Math.min(...this.plotData[n].upper_outlier),o=Math.max(...this.plotData[n].upper_outlier);(null==t||s<t)&&(t=s),(null==e||o>e)&&(e=o)}}"vert"==constants.plotOrientation?(constants.minY=t,constants.maxY=e,constants.minX=0,constants.maxX=this.plotData.length-1):(constants.minX=t,constants.maxX=e,constants.minY=0,constants.maxY=this.plotData.length-1),constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/this.plotData.length),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}GetPlotBounds(t){let e=[],n=this.GetAllSegmentTypes(),s=/(?:\d+(?:\.\d*)?|\.\d+)/g,o=[],i=t.children;for(let t=0;t<i.length;t++){let e={},n=i[t].children;for(let t=0;t<n.length;t++){e[this.GetBoxplotSegmentType(n[t].getAttribute("id"))]=n[t]}o.push(e)}for(let t=0;t<o.length;t++){let i=[],a=o[t].range.getBoundingClientRect(),l=o[t].range.querySelector('polyline[id^="GRID"]').getAttribute("points").match(s),r=o[t].range.querySelector('polygon[id^="geom_polygon"]').getAttribute("points").match(s),c=0;c="vert"==constants.plotOrientation?(l[1]-r[3])/(r[1]-r[3]):(l[0]-r[2])/(r[0]-r[2]),c=Number.isNaN(c)?0:c;let p=0;if(p="vert"==constants.plotOrientation?a.height*c:a.width*c,i[2]=this.convertBoundingClientRectToObj(a),i[2].label=n[2],i[2].type="range","vert"==constants.plotOrientation?(i[2].height=p,i[2].top=i[2].bottom-p,i[2].y=i[2].top):i[2].width=p,i[3]=this.convertBoundingClientRectToObj(a),i[3].label=n[3],i[3].type="range","vert"==constants.plotOrientation?(i[3].height=0,i[3].top=a.bottom-p,i[3].y=i[3].top,i[3].bottom=i[3].top):(i[3].width=0,i[3].left=a.left+p),i[4]=this.convertBoundingClientRectToObj(a),i[4].label=n[4],i[4].type="range","vert"==constants.plotOrientation?(i[4].height=a.height-p,i[4].bottom=i[3].top):(i[4].width=a.width-p,i[4].left=i[3].left),Object.hasOwn(o[t],"whisker")){let e=o[t].whisker.getBoundingClientRect(),s=!1,l=!1;"vert"==constants.plotOrientation?(e.bottom>a.bottom&&(s=!0),e.top<a.top&&(l=!0)):(e.left<a.left&&(s=!0),e.right>a.right&&(l=!0)),s?(i[1]=this.convertBoundingClientRectToObj(e),i[1].label=n[1],i[1].type="whisker","vert"==constants.plotOrientation?(i[1].top=i[2].bottom,i[1].y=i[1].top,i[1].height=i[1].bottom-i[1].top):i[1].width=i[2].left-i[1].left):(i[1]={},i[1].label=n[1],i[1].type="blank"),l?(i[5]=this.convertBoundingClientRectToObj(e),i[5].label=n[5],i[5].type="whisker","vert"==constants.plotOrientation?(i[5].bottom=i[4].top,i[5].height=i[5].bottom-i[5].top):(i[5].left=i[4].right,i[5].x=i[4].right,i[5].width=i[5].right-i[5].left)):(i[5]={},i[5].label=n[5],i[5].type="blank")}if(Object.hasOwn(o[t],"outlier")){let e=o[t].outlier.children,s=null,l=null;for(let t=0;t<e.length;t++){let n=e[t].getBoundingClientRect();"vert"==constants.plotOrientation?n.y<a.y?s?(n.y<s.y&&(s.y=n.y),n.top<s.top&&(s.top=n.top),n.bottom>s.bottom&&(s.bottom=n.bottom)):s=this.convertBoundingClientRectToObj(n):l?(n.y<l.y&&(l.y=n.y),n.top<l.top&&(l.top=n.top),n.bottom>l.bottom&&(l.bottom=n.bottom)):l=this.convertBoundingClientRectToObj(n):n.x>a.x?s?(n.x<s.x&&(s.x=n.x),n.left<s.left&&(s.left=n.left),n.right>s.right&&(s.right=n.right)):s=this.convertBoundingClientRectToObj(n):l?(n.x<l.x&&(l.x=n.x),n.left<l.left&&(l.left=n.left),n.right>l.right&&(l.right=n.right)):l=this.convertBoundingClientRectToObj(n)}l?(l.height=l.bottom-l.top,l.width=l.right-l.left,i[0]=this.convertBoundingClientRectToObj(l),i[0].label=n[0],i[0].type="outlier"):(i[0]={},i[0].label=n[0],i[0].type="blank"),s?(s.height=s.bottom-s.top,s.width=s.right-s.left,i[6]=this.convertBoundingClientRectToObj(s),i[6].label=n[6],i[6].type="outlier"):(i[6]={},i[6].label=n[6],i[6].type="blank")}else i[0]={},i[0].label=n[0],i[0].type="blank",i[6]={},i[6].label=n[6],i[6].type="blank";e.push(i)}return constants.debugLevel>5&&console.log("plotBounds",e),e}GetAllSegmentTypes(){let t=[];for(let e=0;e<this.sections.length;e++)t.push(resources.GetString(this.sections[e]));return t}GetBoxplotSegmentType(t){let e="outlier";return t.includes("geom_crossbar")?e="range":t.includes("GRID")?e="whisker":t.includes("points")&&(e="outlier"),e}GetBoxplotSegmentPoints(t,e){let n=/(?:\d+(?:\.\d*)?|\.\d+)/g,s=[];if("range"==e){let e=t.children[0].getAttribute("points").match(n);s.push(e[0],e[1]),e[0]!=e[2]&&s.push(e[2],e[3])}else if("outlier"==e)s.push(t.getAttribute("x"),t.getAttribute("y"));else{let e=t.getAttribute("points").match(n);"vert"==constants.plotOrientation?e[1]!=e[3]&&s.push(e[0],e[1],e[2],e[3]):e[0]!=e[2]&&s.push(e[0],e[1],e[2],e[3])}return s}GetAllSegmentTypes(){return[resources.GetString("lower_outlier"),resources.GetString("min"),resources.GetString("25"),resources.GetString("50"),resources.GetString("75"),resources.GetString("max"),resources.GetString("upper_outlier")]}convertBoundingClientRectToObj(t){return{top:t.top,right:t.right,bottom:t.bottom,left:t.left,width:t.width,height:t.height,x:t.x,y:t.y}}PlayTones(){let t=null,e=null;constants.outlierInterval&&clearInterval(constants.outlierInterval),"vert"==constants.plotOrientation?(t=position.x,e=this.GetSectionKey(position.y)):(t=position.y,e=this.GetSectionKey(position.x)),null==plot.plotData[t][e]?audio.PlayNull():"lower_outlier"!=e&&"upper_outlier"!=e?audio.playTone():0==plot.plotData[t][e].length?audio.PlayNull():(position.z=0,constants.outlierInterval=setInterval((function(){audio.playTone(),position.z+=1,(null==plot.plotData[t][e]||position.z+1>plot.plotData[t][e].length)&&(clearInterval(constants.outlierInterval),position.z=-1)}),constants.autoPlayOutlierRate))}GetSectionKey(t){return this.sections[t]}}class BoxplotRect{rectPadding=15;rectStrokeWidth=4;constructor(){this.x1=0,this.width=0,this.y1=0,this.height=0,this.chartOffsetLeft=constants.chart.getBoundingClientRect().left,this.chartOffsetTop=constants.chart.getBoundingClientRect().top}UpdateRect(){document.getElementById("highlight_rect")&&document.getElementById("highlight_rect").remove();let t=position.x,e=position.y,n=plot.GetSectionKey(position.y);if("vert"==constants.plotOrientation||(t=position.y,e=position.x,n=plot.GetSectionKey(position.x)),"vert"==constants.plotOrientation&&position.y>-1||"horz"==constants.plotOrientation&&position.x>-1){let s=plot.plotBounds[t][e];"blank"!=s.type&&(this.x1=s.left-this.rectPadding-this.chartOffsetLeft,this.width=s.width+2*this.rectPadding,this.y1=s.top-this.rectPadding-this.chartOffsetTop,this.height=s.height+2*this.rectPadding,constants.debugLevel>5&&(console.log("Point",n,"bottom:",s.bottom,"top:",s.top),console.log("x1:",this.x1,"y1:",this.y1,"width:",this.width,"height:",this.height)),this.CreateRectDisplay())}}CreateRectDisplay(){let t=document.createElementNS("http://www.w3.org/2000/svg","rect");t.setAttribute("id","highlight_rect"),t.setAttribute("x",this.x1),t.setAttribute("y",this.y1),t.setAttribute("width",this.width),t.setAttribute("height",this.height),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.rectStrokeWidth),t.setAttribute("fill","none"),constants.chart.appendChild(t)}}class HeatMap{constructor(){let t=null,e=null;"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.level&&(t=singleMaidr.axes.x.level),singleMaidr.axes.y&&singleMaidr.axes.y.level&&(e=singleMaidr.axes.y.level)),"data"in singleMaidr?(this.data=singleMaidr.data,this.num_rows=this.data.length,this.num_cols=this.data[0].length):console.error("No data found in singleMaidr object"),"selector"in singleMaidr?(this.elements=document.querySelectorAll(singleMaidr.selector),constants.hasRect=1):"elements"in singleMaidr?(this.elements=singleMaidr.elements,constants.hasRect=1):(this.elements=null,constants.hasRect=0),this.group_labels=this.getGroupLabels(),this.x_labels=t,this.y_labels=e,this.title=this.getTitle(),this.fill=this.getFill(),constants.hasRect&&this.SetHeatmapRectData(),this.updateConstants(),this.x_group_label=this.group_labels[0].trim(),this.y_group_label=this.group_labels[1].trim()}SetHeatmapRectData(){let t=[],e=[],n=[],s=[];for(let n=0;n<this.elements.length;n++)if(this.elements[n])if(this.elements[n]instanceof SVGPathElement){const s=this.elements[n].getAttribute("d"),o=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(s),i=[Number(o[1]),Number(o[3])],a=i[0],l=i[1];t.push(parseFloat(a)),e.push(parseFloat(l))}else t.push(parseFloat(this.elements[n].getAttribute("x"))),e.push(parseFloat(this.elements[n].getAttribute("y")));t.sort((function(t,e){return t-e})),e.sort((function(t,e){return t-e}));let o=this.GetSVGScaler();-1==o[0]&&(t=t.reverse()),-1==o[1]&&(e=e.reverse()),n=[...new Set(t)],s=[...new Set(e)],this.x_coord=n,this.y_coord=s}updateConstants(){constants.minX=0,constants.maxX=this.data[0].length-1,constants.minY=Math.min(...this.data.map((t=>Math.min(...t)))),constants.maxY=Math.max(...this.data.map((t=>Math.max(...t)))),constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}PlayTones(){audio.playTone()}GetSVGScaler(){let t=1,e=1,n=!1,s=this.elements[0];for(;s&&"body"!=s.tagName.toLowerCase();)s.tagName&&"svg"===s.tagName.toLowerCase()&&(n=!0),s=s.parentNode;if(n){let n=this.elements[0];for(;n&&"body"!=n.tagName.toLowerCase();){if(n.getAttribute("transform")){let s=n.getAttribute("transform").match(/scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/);s&&(isNaN(s[1])||(t*=parseFloat(s[1])),isNaN(s[3])||(e*=parseFloat(s[3])))}n=n.parentNode}}return[t,e]}getRGBNorm(t){return this.elements[t].getAttribute("fill").slice(4,-1).split(",").map((function(t){return Math.pow(t,2)})).reduce((function(t,e){return t+e}))}getGroupLabels(){let t,e="",n="";return"labels"in singleMaidr&&("x"in singleMaidr.labels&&(e=singleMaidr.labels.x),"y"in singleMaidr.labels&&(n=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&"label"in singleMaidr.axes.x&&""==e&&(e=singleMaidr.axes.x.label),"y"in singleMaidr.axes&&"label"in singleMaidr.axes.y&&""==n&&(n=singleMaidr.axes.y.label)),t=[e,n],t}getXLabels(){if("axes"in singleMaidr&&"x"in singleMaidr.axes&&"level"in singleMaidr.axes.x)return singleMaidr.axes.x.level}getYLabels(){if("axes"in singleMaidr&&"y"in singleMaidr.axes&&"level"in singleMaidr.axes.y)return singleMaidr.axes.y.level}getTitle(){return"title"in singleMaidr?singleMaidr.title:"labels"in singleMaidr&&"title"in singleMaidr.labels?singleMaidr.labels.title:void 0}getSubtitle(){if("labels"in singleMaidr&&"subtitle"in singleMaidr.labels)return singleMaidr.labels.subtitle}getCaption(){if("labels"in singleMaidr&&"caption"in singleMaidr.labels)return singleMaidr.labels.caption}getFill(){if("labels"in singleMaidr&&"fill"in singleMaidr.labels)return singleMaidr.labels.fill}}class HeatMapRect{constructor(){constants.hasRect&&(this.x=plot.x_coord[0],this.y=plot.y_coord[0],this.squareIndex=0,this.rectStrokeWidth=4,this.height=Math.abs(plot.y_coord[1]-plot.y_coord[0]),this.width=Math.abs(plot.x_coord[1]-plot.x_coord[0]))}UpdateRect(){this.x=plot.x_coord[position.x],this.y=plot.y_coord[position.y];for(let t=0;t<plot.elements.length;t++)if(plot.elements[t].getAttribute("x")==this.x&&plot.elements[t].getAttribute("y")==this.y){this.squareIndex=t;break}}UpdateRectDisplay(){this.UpdateRect(),document.getElementById("highlight_rect")&&document.getElementById("highlight_rect").remove();var t=document.createElementNS("http://www.w3.org/2000/svg","rect");t.setAttribute("id","highlight_rect"),t.setAttribute("x",this.x),t.setAttribute("y",this.y),t.setAttribute("width",this.width),t.setAttribute("height",this.height),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.rectStrokeWidth),t.setAttribute("fill","none"),plot.elements[this.squareIndex].parentNode.appendChild(t)}}class ScatterPlot{constructor(){this.prefix=this.GetPrefix(),this.SetScatterLayer(),this.SetLineLayer(),this.SetAxes(),this.svgScaler=this.GetSVGScaler()}SetAxes(){this.x_group_label="",this.y_group_label="",this.title="","labels"in singleMaidr&&("x"in singleMaidr.labels&&(this.x_group_label=singleMaidr.labels.x),"y"in singleMaidr.labels&&(this.y_group_label=singleMaidr.labels.y),"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&""==this.x_group_label&&(this.x_group_label=singleMaidr.axes.x.label),"y"in singleMaidr.axes&&""==this.y_group_label&&(this.y_group_label=singleMaidr.axes.y.label)),"title"in singleMaidr&&""==this.title&&(this.title=singleMaidr.title)}SetScatterLayer(){let t=this.GetElementIndex("point");-1!=t?"selector"in singleMaidr?this.plotPoints=document.querySelectorAll(singleMaidr.selector[t]):"elements"in singleMaidr&&(this.plotPoints=singleMaidr.elements[t]):"point"==singleMaidr.type&&("selector"in singleMaidr?this.plotPoints=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(this.plotPoints=singleMaidr.elements));let e=this.GetSvgPointCoords(),n=this.GetPointValues();this.chartPointsX=e[0],this.chartPointsY=e[1],this.x=n[0],this.y=n[1],this.points_count=n[2],this.max_count=n[3]}SetLineLayer(){let t=this.GetElementIndex("smooth");-1!=t?"selector"in singleMaidr?this.plotLine=document.querySelectorAll(singleMaidr.selector[t])[0]:"elements"in singleMaidr&&(this.plotLine=singleMaidr.elements[t][0]):"smooth"==singleMaidr.type&&("selector"in singleMaidr?this.plotLine=document.querySelectorAll(singleMaidr.selector)[0]:"elements"in singleMaidr&&(this.plotLine=singleMaidr.elements));let e=this.GetSvgLineCoords(),n=this.GetSmoothCurvePoints();this.chartLineX=e[0],this.chartLineY=e[1],this.curveX=n[0],this.curvePoints=n[1],this.curvePoints&&this.curvePoints.length>0?(this.curveMinY=Math.min(...this.curvePoints),this.curveMaxY=Math.max(...this.curvePoints)):(this.curveMinY=Number.MAX_VALUE,this.curveMaxY=Number.MIN_VALUE),this.gradient=this.GetGradient()}GetSvgPointCoords(){let t=new Map;if(this.plotPoints)for(let e=0;e<this.plotPoints.length;e++){let n,s;if(this.plotPoints[e]instanceof SVGPathElement){let t=this.plotPoints[e].getAttribute("d"),o=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(o[1]),s=parseFloat(o[3])}else n=parseFloat(this.plotPoints[e].getAttribute(this.prefix+"x")),s=parseFloat(this.plotPoints[e].getAttribute(this.prefix+"y"));t.has(n)?t.get(n).add(s):t.set(n,new Set([s]))}else if([].concat(singleMaidr.type).includes("point")){let e,n=this.GetElementIndex("point"),s=this.GetDataXYFormat(n);e=n>-1?singleMaidr.data[n]:singleMaidr.data;let o=[],i=[];if("array"==s)"x"in e&&(o=e.x),"y"in e&&(i=e.y);else if("object"==s)for(let t=0;t<e.length;t++){let n=e[t].x,s=e[t].y;o.push(n),i.push(s)}for(let e=0;e<o.length;e++){let n=o[e],s=i[e];t.has(n)?t.get(n).add(s):t.set(n,new Set([s]))}}t=new Map([...t].sort((function(t,e){return t[0]-e[0]}))),t.forEach((function(e,n){t[n]=Array.from(e).sort((function(t,e){return t-e}))}));let e=[...t.keys()],n=[];for(let s=0;s<e.length;s++)n.push(t[e[s]]);return[e,n]}GetElementIndex(t="point"){let e=-1;return"type"in singleMaidr&&Array.isArray(singleMaidr.type)&&(e=singleMaidr.type.indexOf(t)),e}GetDataXYFormat(t){let e,n;return e=t>-1?singleMaidr.data[t]:singleMaidr.data,n=Array.isArray(e)?"object":"array",n}GetSVGScaler(){let t=1,e=1,n=!1;if(this.plotPoints){let s=this.plotPoints[0];for(;s&&"body"!=s.tagName.toLowerCase();)s.tagName&&"svg"===s.tagName.toLowerCase()&&(n=!0),s=s.parentNode;if(n){let n=this.plotPoints[0];for(;n&&"body"!=n.tagName.toLowerCase();){if(n.getAttribute("transform")){let s=n.getAttribute("transform").match(/scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/);s&&(isNaN(s[1])||(t*=parseFloat(s[1])),isNaN(s[3])||(e*=parseFloat(s[3])))}n=n.parentNode}}}return[t,e]}GetPrefix(){let t=this.GetElementIndex("point"),e=null;-1!=t?"selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector[t])[0]:"elements"in singleMaidr&&(e=singleMaidr.elements[t][0]):"point"==singleMaidr.type&&("selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector)[0]:"elements"in singleMaidr&&(e=singleMaidr.elements[0]));let n="";return e&&"circle"===e.tagName.toLowerCase()&&(n="c"),n}GetPointValues(){let t,e,n=new Map,s=[],o=[],i=[],a=this.GetElementIndex("point"),l=this.GetDataXYFormat(a);if(a>-1?e=singleMaidr.data[a]:"point"==singleMaidr.type&&(e=singleMaidr.data),void 0!==e){let a=[],r=[];if("array"==l)"x"in e&&(a=e.x),"y"in e&&(r=e.y);else if("object"==l)for(let t=0;t<e.length;t++){let n=e[t].x,s=e[t].y;a.push(n),r.push(s)}for(let t=0;t<a.length;t++){let e=a[t],s=r[t];if(n.has(e))if(n.get(e).has(s)){let t=n.get(e);t.set(s,t.get(s)+1)}else n.get(e).set(s,1);else n.set(e,new Map([[s,1]]))}constants.minX=0,constants.maxX=[...new Set(a)].length,constants.minY=Math.min(...r),constants.maxY=Math.max(...r),constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate),n=new Map([...n].sort((function(t,e){return t[0]-e[0]}))),n.forEach((function(t,e){n[e]=Array.from(t).sort((function(t,e){return t[0]-e[0]}))}));for(const[t,e]of n){s.push(t);let n=[],a=[];for(const[t,s]of e)n.push(t),a.push(s);o.push(n.sort()),i.push(a)}t=Math.max(...i.map((t=>Math.max(...t))))}return[s,o,i,t]}PlayTones(){constants.sepPlayId&&constants.KillSepPlay(),"point"==constants.chartType?(position.z=0,constants.sepPlayId=setInterval((function(){audio.playTone(),position.z+=1,position.z+1>plot.y[position.x].length&&(constants.KillSepPlay(),position.z=-1)}),"on"==constants.sonifMode?constants.autoPlayPointsRate:0)):"smooth"==constants.chartType&&audio.playTone()}GetSvgLineCoords(){let t=[],e=[];if(this.plotLine){if(this.plotLine instanceof SVGPathElement){const n=this.plotLine.getAttribute("d"),s=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;let o;for(;null!==(o=s.exec(n));)t.push(o[1]),e.push(o[3])}else if(this.plotLine instanceof SVGPolylineElement){let n=this.plotLine.getAttribute("points").split(" ");for(let s=0;s<n.length;s++){let o=n[s].split(",");t.push(parseFloat(o[0])),e.push(parseFloat(o[1]))}}}else if([].concat(singleMaidr.type).includes("smooth")){let n,s=this.GetElementIndex("smooth"),o=this.GetDataXYFormat(s);if(n=s>-1?singleMaidr.data[s]:singleMaidr.data,"object"==o)for(let s=0;s<n.length;s++)t.push(n[s].x),e.push(n[s].y);else"array"==o&&("x"in n&&(t=n.x),"y"in n&&(e=n.y))}return[t,e]}GetSmoothCurvePoints(){let t,e=[],n=[],s=this.GetElementIndex("smooth"),o=this.GetDataXYFormat(s);if(s>-1?t=singleMaidr.data[s]:"smooth"==singleMaidr.type&&(t=singleMaidr.data),void 0!==t)if("object"==o)for(let s=0;s<t.length;s++)e.push(t[s].x),n.push(t[s].y);else"array"==o&&("x"in t&&(e=t.x),"y"in t&&(n=t.y));return[e,n]}GetGradient(){let t=[];for(let e=0;e<this.curvePoints.length-1;e++){let n=Math.abs((this.curvePoints[e+1]-this.curvePoints[e])/(this.curveX[e+1]-this.curveX[e])).toFixed(3);t.push(n)}return t.push("end"),t}GetRectStatus(t){let e=this.GetElementIndex(t);if(e>-1){if("selector"in singleMaidr)return!!singleMaidr.selector[e];if("elements"in singleMaidr)return!!singleMaidr.elements[e]}else{if("selector"in singleMaidr)return!!singleMaidr.selector;if("elements"in singleMaidr)return!!singleMaidr.elements}}}class Layer0Point{constructor(){[].concat(singleMaidr.type).includes("point")&&(this.x=plot.chartPointsX[0],this.y=plot.chartPointsY[0],this.strokeWidth=1.35,this.hasRect=plot.GetRectStatus("point"),this.circleIndex=[])}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartPointsX[position.x],this.y=plot.chartPointsY[position.x],this.circleIndex=[];for(let t=0;t<this.y.length;t++)for(let e=0;e<plot.plotPoints.length;e++){let n,s;if(plot.plotPoints[e]instanceof SVGPathElement){const t=plot.plotPoints[e].getAttribute("d");let o=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(o[1]),s=parseFloat(o[3])}else(plot.plotPoints[e]instanceof SVGUseElement||plot.plotPoints[e]instanceof SVGCircleElement)&&(n=plot.plotPoints[e].getAttribute(plot.prefix+"x"),s=plot.plotPoints[e].getAttribute(plot.prefix+"y"));if(n==this.x&&s==this.y[t]){this.circleIndex.push(e);break}}}async PrintPoints(){await this.ClearPoints(),await this.UpdatePoints();for(let e=0;e<this.circleIndex.length;e++){const n="http://www.w3.org/2000/svg";var t=document.createElementNS(n,"circle");if(t.setAttribute("class","highlight_point"),t.setAttribute("cx",this.x),-1==plot.svgScaler[1])t.setAttribute("cy",constants.chart.getBoundingClientRect().height-this.y[e]);else{let n;if(plot.plotPoints[this.circleIndex[e]]instanceof SVGPathElement){const t=plot.plotPoints[this.circleIndex[e]].getAttribute("d");let s=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(s[3])}else(plot.plotPoints[this.circleIndex[e]]instanceof SVGUseElement||plot.plotPoints[this.circleIndex[e]]instanceof SVGCircleElement)&&(n=plot.plotPoints[this.circleIndex[e]].getAttribute(plot.prefix+"y"));t.setAttribute("cy",n)}t.setAttribute("r",3.95),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.strokeWidth),t.setAttribute("fill",constants.colorSelected),constants.chart.appendChild(t)}}async ClearPoints(){document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove();let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove()}UpdatePointDisplay(){this.ClearPoints(),this.UpdatePoints(),this.PrintPoints()}}class Layer1Point{constructor(){[].concat(singleMaidr.type).includes("smooth")&&(this.x=plot.chartLineX[0],this.y=plot.chartLineY[0],this.strokeWidth=1.35,this.hasRect=plot.GetRectStatus("point"))}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartLineX[positionL1.x],this.y=plot.chartLineY[positionL1.x]}async PrintPoints(){await this.ClearPoints(),await this.UpdatePoints();var t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("id","highlight_point"),t.setAttribute("cx",this.x),-1==plot.svgScaler[1]?t.setAttribute("cy",constants.chart.getBoundingClientRect().height-this.y):t.setAttribute("cy",this.y),t.setAttribute("r",3.95),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.strokeWidth),t.setAttribute("fill",constants.colorSelected),-1==plot.svgScaler[1]?constants.chart.appendChild(t):plot.plotLine.parentNode.appendChild(t)}async ClearPoints(){let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove();document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove()}UpdatePointDisplay(){this.ClearPoints(),this.UpdatePoints(),this.PrintPoints()}}class Histogram{constructor(){"data"in singleMaidr?(this.plotData=singleMaidr.data,this.bars=null,"selector"in singleMaidr?this.bars=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(this.bars=singleMaidr.elements),this.legendX=null,this.legendY=null,"labels"in singleMaidr&&("x"in singleMaidr.labels&&(this.legendX=singleMaidr.labels.x),"y"in singleMaidr.labels&&(this.legendY=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&"label"in singleMaidr.axes.x&&(this.legendX||(this.legendX=singleMaidr.axes.x.label)),"y"in singleMaidr.axes&&"label"in singleMaidr.axes.y&&(this.legendY||(this.legendY=singleMaidr.axes.y.label))),this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),this.SetMaxMin(),this.autoplay=null):console.log("Error: no data found")}PlayTones(){audio.playTone()}SetMaxMin(){for(let t=0;t<this.plotData.length;t++)0==t?(constants.maxY=this.plotData[t].y,constants.minY=this.plotData[t].y,constants.maxX=this.plotData[t].xmax,constants.minX=this.plotData[t].xmin):(this.plotData[t].y>constants.maxY&&(constants.maxY=this.plotData[t].y),this.plotData[t].y<constants.minY&&(constants.minY=this.plotData[t].y),this.plotData[t].xmax>constants.maxX&&(constants.maxX=this.plotData[t].xmax),this.plotData[t].xmin<constants.minX&&(constants.minX=this.plotData[t].xmin));constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}Select(){if(this.UnSelectPrevious(),this.bars&&(this.activeElement=this.bars[position.x],this.activeElement))if(this.activeElement.hasAttribute("fill"))this.activeElementColor=this.activeElement.getAttribute("fill"),this.activeElement.setAttribute("fill",constants.GetBetterColor(this.activeElementColor));else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);this.activeElementColor=e[e.indexOf("fill")+1],e[e.indexOf("fill")+1]=constants.GetBetterColor(this.activeElementColor),t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t)}}UnSelectPrevious(){if(this.activeElement)if(this.activeElement.hasAttribute("fill"))this.activeElement.setAttribute("fill",this.activeElementColor),this.activeElement=null;else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);e[e.indexOf("fill")+1]=this.activeElementColor,t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t),this.activeElement=null}}}class LinePlot{constructor(){this.SetLineLayer(),this.SetAxes(),this.UpdateConstants()}SetLineLayer(){let t;"selector"in singleMaidr?t=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(t=singleMaidr.elements),t?this.plotLine=t[t.length-1]:constants.hasRect=0;let e=this.GetPointCoords(),n=this.GetPoints();this.chartLineX=e[0],this.chartLineY=e[1],this.pointValuesX=n[0],this.pointValuesY=n[1],this.curveMinY=Math.min(...this.pointValuesY),this.curveMaxY=Math.max(...this.pointValuesY)}UpdateConstants(){constants.minX=0,constants.maxX=singleMaidr.data.length-1,constants.minY=singleMaidr.data.reduce(((t,e)=>e.y<t?e.y:t),singleMaidr.data[0].y),constants.maxY=singleMaidr.data.reduce(((t,e)=>e.y>t?e.y:t),singleMaidr.data[0].y),constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}GetPointCoords(){let t=[[],[]];if(!this.plotLine){let t,e=[],n=[];if("data"in singleMaidr&&(t=singleMaidr.data),void 0!==t)for(let s=0;s<t.length;s++)e.push(t[s].x),n.push(t[s].y);return[e,n]}if(this.plotLine instanceof SVGPathElement){const e=this.plotLine.getAttribute("d"),n=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;let s;for(;null!==(s=n.exec(e));)t[0].push(s[1]),t[1].push(s[3])}else{let e=this.plotLine.getAttribute("points").split(" ");for(let n=0;n<e.length;n++)if(""!==e[n]){let s=e[n].split(",");t[0].push(s[0]),t[1].push(s[1])}}return t}GetPoints(){let t,e=[],n=[];if("data"in singleMaidr&&(t=singleMaidr.data),void 0!==t){for(let s=0;s<t.length;s++)e.push(t[s].x),n.push(t[s].y);return[e,n]}}SetAxes(){let t="",e="";"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&""==t&&(t=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&""==e&&(e=singleMaidr.axes.y.label)),this.plotLegend={x:t,y:e},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption)}PlayTones(){audio.playTone()}}class Point{constructor(){this.x=plot.chartLineX[0],this.y=plot.chartLineY[0]}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartLineX[position.x],this.y=plot.chartLineY[position.x]}async PrintPoints(){await this.ClearPoints(),await this.UpdatePoints();var t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("id","highlight_point"),t.setAttribute("cx",this.x),t.setAttribute("cy",this.y),t.setAttribute("r",1.75),t.setAttribute("style","fill:"+constants.colorSelected+";stroke:"+constants.colorSelected),constants.chart.appendChild(t)}async ClearPoints(){let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove();document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove()}UpdatePointDisplay(){this.ClearPoints(),this.UpdatePoints(),this.PrintPoints()}}class Segmented{constructor(){let t=null,e=null;if("axes"in singleMaidr&&("x"in singleMaidr.axes?"level"in singleMaidr.axes.x&&(this.level=singleMaidr.axes.x.level):"y"in singleMaidr.axes&&"level"in singleMaidr.axes.y&&(this.level=singleMaidr.axes.y.level),"fill"in singleMaidr.axes&&"level"in singleMaidr.axes.fill&&(this.fill=singleMaidr.axes.fill.level)),"data"in singleMaidr&&(t=singleMaidr.data),"selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(e=singleMaidr.elements),null==e&&(logError.LogAbsentElement("elements"),constants.hasRect=0),!t)return void console.log("Segmented chart missing level, fill, or data. Unable to create chart.");{this.fill&&(this.fill=this.fill.reverse());let n=this.ParseData(t,e);this.plotData=n[0],this.elements=n[1]}let n="",s="";"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&(n=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&(s=singleMaidr.axes.y.label)),"labels"in singleMaidr&&("x"in singleMaidr.labels&&(n=singleMaidr.labels.x),"y"in singleMaidr.labels&&(s=singleMaidr.labels.y)),this.plotLegend={x:n,y:s},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),this.SetMaxMin(),this.CreateSummaryLevel(),this.CreateAllLevel(),this.autoplay=null}ParseData(t,e=null){let n=[],s=[];e?e.length!=t.length&&(s=null):s=null;for(let o=0;o<this.level.length;o++)for(let i=0;i<this.fill.length;i++)for(let a=0;a<t.length;a++)if(n[o]||(n[o]=[],null!=s&&(s[o]||(s[o]=[]))),n[o][i]||(n[o][i]=0,null!=s&&(s[o][i]||(s[o][i]=null))),t[a].x==this.level[o]&&t[a].fill==this.fill[i]){n[o][i]=t[a].y,e&&(s[o][i]=e[a]);break}return[n,s]}CreateSummaryLevel(){for(let t=0;t<this.plotData.length;t++){let e=0;for(let n=0;n<this.plotData[t].length;n++)e+=this.plotData[t][n];this.plotData[t].push(e)}this.fill.push("Sum")}CreateAllLevel(){for(let t=0;t<this.plotData.length;t++){let e=[];for(let n=0;n<this.fill.length;n++)"Sum"!=this.fill[n]&&e.push(this.plotData[t][n]);this.plotData[t].push(e)}this.fill.push("All")}PlayTones(){if(Array.isArray(this.plotData[position.x][position.y]))if("on"==constants.sonifMode)position.z=0,constants.KillSepPlay(),constants.sepPlayId=setInterval((function(){audio.playTone(),position.z+=1,Array.isArray(plot.plotData[position.x][position.y])?position.z+1>plot.plotData[position.x][position.y].length&&(constants.KillSepPlay(),position.z=-1):(constants.KillSepPlay(),position.z=-1)}),"on"==constants.sonifMode?constants.autoPlayPointsRate:0);else{let t=Math.min(...this.plotData[position.x][position.y]),e=Math.max(...this.plotData[position.x][position.y]);for(let n=0;n<this.plotData[position.x][position.y].length;n++){position.z=n;let s=audio.SlideBetween(this.plotData[position.x][position.y][n],t,e,constants.combinedVolMin,constants.combinedVolMax);audio.playTone({volScale:s})}}else audio.playTone()}SetMaxMin(){for(let t=0;t<singleMaidr.data.length;t++)0==t?(constants.maxY=singleMaidr.data[t].y,constants.minY=singleMaidr.data[t].y):(singleMaidr.data[t].y>constants.maxY&&(constants.maxY=singleMaidr.data[t].y),singleMaidr.data[t].y<constants.minY&&(constants.minY=singleMaidr.data[t].y));constants.maxX=this.level.length,constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}Select(){if(this.UnSelectPrevious(),this.elements&&(this.activeElement=this.elements[position.x][position.y],this.activeElement)){this.activeElementColor=this.activeElement.style.fill;let t=constants.GetBetterColor(this.activeElementColor);this.activeElement.style.fill=t}}UnSelectPrevious(){this.activeElement&&(this.activeElement.style.fill=this.activeElementColor,this.activeElement=null)}}class Control{constructor(){this.SetControls()}SetControls(){let t=[constants.chart,constants.brailleInput,constants.review_container],e=!1,n=null;for(let s=0;s<t.length;s++)constants.events.push([t[s],"keydown",function(t){if(!e&&("b"==t.key&&(constants.tabMovement=0,t.preventDefault(),display.toggleBrailleMode()),"t"==t.key&&display.toggleTextMode(),"s"==t.key&&display.toggleSonificationMode(),"r"!=t.key||t.ctrlKey||t.shiftKey||(constants.tabMovement=0,t.preventDefault(),constants.review_container.classList.contains("hidden")?review.ToggleReviewMode(!0):review.ToggleReviewMode(!1))," "==t.key&&(position.x<0&&(position.x=0),position.y<0&&(position.y=0),constants.showDisplay&&display.displayValues(),"off"!=constants.sonifMode&&plot.PlayTones()),Array.isArray(singleMaidr.type)&&[].concat(singleMaidr.type).includes("point")&&[].concat(singleMaidr.type).includes("smooth")&&("PageDown"==t.key&&"off"==constants.brailleMode&&display.changeChartLayer("down"),"PageUp"==t.key&&"off"==constants.brailleMode&&display.changeChartLayer("up")),"-"==t.key)){}}]);for(let o=0;o<t.length;o++)constants.events.push([t[o],"keydown",function(t){"Tab"==t.key&&(t.shiftKey?constants.tabDirection=-1:constants.tabDirection=1)}]);if(constants.events.push([document,"keydown",function(t){if("l"==t.key&&(e=!0,null!=n&&(clearTimeout(n),n=null),n=setTimeout((function(){e=!1}),constants.keypressInterval)),(constants.isMac?t.metaKey:t.ctrlKey)&&("Home"==t.key?("bar"==constants.chartType||"hist"==constants.chartType?position.x=0:"box"==constants.chartType?(position.x=0,position.y=plot.sections.length-1):"heat"==constants.chartType?(position.x=0,position.y=0):"point"==constants.chartType?position.x=0:"smooth"==constants.chartType&&(positionL1.x=0),UpdateAllBraille()):"End"==t.key&&("bar"==constants.chartType||"hist"==constants.chartType?position.x=plot.bars.length-1:"box"==constants.chartType?(position.x=plot.sections.length-1,position.y=0):"heat"==constants.chartType?(position.x=plot.num_cols-1,position.y=plot.num_rows-1):"point"==constants.chartType?position.x=plot.y.length-1:"smooth"==constants.chartType&&(positionL1.x=plot.curvePoints.length-1),UpdateAllBraille())),e)if("x"==t.key){let t="";"bar"==constants.chartType||"line"==singleMaidr.type?t=plot.plotLegend.x:("heat"==constants.chartType||"box"==constants.chartType||"point"==singleMaidr.type||singleMaidr.type.includes("point"))&&(t=plot.x_group_label),display.displayInfo("x label",t),e=!1}else if("y"==t.key){let t="";"bar"==constants.chartType||"line"==singleMaidr.type?t=plot.plotLegend.y:("heat"==constants.chartType||"box"==constants.chartType||"point"==singleMaidr.type||"line"==singleMaidr.type||singleMaidr.type.includes("point"))&&(t=plot.y_group_label),display.displayInfo("y label",t),e=!1}else"t"==t.key?(display.displayInfo("title",plot.title),e=!1):"s"==t.key?(display.displayInfo("subtitle",plot.subtitle),e=!1):"c"==t.key?(display.displayInfo("caption",plot.caption),e=!1):"f"==t.key?(display.displayInfo("fill",plot.fill),e=!1):"l"!=t.key&&(e=!1)}]),[].concat(singleMaidr.type).includes("bar")){window.position=new Position(-1,-1),window.plot=new BarChart,constants.lastx=0;let i="";constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,u("right",position.x,plot.plotData.length)):(position.x=plot.plotData.length-1,e=!0,n=c()):t.altKey&&t.shiftKey&&position.x!=plot.bars.length-1?(constants.lastx=position.x,u("reverse-right",plot.bars.length,position.x)):(position.x+=1,e=!0,n=c()):"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,u("left",position.x,-1)):(position.x=0,e=!0,n=c()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,u("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=c())),e&&!n&&p(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(t.preventDefault(),t.target.selectionStart>t.target.value.length-2||((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,u("right",position.x,plot.plotData.length)):(position.x=plot.bars.length-1,e=!0,n=c()):t.altKey&&t.shiftKey&&position.x!=plot.bars.length-1?(constants.lastx=position.x,u("reverse-right",plot.bars.length,position.x)):(position.x+=1,e=!0,n=c()))):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,u("left",position.x,-1)):(position.x=0,e=!0,n=c()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,u("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=c())):"Tab"==t.key||t.preventDefault(),e&&!n&&h(),n&&audio.playEnd()}]);let a=[constants.chart,constants.brailleInput],l=0;for(let y=0;y<a.length;y++)constants.events.push([a[y],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),r(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),r(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),r(),display.announceText("Speed reset"))}]);function r(){null!=constants.autoplayId&&(constants.KillAutoplay(),u("reverse-left"==i?"right":"reverse-right"==i?"left":i,position.x,l))}function c(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.plotData.length-1&&(position.x=plot.plotData.length-1,t=!0),t}function p(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones()}function d(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function h(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function u(t,e,n){i=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),c()):position.x==n?(constants.KillAutoplay(),d()):d()}),constants.autoPlayRate)}}else if([].concat(singleMaidr.type).includes("box")){let g;constants.plotId="geom_boxplot.gTree.78.1",window.plot=new BoxPlot,"vert"==constants.plotOrientation?window.position=new Position(0,6):window.position=new Position(-1,plot.plotData.length),constants.hasRect&&(g=new BoxplotRect);let m="";constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;if("ArrowRight"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?w("right",position.x,plot.plotData.length-1):w("right",position.x,plot.sections.length-1):(n=L(),"vert"==constants.plotOrientation?position.x=plot.plotData.length-1:position.x=plot.sections.length-1,e=!0,n=L()):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&plot.sections.length-1!=position.x?(lastY=position.y,w("reverse-right",plot.plotData.length-1,position.x)):(-1==position.x&&position.y==plot.sections.length&&(position.y-=1),position.x+=1,e=!0,n=L()):t.altKey&&t.shiftKey&&plot.sections.length-1!=position.x?(constants.lastx=position.x,w("reverse-right",plot.sections.length-1,position.x)):(-1==position.x&&position.y==plot.plotData.length&&(position.y-=1),position.x+=1,e=!0,n=L()),constants.navigation=1),"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?w("left",position.x,-1):(position.x=0,e=!0,n=L()):t.altKey&&t.shiftKey&&position.x>0?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,w("reverse-left",0,position.x)):(position.x+=-1,e=!0,n=L()),constants.navigation=1),"ArrowUp"==t.key){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?w("up",position.y,plot.sections.length):w("up",position.y,plot.plotData.length):("vert"==constants.plotOrientation?position.y=plot.sections.length-1:position.y=plot.plotData.length-1,e=!0,n=L()):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&position.y!=plot.sections.length-1?(lastY=position.y,w("reverse-up",plot.sections.length-1,position.y)):(position.y+=1,e=!0,n=L()):t.altKey&&t.shiftKey&&position.y!=plot.sections.length-1?(constants.lastx=position.x,w("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,e=!0,n=L()),constants.navigation=0}if("ArrowDown"==t.key){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?w("down",position.y,-1):(position.y=0,e=!0,n=L()):t.altKey&&t.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,w("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.sections.length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,e=!0,n=L()),constants.navigation=0}e&&!n&&M(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1,s=!1;if("ArrowRight"==t.key)t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?w("right",position.x,plot.plotData.length-1):w("right",position.x,plot.sections.length):("vert"==constants.plotOrientation?position.x=plot.plotData.length-1:position.x=plot.sections.length-1,e=!0,s=L()):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&plot.plotData.length-1!=position.x?(lastY=position.y,w("reverse-right",plot.plotData.length-1,position.x)):(-1==position.x&&position.y==plot.plotData[position.x].length&&(position.y-=1),position.x+=1,e=!0,s=L()):t.altKey&&t.shiftKey&&plot.sections.length-1!=position.x?(constants.lastx=position.x,w("reverse-right",plot.sections.length-1,position.x)):(-1==position.x&&position.y==plot.plotData.length&&(position.y-=1),position.x+=1,e=!0,s=L()),n=!0,constants.navigation=1;else if("ArrowLeft"==t.key)t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?w("left",position.x,-1):(position.x=0,e=!0,s=L()):t.altKey&&t.shiftKey&&position.x>0?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,w("reverse-left",0,position.x)):(position.x+=-1,e=!0,s=L()),n=!0,constants.navigation=1;else if("ArrowUp"==t.key){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?(position.x<0&&(position.x=0),w("up",position.y,plot.sections.length)):w("up",position.y,plot.plotData.length):"vert"==constants.plotOrientation?(position.y=plot.sections.length-1,e=!0):(position.y=plot.plotData.length-1,e=!0):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&position.y!=plot.sections.length-1?(lasY=position.y,w("reverse-up",plot.sections.length-1,position.y)):(position.y+=1,e=!0,s=L()):t.altKey&&t.shiftKey&&position.y!=plot.plotData.length-1?(constants.lastx=position.x,w("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,e=!0,s=L()),"vert"==constants.plotOrientation||(n=!0),constants.navigation=0}else if("ArrowDown"==t.key){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?w("down",position.y,-1):(position.y=0,e=!0,s=L()):t.altKey&&t.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,w("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.sections.length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,e=!0,s=L()),constants.navigation=0,"vert"==constants.plotOrientation||(n=!0),constants.navigation=0}else"Tab"==t.key||t.preventDefault();e&&!s&&(n&&display.SetBraille(plot),setTimeout(_,50)),s&&audio.playEnd()}]);let f=[constants.chart,constants.brailleInput],x=0;for(let E=0;E<f.length;E++)constants.events.push([f[E],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),v(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),v(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),v(),display.announceText("Speed reset"))}]);function v(){null!=constants.autoplayId&&(constants.KillAutoplay(),"reverse-left"==m?"vert"==constants.plotOrientation?w("right",position.y,lastY):w("right",position.x,x):"reverse-right"==m?"vert"==constants.plotOrientation?w("left",position.y,lastY):w("left",position.x,x):"reverse-up"==m?"vert"==constants.plotOrientation?w("down",position.y,lastY):w("down",position.x,x):"reverse-down"==m?"vert"==constants.plotOrientation?w("up",position.y,lastY):w("up",position.x,x):"vert"==constants.plotOrientation?w(m,position.y,lastY):w(m,position.x,x))}function M(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&g.UpdateRect(),"off"!=constants.sonifMode&&plot.PlayTones()}function b(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&g.UpdateRect(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function _(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&constants.hasRect&&g.UpdateRect(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function L(){let t=!1;return position.y<0&&(position.y=0,t=!0),position.x<0&&(position.x=0,t=!0),"vert"==constants.plotOrientation?(position.x>plot.plotData.length-1&&(position.x=plot.plotData.length-1,t=!0),position.y>plot.sections.length-1&&(position.y=plot.sections.length-1,t=!0)):(position.y>plot.plotData.length-1&&(position.y=plot.plotData.length-1,t=!0),position.x>plot.sections.length-1&&(position.x=plot.sections.length-1,t=!0)),t}function w(t,e,n){m=t;let s=1;"left"!=t&&"down"!=t&&"reverse-right"!=t&&"reverse-up"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.debugLevel>0&&console.log("starting autoplay",t,e,n),b(),constants.autoplayId=setInterval((function(){let e=!1;"left"==t||"right"==t||"up"==t||"down"==t?(position.x<1&&"left"==t||"vert"==constants.plotOrientation&&"up"==t&&position.y>plot.sections.length-2||"horz"==constants.plotOrientation&&"up"==t&&position.y>plot.plotData.length-2||"horz"==constants.plotOrientation&&"right"==t&&position.x>plot.sections.length-2||"vert"==constants.plotOrientation&&"right"==t&&position.x>plot.plotData.length-2||"horz"==constants.plotOrientation&&"down"==t&&position.y<1||"vert"==constants.plotOrientation&&"down"==t&&position.y<1)&&(e=!0):("reverse-left"==t&&position.x>=n||"reverse-right"==t&&position.x<=n||"reverse-up"==t&&position.y<=n||"reverse-down"==t&&position.y>=n)&&(e=!0),e?constants.KillAutoplay():("left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?position.x+=s:position.y+=s,b()),constants.debugLevel>5&&console.log("autoplay pos",position)}),constants.autoPlayRate)}}else if([].concat(singleMaidr.type).includes("heat")){constants.plotId="geom_rect.rect.2.1",window.position=new Position(-1,-1),window.plot=new HeatMap;let S=new HeatMapRect,D="";constants.lastx=0,constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,R("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,e=!0):t.altKey&&t.shiftKey&&position.x!=plot.num_cols-1?(constants.lastx=position.x,R("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,e=!0,n=k()),constants.navigation=1),"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,R("left",position.x,-1)):(position.x=0,e=!0):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,R("reverse-left",-1,position.x)):(position.x-=1,e=!0,n=k()),constants.navigation=1),"ArrowUp"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.y+=1,R("up",position.y,-1)):(position.y=0,e=!0):t.altKey&&t.shiftKey&&0!=position.y?(constants.lastx=position.x,R("reverse-up",-1,position.y)):(position.y-=1,e=!0,n=k()),constants.navigation=0),"ArrowDown"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.y-=1,R("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,e=!0):t.altKey&&t.shiftKey&&position.y!=plot.num_rows-1?(constants.lastx=position.x,R("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,e=!0,n=k()),constants.navigation=0),e&&!n&&T(),n&&audio.playEnd()}]);let A=[constants.chart,constants.brailleInput],I=0;for(let B=0;B<A.length;B++)constants.events.push([A[B],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),P(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),P(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),P(),display.announceText("Speed reset"))}]);function P(){null!=constants.autoplayId&&(constants.KillAutoplay(),R("reverse-left"==D?"right":"reverse-right"==D?"left":"reverse-up"==D?"down":"reverse-down"==D?"up":D,position.x,I))}function k(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.num_cols-1&&(position.x=plot.num_cols-1,t=!0),position.y<0&&(position.y=0,t=!0),position.y>plot.num_rows-1&&(position.y=plot.num_rows-1,t=!0),t}function T(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&S.UpdateRectDisplay(),"off"!=constants.sonifMode&&plot.PlayTones()}function K(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&S.UpdateRectDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function C(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&constants.hasRect&&S.UpdateRectDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function R(t,e,n){D=t;let s=1;"left"!=t&&"up"!=t&&"reverse-right"!=t&&"reverse-down"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.autoplayId=setInterval((function(){"left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?(position.x+=s,position.x<0||plot.num_cols-1<position.x?(constants.KillAutoplay(),k()):position.x==n?(constants.KillAutoplay(),K()):K()):(position.y+=s,position.y<0||plot.num_rows-1<position.y?(constants.KillAutoplay(),k()):position.y==n?(constants.KillAutoplay(),K()):K())}),constants.autoPlayRate)}constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;if("ArrowRight"==t.key)if(t.target.selectionStart>t.target.value.length-3||"⠳"==t.target.value.substring(t.target.selectionStart+1,t.target.selectionStart+2))t.preventDefault();else{(constants.isMac?t.metaKey:t.ctrlKey)?(-1==position.x&&-1==position.y&&(position.x+=1,position.y+=1),t.shiftKey?(position.x-=1,R("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,e=!0)):t.altKey&&t.shiftKey&&position.x!=plot.num_cols-1?(constants.lastx=position.x,R("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,e=!0,n=k());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=1}else if("ArrowLeft"==t.key)if(0==t.target.selectionStart||"⠳"==t.target.value.substring(t.target.selectionStart-1,t.target.selectionStart))t.preventDefault();else{(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,R("left",position.x,-1)):(position.x=0,e=!0):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,R("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=k());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=1}else if("ArrowDown"==t.key)if(position.y+1==plot.num_rows)t.preventDefault();else{(constants.isMac?t.metaKey:t.ctrlKey)?(-1==position.x&&-1==position.y&&(position.x+=1,position.y+=1),t.shiftKey?(position.y-=1,R("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,e=!0)):t.altKey&&t.shiftKey&&position.y!=plot.num_rows-1?(constants.lastx=position.x,R("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,e=!0,n=k());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=0}else if("ArrowUp"==t.key)if(t.target.selectionStart-plot.num_cols-1<0)t.preventDefault();else{(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.y+=1,R("up",position.y,-1)):(position.y=0,e=!0):t.altKey&&t.shiftKey&&0!=position.y?(constants.lastx=position.x,R("reverse-up",-1,position.y)):(position.y+=-1,e=!0,n=k());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=0}else"Tab"==t.key||t.preventDefault();e&&!n&&C(),n&&audio.playEnd()}])}else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")){constants.plotId="geom_point.points.12.1",window.position=new Position(-1,-1),window.plot=new ScatterPlot;let O=new Layer0Point,N=new Layer1Point,U="";constants.lastx=0;let Y=0;window.positionL1=new Position(Y,Y),constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;"point"==constants.chartType?("ArrowRight"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,Q("right",position.x,plot.x.length)):(position.x=plot.x.length-1,e=!0,n=V()):t.altKey&&t.shiftKey&&position.x!=plot.x.length-1?(constants.lastx=position.x,Q("reverse-right",plot.x.length,position.x)):(position.x+=1,e=!0,n=V())),"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,Q("left",position.x,-1)):(position.x=0,e=!0,n=V()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,Q("reverse-left",-1,position.x)):(position.x-=1,e=!0,n=V()))):"smooth"==constants.chartType&&(positionL1.x||(positionL1.x=Y),"ArrowRight"==t.key&&t.shiftKey&&((constants.isMac?t.metaKey:t.ctrlKey)&&"off"!=constants.sonifMode?z("right"):t.altKey&&"off"!=constants.sonifMode&&z("reverse-right")),"ArrowLeft"==t.key&&t.shiftKey&&((constants.isMac?t.metaKey:t.ctrlKey)&&"off"!=constants.sonifMode?z("left"):t.altKey&&"off"!=constants.sonifMode&&z("reverse-left"))),e&&"point"==constants.chartType&&!n&&X(),n&&audio.playEnd()}]);let G=[constants.chart,constants.brailleInput],q=0;for(let $=0;$<G.length;$++)constants.events.push([G[$],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),F(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),F(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),F(),display.announceText("Speed reset"))}]);function F(){null!=constants.autoplayId&&(constants.KillAutoplay(),audio.KillSmooth(),"reverse-left"==U?"point"==constants.chartType?Q("right",position.x,q):"smooth"==constants.chartType&&Q("right",positionL1.x,Y):"reverse-right"==U?"point"==constants.chartType?Q("left",position.x,q):"smooth"==constants.chartType&&Q("left",positionL1.x,Y):"point"==constants.chartType?Q(U,position.x,q):"smooth"==constants.chartType&&Q(U,positionL1.x,Y))}function V(){let t=!1;return"point"==constants.chartType?(position.x<0&&(position.x=0,t=!0),position.x>plot.x.length-1&&(position.x=plot.x.length-1,t=!0)):"smooth"==constants.chartType&&(positionL1.x<0&&(positionL1.x=0,t=!0),positionL1.x>plot.curvePoints.length-1&&(positionL1.x=plot.curvePoints.length-1,t=!0)),t}function X(){constants.showDisplay&&display.displayValues(),O.hasRect&&O.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones()}function j(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&("point"==constants.chartType&&O.hasRect?O.UpdatePointDisplay():"smooth"==constants.chartType&&N.hasRect&&N.UpdatePointDisplay()),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function H(){constants.showDisplayInBraille&&display.displayValues(),N.hasRect&&N.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function Q(t,e,n){U=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),constants.autoplayId&&constants.KillAutoplay(),constants.isSmoothAutoplay&&audio.KillSmooth(),"reverse-left"!=t&&"reverse-right"!=t||(position.x=e,position.L1x=e),"point"==constants.chartType?constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||position.x>plot.y.length-1?(constants.KillAutoplay(),V()):position.x==n?(constants.KillAutoplay(),j()):j()}),constants.autoPlayRate):"smooth"==constants.chartType&&(constants.autoplayId=setInterval((function(){positionL1.x+=s,positionL1.x<0||positionL1.x>plot.curvePoints.length-1?(constants.KillAutoplay(),V()):positionL1.x==n?(constants.KillAutoplay(),j()):j()}),constants.autoPlayRate))}function z(t){U=t;let e=[],n=[],s=audio.SlideBetween(positionL1.x,0,plot.curvePoints.length-1,-1,1),o=positionL1.x<0?0:positionL1.x,i=0;if("right"==t){for(let t=o;t<plot.curvePoints.length;t++)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[s,1],i=Math.abs(plot.curvePoints.length-o)/plot.curvePoints.length*3}else if("left"==t){for(let t=o;t>=0;t--)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[s,-1],i=Math.abs(o)/plot.curvePoints.length*3}else if("reverse-right"==t){for(let t=plot.curvePoints.length-1;t>=o;t--)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[1,s],i=Math.abs(plot.curvePoints.length-o)/plot.curvePoints.length*3}else if("reverse-left"==t){for(let t=0;t<=o;t++)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[-1,s],i=Math.abs(o)/plot.curvePoints.length*3}constants.isSmoothAutoplay&&audio.KillSmooth(),audio.playSmooth(e,i,n,constants.vol,"sine")}constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"smooth"==constants.chartType?(V(),"ArrowRight"==t.key?(t.preventDefault(),constants.brailleInput.setSelectionRange(positionL1.x,positionL1.x),t.target.selectionStart>t.target.value.length-2?t.preventDefault():(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(positionL1.x-=1,Q("right",positionL1.x,plot.curvePoints.length)):(positionL1.x=plot.curvePoints.length-1,e=!0,n=V()):t.altKey&&t.shiftKey&&positionL1.x!=plot.curvePoints.length-1?(Y=positionL1.x,Q("reverse-right",plot.curvePoints.length,positionL1.x)):(positionL1.x+=1,e=!0,n=V())):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(positionL1.x+=1,Q("left",positionL1.x,-1)):(positionL1.x=0,e=!0,n=V()):t.altKey&&t.shiftKey&&0!=positionL1.x?Q("reverse-left",-1,positionL1.x):(positionL1.x-=1,e=!0,n=V())):t.preventDefault()):"Tab"==t.key||t.preventDefault(),Y=positionL1.x,e&&!n&&H(),n&&audio.playEnd()}])}else if([].concat(singleMaidr.type).includes("hist")){window.position=new Position(-1,-1),window.plot=new Histogram;let J="";constants.lastx=0,constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;"ArrowRight"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(t.preventDefault(),position.x-=1,it("right",position.x,plot.plotData.length)):"ArrowRight"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(t.preventDefault(),constants.lastx=position.x,it("reverse-right",plot.bars.length,position.x)):"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(t.preventDefault(),position.x=plot.plotData.length-1,e=!0,n=et()):(t.preventDefault(),position.x+=1,e=!0,n=et()),"ArrowLeft"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(t.preventDefault(),position.x+=1,it("left",position.x,-1)):"ArrowLeft"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(t.preventDefault(),constants.lastx=position.x,it("reverse-left",-1,position.x)):"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(t.preventDefault(),position.x=0,e=!0,n=et()):(t.preventDefault(),position.x+=-1,e=!0,n=et()),e&&!n&&("off"==constants.brailleMode?nt():ot()),n&&audio.playEnd()}]);let W=[constants.chart,constants.brailleInput],Z=0;for(let at=0;at<W.length;at++)constants.events.push([W[at],"keydown",function(t){"."==t.key&&(t.preventDefault(),constants.SpeedUp(),tt(),display.announceText("Speed up")),","==t.key&&(t.preventDefault(),constants.SpeedDown(),tt(),display.announceText("Speed down")),"/"==t.key&&(t.preventDefault(),constants.SpeedReset(),tt(),display.announceText("Speed reset"))}]);function tt(){null!=constants.autoplayId&&(constants.KillAutoplay(),it("reverse-left"==J?"right":"reverse-right"==J?"left":J,position.x,Z))}function et(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.plotData.length-1&&(position.x=plot.plotData.length-1,t=!0),t}function nt(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones()}function st(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function ot(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function it(t,e,n){J=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),et()):position.x==n?(constants.KillAutoplay(),st()):st()}),constants.autoPlayRate)}}else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar")){window.position=new Position(-1,-1),window.plot=new Segmented;let lt="";constants.lastx=0,constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;constants.navigation=0,"on"==constants.brailleMode&&("Tab"==t.key||t.preventDefault()),"ArrowRight"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(position.x-=1,gt("right",position.x,plot.plotData.length)):"ArrowRight"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,gt("reverse-right",plot.plotData.length,position.x)):"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.x=plot.plotData.length-1,e=!0,n=dt()):(position.x+=1,e=!0,constants.navigation=1,n=dt()),"ArrowLeft"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(position.x+=1,gt("left",position.x,-1)):"ArrowLeft"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,gt("reverse-left",-1,position.x)):"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.x=0,e=!0,n=dt()):(position.x+=-1,e=!0,constants.navigation=1,n=dt()),"ArrowUp"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowUp"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?gt("up",position.y,plot.plotData[0].length):"ArrowUp"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,gt("reverse-up",-1,plot.plotData[0].length)):"ArrowUp"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.y=plot.plotData[0].length-1,e=!0):(position.y+=1,e=!0,constants.navigation=0,n=dt()),"ArrowDown"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowDown"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?gt("down",position.y,-1):"ArrowDown"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,gt("reverse-down",-1,position.y)):"ArrowDown"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.y=0,e=!0):(position.y+=-1,e=!0,constants.navigation=0,n=dt()),e&&!n&&("off"==constants.brailleMode?ht():yt()),n&&audio.playEnd()}]);let rt=[constants.chart,constants.brailleInput],ct=0;for(let mt=0;mt<rt.length;mt++)constants.events.push([rt[mt],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),pt(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),pt(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),pt(),display.announceText("Speed reset"))}]);function pt(){null!=constants.autoplayId&&(constants.KillAutoplay(),gt("reverse-left"==lt?"right":"reverse-right"==lt?"left":"reverse-up"==lt?"down":"reverse-down"==lt?"up":lt,position.x,ct))}function dt(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.level.length-1&&(position.x=plot.plotData.length-1,t=!0),position.y<0&&(position.y=0,t=!0),position.y>plot.fill.length-1&&(position.y=plot.fill.length-1,t=!0),t}function ht(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones()}function ut(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function yt(){constants.showDisplayInBraille&&(display.SetBraille(),display.displayValues()),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function gt(t,e,n){lt=t;let s=1;"left"!=t&&"down"!=t&&"reverse-right"!=t&&"reverse-up"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.autoplayId=setInterval((function(){"left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?(position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),dt()):position.x==n?(constants.KillAutoplay(),ut()):ut()):(position.y+=s,position.y<0||plot.plotData[0].length-1<position.y?(constants.KillAutoplay(),dt()):position.y==n?(constants.KillAutoplay(),ut()):ut())}),constants.autoPlayRate)}}else if("line"==singleMaidr.type){window.position=new Position(-1,-1),window.plot=new LinePlot;let ft=new Point,xt="";constants.lastx=0,constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,St("right",position.x,plot.pointValuesY.length)):(position.x=plot.pointValuesY.length-1,e=!0,n=_t()):t.altKey&&t.shiftKey&&position.x!=plot.pointValuesY.length-1?(constants.lastx=position.x,St("reverse-right",plot.pointValuesY.length,position.x)):(position.x+=1,e=!0,n=_t()):"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,St("left",position.x,-1)):(position.x=0,e=!0,n=_t()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,St("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=_t())),e&&!n&&Lt(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(t.preventDefault(),t.target.selectionStart>t.target.value.length-2||((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,St("right",position.x,plot.pointValuesY.length)):(position.x=plot.pointValuesY.length-1,e=!0,n=_t()):t.altKey&&t.shiftKey&&position.x!=plot.pointValues.length-1?(constants.lastx=position.x,St("reverse-right",plot.pointValuesY.length,position.x)):(position.x+=1,e=!0,n=_t()))):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,St("left",position.x,-1)):(position.x=0,e=!0,n=_t()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,St("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=_t())):"Tab"==t.key||t.preventDefault(),e&&!n&&Et(),n&&audio.playEnd()}]);let vt=[constants.chart,constants.brailleInput],Mt=0;for(let Dt=0;Dt<vt.length;Dt++)constants.events.push([vt[Dt],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),bt(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),bt(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),bt(),display.announceText("Speed reset"))}]);function bt(){null!=constants.autoplayId&&(constants.KillAutoplay(),St("reverse-left"==xt?"right":"reverse-right"==xt?"left":xt,position.x,Mt))}function _t(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.pointValuesY.length-1&&(position.x=plot.pointValuesY.length-1,t=!0),t}function Lt(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&ft.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones()}function wt(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&ft.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function Et(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&ft.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function St(t,e,n){xt=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.pointValuesY.length-1<position.x?(constants.KillAutoplay(),_t()):position.x==n?(constants.KillAutoplay(),wt()):wt()}),constants.autoPlayRate)}}}GetNextPrevFocusable(t="next"){let e='a[href], button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';constants.focusables=Array.from(document.querySelectorAll(e));let n=constants.focusables.indexOf(constants.chart),s=constants.main_container.querySelectorAll(e);for(let t=0;t<s.length;t++){let e=constants.focusables.indexOf(s[t]);e>-1&&constants.focusables.splice(e,1),n>e&&n--}}}function InitMaidr(t){if("undefined"!=typeof constants){window.singleMaidr=t,constants.chartId=singleMaidr.id,Array.isArray(singleMaidr.type)?constants.chartType=singleMaidr.type[0]:constants.chartType=singleMaidr.type,CreateChartComponents(singleMaidr),window.control=new Control,window.review=new Review,window.display=new Display,window.audio=new Audio;let e=[constants.chart,constants.brailleInput,constants.review];for(let t=0;t<e.length;t++)constants.events.push([e[t],"blur",ShouldWeDestroyMaidr]);constants.events.push([document,"keydown",KillAutoplayEvent]),this.SetEvents(),"name"in singleMaidr?display.announceText(singleMaidr.name):"title"in singleMaidr&&display.announceText(singleMaidr.title)}}function ShouldWeInitMaidr(t){"undefined"==typeof singleMaidr?InitMaidr(t):singleMaidr?t.id!==singleMaidr.id&&(DestroyMaidr(),InitMaidr(t)):InitMaidr(t)}function ShouldWeDestroyMaidr(t){setTimeout((()=>{0==constants.tabMovement?constants.tabMovement=null:(1!=constants.tabMovement&&-1!=constants.tabMovement||FocusBeforeOrAfter(),DestroyMaidr())}),0)}function FocusBeforeOrAfter(){if(1==constants.tabMovement){let t=document.createElement("div");t.setAttribute("tabindex","0"),constants.main_container.after(t),t.focus(),t.remove()}else if(-1==constants.tabMovement){let t=document.createElement("div");t.setAttribute("tabindex","0"),constants.main_container.before(t),t.focus(),t.remove()}}function DestroyMaidr(){"bar"!=constants.chartType&&"hist"!=constants.chartType||("function"==typeof plot.DeselectAll&&plot.DeselectAll(),"function"==typeof plot.UnSelectPrevious&&plot.UnSelectPrevious());for(let t=0;t<constants.events.length;t++)if(Array.isArray(constants.events[t][0]))for(let e=0;e<constants.events[t][0].length;e++)constants.events[t][0][e].removeEventListener(constants.events[t][1],constants.events[t][2]);else constants.events[t][0].removeEventListener(constants.events[t][1],constants.events[t][2]);for(let t=0;t<constants.postLoadEvents.length;t++)if(Array.isArray(constants.postLoadEvents[t][0]))for(let e=0;e<constants.postLoadEvents[t][0].length;e++)constants.postLoadEvents[t][0][e].removeEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);else constants.postLoadEvents[t][0].removeEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);constants.events=[],constants.postLoadEvents=[],constants.chartId=null,constants.chartType=null,constants.tabMovement=null,DestroyChartComponents(),window.review=null,window.display=null,window.control=null,window.plot=null,window.audio=null,window.singleMaidr=null}function KillAutoplayEvent(t){(constants.isMac?"Meta"==t.key||"ContextMenu"==t.key:"Control"==t.key)&&constants.KillAutoplay()}function SetEvents(){for(let t=0;t<constants.events.length;t++)if(Array.isArray(constants.events[t][0]))for(let e=0;e<constants.events[t][0].length;e++)constants.events[t][0][e].addEventListener(constants.events[t][1],constants.events[t][2]);else constants.events[t][0].addEventListener(constants.events[t][1],constants.events[t][2]);setTimeout((function(){for(let t=0;t<constants.postLoadEvents.length;t++)if(Array.isArray(constants.postLoadEvents[t][0]))for(let e=0;e<constants.postLoadEvents[t][0].length;e++)constants.postLoadEvents[t][0][e].addEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);else constants.postLoadEvents[t][0].addEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2])}),100)}function CreateChartComponents(){let t=document.getElementById(singleMaidr.id),e=document.createElement("div");e.id=constants.main_container_id;let n=document.createElement("div");n.id=constants.chart_container_id,t.parentNode.replaceChild(e,t),e.appendChild(t),t.parentNode.replaceChild(n,t),n.appendChild(t),t.focus(),constants.chart=t,constants.chart_container=n,constants.main_container=e,constants.chart_container.insertAdjacentHTML("beforebegin",'<div class="hidden" id="'+constants.braille_container_id+'">\n<input id="'+constants.braille_input_id+'" class="braille-input" type="text" size="'+constants.brailleDisplayLength+'" aria-brailleroledescription="" />\n</div>\n'),constants.chart_container.insertAdjacentHTML("afterend",'<br>\n<div id="'+constants.info_id+'" aria-live="assertive" aria-atomic="true">\n<p id="x"></p>\n<p id="y"></p>\n</div>\n'),document.getElementById(constants.info_id).insertAdjacentHTML("afterend",'<div id="announcements" aria-live="assertive" aria-atomic="true" class="mb-3"></div>\n'),document.getElementById(constants.info_id).insertAdjacentHTML("beforebegin",'<div id="'+constants.review_id_container+'" class="hidden sr-only sr-only-focusable"><input id="'+constants.review_id+'" type="text" readonly size="50" /></div>'),constants.chart_container.setAttribute("role","application"),constants.brailleContainer=document.getElementById(constants.braille_container_id),constants.brailleInput=document.getElementById(constants.braille_input_id),constants.infoDiv=document.getElementById(constants.info_id),constants.announceContainer=document.getElementById(constants.announcement_container_id),constants.nonMenuFocus=constants.chart,constants.endChime=document.getElementById(constants.end_chime_id),constants.review_container=document.querySelector("#"+constants.review_id_container),constants.review=document.querySelector("#"+constants.review_id),window.menu=new Menu,window.chatLLM=new ChatLLM,window.description=new Description}function DestroyChartComponents(){null!=constants.chart_container&&(null!=constants.chart&&null!=constants.chart_container.parentNode&&constants.chart_container.parentNode.replaceChild(constants.chart,constants.chart_container),constants.chart_container.remove()),null!=constants.brailleContainer&&constants.brailleContainer.remove(),null!=constants.infoDiv&&constants.infoDiv.remove(),null!=constants.announceContainer&&constants.announceContainer.remove(),null!=constants.endChime&&constants.endChime.remove(),null!=constants.review_container&&constants.review_container.remove(),"undefined"!=typeof menu&&menu.Destroy(),"undefined"!=typeof description&&description.Destroy(),constants.chart=null,constants.chart_container=null,constants.brailleContainer=null,constants.brailleInput=null,constants.infoDiv=null,constants.announceContainer=null,constants.endChime=null,constants.review_container=null,menu=null,description=null}document.addEventListener("DOMContentLoaded",(function(t){window.constants=new Constants,window.resources=new Resources,window.logError=new LogError;let e=[];"undefined"!=typeof maidr&&(Array.isArray(maidr)?e=maidr:e.push(maidr)),DestroyMaidr(),window.maidrIds=[];for(let t=0;t<e.length;t++){let n=e[t].id;maidrIds.push(n);let s=document.getElementById(n);s&&(s.setAttribute("tabindex","0"),s.addEventListener("focus",(function(n){ShouldWeInitMaidr(e[t])})))}constants.canTrack&&(window.tracker=new Tracker,document.getElementById("download_data_trigger")&&document.getElementById("download_data_trigger").addEventListener("click",(function(t){tracker.DownloadTrackerData()})),document.addEventListener("keydown",(function(t){("F5"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)||"R"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey))&&(t.preventDefault(),tracker.Delete(),location.reload(!0)),"F10"==t.key?tracker.DownloadTrackerData():plot&&tracker.LogEvent(t),document.getElementById("info")})))}));
|
|
1
|
+
class Constants{chart_container_id="chart-container";main_container_id="maidr-container";braille_container_id="braille-div";braille_input_id="braille-input";info_id="info";announcement_container_id="announcements";end_chime_id="end_chime";container_id="container";project_id="maidr";review_id_container="review_container";review_id="review";reviewSaveSpot;reviewSaveBrailleMode;chartId="";events=[];postLoadEvents=[];constructor(){}textMode="verbose";brailleMode="off";sonifMode="on";reviewMode="off";minX=0;maxX=0;minY=0;maxY=0;plotId="";chartType="";navigation=1;MAX_FREQUENCY=1e3;MIN_FREQUENCY=200;NULL_FREQUENCY=100;combinedVolMin=.25;combinedVolMax=1.25;MAX_SPEED=500;MIN_SPEED=50;DEFAULT_SPEED=250;INTERVAL=20;AUTOPLAY_DURATION=5e3;vol=.5;MAX_VOL=30;autoPlayRate=this.DEFAULT_SPEED;colorSelected="#03C809";brailleDisplayLength=32;showRect=1;hasRect=1;hasSmooth=1;duration=.3;outlierDuration=.06;autoPlayOutlierRate=50;autoPlayPointsRate=50;colorUnselected="#595959";canTrack=1;isTracking=1;visualBraille=!1;globalMinMax=!0;ariaMode="assertive";userSettingsKeys=["vol","autoPlayRate","brailleDisplayLength","colorSelected","MIN_FREQUENCY","MAX_FREQUENCY","keypressInterval","ariaMode","openAIAuthKey","geminiAuthKey","skillLevel","skillLevelOther","LLMModel","LLMPreferences","LLMOpenAiMulti","LLMGeminiMulti","autoInitLLM"];openAIAuthKey=null;geminiAuthKey=null;LLMmaxResponseTokens=1e3;playLLMWaitingSound=!0;LLMDetail="high";LLMModel="openai";LLMSystemMessage="You are a helpful assistant describing the chart to a blind person. ";skillLevel="basic";skillLevelOther="";autoInitLLM=!0;verboseText="";showDisplay=1;showDisplayInBraille=1;showDisplayInAutoplay=0;outlierInterval=null;isMac=navigator.userAgent.toLowerCase().includes("mac");control=this.isMac?"Cmd":"Ctrl";alt=this.isMac?"option":"Alt";home=this.isMac?"fn + Left arrow":"Home";end=this.isMac?"fn + Right arrow":"End";keypressInterval=2e3;tabMovement=null;debugLevel=3;canPlayEndChime=!1;manualData=!0;KillAutoplay(){this.autoplayId&&(clearInterval(this.autoplayId),this.autoplayId=null)}KillSepPlay(){this.sepPlayId&&(clearInterval(this.sepPlayId),this.sepPlayId=null)}SpeedUp(){constants.autoPlayRate-this.INTERVAL>this.MIN_SPEED&&(constants.autoPlayRate-=this.INTERVAL)}SpeedDown(){constants.autoPlayRate+this.INTERVAL<=this.MAX_SPEED&&(constants.autoPlayRate+=this.INTERVAL)}SpeedReset(){constants.autoPlayRate=constants.DEFAULT_SPEED}ConvertHexToRGBString(t){return"rgb("+parseInt(t.slice(1,3),16)+","+parseInt(t.slice(3,5),16)+","+parseInt(t.slice(5,7),16)+")"}ConvertRGBStringToHex(t){let e=t.replace(/[^\d,]/g,"").split(",");return"#"+e[0].toString(16).padStart(2,"0")+e[1].toString(16).padStart(2,"0")+e[2].toString(16).padStart(2,"0")}ColorInvert(t){let e=t.replace(/[^\d,]/g,"").split(",");return"rgb("+(255-e[0])+","+(255-e[1])+","+(255-e[2])+")"}GetBetterColor(t){-1!==t.indexOf("#")&&(t=this.ConvertHexToRGBString(t));let e=this.ColorInvert(t),n=e.replace(/[^\d,]/g,"").split(",");return n[1]<n[0]+10&&n[1]>n[0]-10&&n[2]<n[0]+10&&n[2]>n[0]-10&&(n[0]>86||n[0]<169)&&(e=this.colorSelected),e}GetStyleArrayFromString(t){return t.replaceAll(" ","").split(/[:;]/)}GetStyleStringFromArray(t){let e="";for(let n=0;n<t.length;n++)n%2==0?n!==t.length-1?e+=t[n]+": ":e+=t[n]:e+=t[n]+"; ";return e}}class Resources{constructor(){}language="en";knowledgeLevel="basic";strings={en:{basic:{upper_outlier:"Upper Outlier",lower_outlier:"Lower Outlier",min:"Minimum",max:"Maximum",25:"25%",50:"50%",75:"75%",q1:"25%",q2:"50%",q3:"75%",son_on:"Sonification on",son_off:"Sonification off",son_des:"Sonification descrete",son_comp:"Sonification compare",son_ch:"Sonification chord",son_sep:"Sonification separate",son_same:"Sonification combined",empty:"Empty",openai:"OpenAI Vision",gemini:"Gemini Pro Vision",multi:"Multiple AI",processing:"Processing Chart..."}}};GetString(t){return this.strings[this.language][this.knowledgeLevel][t]}}class Menu{whereWasMyFocus=null;constructor(){this.CreateMenu(),this.LoadDataFromLocalStorage()}menuHtml=`\n <div id="menu" class="modal hidden" role="dialog" tabindex="-1">\n <div class="modal-dialog" role="document" tabindex="0">\n <div class="modal-content">\n <div class="modal-header">\n <h2 class="modal-title">Menu</h2>\n <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n <div class="modal-body">\n <div>\n <h5 class="modal-title">Keyboard Shortcuts</h5>\n <table>\n <caption class="sr-only">Keyboard Shortcuts</caption>\n <thead>\n <tr>\n <th scope="col">Function</th>\n <th scope="col">Key</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>Move around plot</td>\n <td>Arrow keys</td>\n </tr>\n <tr>\n <td>Go to the very left right up down</td>\n <td>${constants.control} + Arrow key</td>\n </tr>\n <tr>\n <td>Select the first element</td>\n <td>${constants.control} + ${constants.home}</td>\n </tr>\n <tr>\n <td>Select the last element</td>\n <td>${constants.control} + ${constants.end}</td>\n </tr>\n <tr>\n <td>Toggle Braille Mode</td>\n <td>b</td>\n </tr>\n <tr>\n <td>Toggle Sonification Mode</td>\n <td>s</td>\n </tr>\n <tr>\n <td>Toggle Text Mode</td>\n <td>t</td>\n </tr>\n <tr>\n <td>Repeat current sound</td>\n <td>Space</td>\n </tr>\n <tr>\n <td>Auto-play outward in direction of arrow</td>\n <td>${constants.control} + Shift + Arrow key</td>\n </tr>\n <tr>\n <td>Auto-play inward in direction of arrow</td>\n <td>${constants.alt} + Shift + Arrow key</td>\n </tr>\n <tr>\n <td>Stop Auto-play</td>\n <td>${constants.control}</td>\n </tr>\n <tr>\n <td>Auto-play speed up</td>\n <td>Period</td>\n </tr>\n <tr>\n <td>Auto-play speed down</td>\n <td>Comma</td>\n </tr>\n <tr>\n <td>Open GenAI Chat</td>\n <td>${constants.isMac?constants.alt:constants.control} + Shift + ?</td>\n </tr>\n <tr>\n <td>Copy last chat message</td>\n <td>${constants.alt} + Shift + C</td>\n </tr>\n <tr>\n <td>Copy full chat history</td>\n <td>${constants.alt} + Shift + A</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <div>\n <h5 class="modal-title">Settings</h5>\n <p><input type="range" id="vol" name="vol" min="0" max="1" step=".05"><label for="vol">Volume</label></p>\n \x3c!-- <p><input type="checkbox" id="show_rect" name="show_rect"><label for="show_rect">Show Outline</label></p> //--\x3e\n <p><input type="number" min="4" max="2000" step="1" id="braille_display_length" name="braille_display_length"><label for="braille_display_length">Braille Display Size</label></p>\n <p><input type="number" min="${constants.MIN_SPEED}" max="500" step="${constants.INTERVAL}" id="autoplay_rate" name="autoplay_rate"><label for="autoplay_rate">Autoplay Rate</label></p>\n <p><input type="color" id="color_selected" name="color_selected"><label for="color_selected">Outline Color</label></p>\n <p><input type="number" min="10" max="2000" step="10" id="min_freq" name="min_freq"><label for="min_freq">Min Frequency (Hz)</label></p>\n <p><input type="number" min="20" max="2010" step="10" id="max_freq" name="max_freq"><label for="max_freq">Max Frequency (Hz)</label></p>\n <p><input type="number" min="500" max="5000" step="500" id="keypress_interval" name="keypress_interval"><label for="keypress_interval">Keypress Interval (ms)</label></p>\n <div><fieldset>\n <legend>Aria Mode</legend>\n <p><input type="radio" id="aria_mode_assertive" name="aria_mode" value="assertive" ${"assertive"==constants.ariaMode?"checked":""}><label for="aria_mode_assertive">Assertive</label></p>\n <p><input type="radio" id="aria_mode_polite" name="aria_mode" value="polite" ${"polite"==constants.ariaMode?"checked":""}><label for="aria_mode_polite">Polite</label></p>\n </fieldset></div>\n <h5 class="modal-title">LLM Settings</h5>\n <p>\n <select id="LLM_model">\n <option value="openai">OpenAI Vision</option>\n <option value="gemini">Gemini Pro Vision</option>\n <option value="multi">Multiple</option>\n </select>\n <label for="LLM_model">LLM Model</label>\n </p>\n <p id="openai_auth_key_container" class="multi_container hidden">\n <span id="openai_multi_container" class="hidden"><input type="checkbox" id="openai_multi" name="openai_multi" aria-label="Use OpenAI in Multi modal mode"></span>\n <input type="password" id="openai_auth_key"><button aria-label="Delete OpenAI key" title="Delete OpenAI key" id="delete_openai_key" class="invis_button">×</button><label for="openai_auth_key">OpenAI Authentication Key</label>\n </p>\n <p id="gemini_auth_key_container" class="multi_container hidden">\n <span id="gemini_multi_container" class="hidden"><input type="checkbox" id="gemini_multi" name="gemini_multi" aria-label="Use Gemini in Multi modal mode"></span>\n <input type="password" id="gemini_auth_key"><button aria-label="Delete Gemini key" title="Delete Gemini key" id="delete_gemini_key" class="invis_button">×</button><label for="gemini_auth_key">Gemini Authentication Key</label>\n </p>\n <p><input type="checkbox" ${constants.autoInitLLM?"checked":""} id="init_llm_on_load" name="init_llm_on_load"><label for="init_llm_on_load">Start first LLM chat chart load</label></p>\n <p>\n <select id="skill_level">\n <option value="basic">Basic</option>\n <option value="intermediate">Intermediate</option>\n <option value="expert">Expert</option>\n <option value="other">Other: describe in your own words</option>\n </select>\n <label for="skill_level">Level of skill in statistical charts</label>\n </p>\n <p id="skill_level_other_container" class="hidden"><input type="text" placeholder="Very basic" id="skill_level_other"> <label for="skill_level_other">Describe your level of skill in statistical charts</label></p>\n <p><label for="LLM_preferences">Custom instructions for the chat response</label></p>\n <p><textarea id="LLM_preferences" rows="4" cols="50" placeholder="I'm a stats undergrad and work with Python. I prefer a casual tone, and favor information accuracy over creative description; just the facts please!"></textarea></p>\n </div>\n </div>\n <div class="modal-footer">\n <p>\n <button type="button" id="save_and_close_menu" aria-labelledby="save_and_close_text"><span id="save_and_close_text">Save and Close</span></button>\n <button type="button" id="close_menu">Close</button>\n </p>\n </div>\n </div>\n </div>\n </div>\n <div id="menu_modal_backdrop" class="modal-backdrop hidden"></div>\n `;CreateMenu(){document.querySelector("body").insertAdjacentHTML("beforeend",this.menuHtml);let t=document.querySelectorAll("#close_menu, #menu .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){menu.Toggle(!1)}]);constants.events.push([document.getElementById("save_and_close_menu"),"click",function(t){menu.SaveData(),menu.Toggle(!1)}]),constants.events.push([document.getElementById("menu"),"keyup",function(t){"Esc"==t.key&&menu.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){"input"!=t.target.tagName.toLowerCase()&&"textarea"!=t.target.tagName.toLowerCase()&&"h"==t.key&&menu.Toggle(!0)}]),constants.events.push([document.getElementById("LLM_model"),"change",function(t){"openai"==t.target.value?(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.add("hidden"),document.getElementById("openai_multi_container").classList.add("hidden"),document.getElementById("gemini_multi_container").classList.add("hidden"),document.getElementById("openai_multi").checked=!0,document.getElementById("gemini_multi").checked=!1):"gemini"==t.target.value?(document.getElementById("openai_auth_key_container").classList.add("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.add("hidden"),document.getElementById("gemini_multi_container").classList.add("hidden"),document.getElementById("openai_multi").checked=!1,document.getElementById("gemini_multi").checked=!0):"multi"==t.target.value&&(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.remove("hidden"),document.getElementById("gemini_multi_container").classList.remove("hidden"),document.getElementById("openai_multi").checked=!0,document.getElementById("gemini_multi").checked=!0)}]),constants.events.push([document.getElementById("skill_level"),"change",function(t){"other"==t.target.value?document.getElementById("skill_level_other_container").classList.remove("hidden"):document.getElementById("skill_level_other_container").classList.add("hidden")}]);let e=["LLM_model","openai_multi","gemini_multi","skill_level","LLM_preferences"];for(let t=0;t<e.length;t++)constants.events.push([document.getElementById(e[t]),"change",function(t){menu.NotifyOfLLMReset()}])}Destroy(){let t=document.getElementById("menu");t&&t.remove();let e=document.getElementById("menu_modal_backdrop");e&&e.remove()}Toggle(t=!1){void 0===t&&(t=!!document.getElementById("menu").classList.contains("hidden")),t&&document.getElementById("chatLLM")&&!document.getElementById("chatLLM").classList.contains("hidden")||(t?(this.whereWasMyFocus=document.activeElement,this.PopulateData(),constants.tabMovement=0,document.getElementById("menu").classList.remove("hidden"),document.getElementById("menu_modal_backdrop").classList.remove("hidden"),document.querySelector("#menu .close").focus()):(document.getElementById("menu").classList.add("hidden"),document.getElementById("menu_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null))}PopulateData(){document.getElementById("vol").value=constants.vol,document.getElementById("autoplay_rate").value=constants.autoPlayRate,document.getElementById("braille_display_length").value=constants.brailleDisplayLength,document.getElementById("color_selected").value=constants.colorSelected,document.getElementById("min_freq").value=constants.MIN_FREQUENCY,document.getElementById("max_freq").value=constants.MAX_FREQUENCY,document.getElementById("keypress_interval").value=constants.keypressInterval,"string"==typeof constants.openAIAuthKey&&(document.getElementById("openai_auth_key").value=constants.openAIAuthKey),"string"==typeof constants.geminiAuthKey&&(document.getElementById("gemini_auth_key").value=constants.geminiAuthKey),document.getElementById("skill_level").value=constants.skillLevel,constants.skillLevelOther&&(document.getElementById("skill_level_other").value=constants.skillLevelOther),document.getElementById("LLM_model").value=constants.LLMModel,"assertive"==constants.ariaMode?(document.getElementById("aria_mode_assertive").checked=!0,document.getElementById("aria_mode_polite").checked=!1):(document.getElementById("aria_mode_polite").checked=!0,document.getElementById("aria_mode_assertive").checked=!1),"openai"==constants.LLMModel?(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.add("hidden")):"gemini"==constants.LLMModel?(document.getElementById("openai_auth_key_container").classList.add("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden")):"multi"==constants.LLMModel&&(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.remove("hidden"),document.getElementById("gemini_multi_container").classList.remove("hidden"),document.getElementById("openai_multi").checked=!1,constants.LLMOpenAiMulti&&(document.getElementById("openai_multi").checked=!0),document.getElementById("gemini_multi").checked=!1,constants.LLMGeminiMulti&&(document.getElementById("gemini_multi").checked=!0)),"other"==constants.skillLevel&&document.getElementById("skill_level_other_container").classList.remove("hidden"),constants.LLMPreferences&&(document.getElementById("LLM_preferences").value=constants.LLMPreferences),document.getElementById("LLM_reset_notification")&&document.getElementById("LLM_reset_notification").remove()}SaveData(){let t=this.ShouldLLMReset();constants.vol=document.getElementById("vol").value,constants.autoPlayRate=document.getElementById("autoplay_rate").value,constants.brailleDisplayLength=document.getElementById("braille_display_length").value,constants.colorSelected=document.getElementById("color_selected").value,constants.MIN_FREQUENCY=document.getElementById("min_freq").value,constants.MAX_FREQUENCY=document.getElementById("max_freq").value,constants.keypressInterval=document.getElementById("keypress_interval").value,constants.openAIAuthKey=document.getElementById("openai_auth_key").value,constants.geminiAuthKey=document.getElementById("gemini_auth_key").value,constants.skillLevel=document.getElementById("skill_level").value,constants.skillLevelOther=document.getElementById("skill_level_other").value,constants.LLMModel=document.getElementById("LLM_model").value,constants.LLMPreferences=document.getElementById("LLM_preferences").value,constants.LLMOpenAiMulti=document.getElementById("openai_multi").checked,constants.LLMGeminiMulti=document.getElementById("gemini_multi").checked,constants.autoInitLLM=document.getElementById("init_llm_on_load").checked,document.getElementById("aria_mode_assertive").checked?constants.ariaMode="assertive":document.getElementById("aria_mode_polite").checked&&(constants.ariaMode="polite"),this.SaveDataToLocalStorage(),this.UpdateHtml(),t&&chatLLM&&chatLLM.ResetLLM()}UpdateHtml(){constants.infoDiv.setAttribute("aria-live",constants.ariaMode),document.getElementById(constants.announcement_container_id).setAttribute("aria-live",constants.ariaMode),document.getElementById("init_llm_on_load").checked=constants.autoInitLLM}NotifyOfLLMReset(){document.getElementById("LLM_reset_notification")&&document.getElementById("LLM_reset_notification").remove(),document.getElementById("save_and_close_menu").parentElement.insertAdjacentHTML("afterend",'<p id="LLM_reset_notification">Note: Changes in LLM settings will reset any existing conversation.</p>'),document.getElementById("save_and_close_menu").setAttribute("aria-labelledby","save_and_close_text LLM_reset_notification")}ShouldLLMReset(){let t=!1;return t||constants.skillLevel==document.getElementById("skill_level").value||(t=!0),t||constants.LLMPreferences==document.getElementById("LLM_preferences").value||(t=!0),t||constants.LLMModel==document.getElementById("LLM_model").value||(t=!0),t||constants.LLMOpenAiMulti==document.getElementById("openai_multi").checked&&constants.LLMGeminiMulti==document.getElementById("gemini_multi").checked||(t=!0),t}SaveDataToLocalStorage(){let t={};for(let e=0;e<constants.userSettingsKeys.length;e++)t[constants.userSettingsKeys[e]]=constants[constants.userSettingsKeys[e]];localStorage.setItem("settings_data",JSON.stringify(t)),constants.isTracking&&(t.openAIAuthKey="hidden",t.geminiAuthKey="hidden",t.timestamp=(new Date).toISOString(),tracker.SetData("settings",t))}LoadDataFromLocalStorage(){let t=JSON.parse(localStorage.getItem("settings_data"));if(t)for(let e=0;e<constants.userSettingsKeys.length;e++)constants[constants.userSettingsKeys[e]]=t[constants.userSettingsKeys[e]];this.PopulateData(),this.UpdateHtml()}}class ChatLLM{constructor(){this.firstTime=!0,this.firstMulti=!0,this.firstOpen=!0,this.shown=!1,this.CreateComponent(),this.SetEvents(),constants.autoInitLLM&&("openai"==constants.LLMModel&&constants.openAIAuthKey||"gemini"==constants.LLMModel&&constants.geminiAuthKey||"multi"==constants.LLMModel&&constants.openAIAuthKey&&constants.geminiAuthKey)&&this.InitChatMessage()}CreateComponent(){let t=`\n <div id="chatLLM" class="modal hidden" role="dialog" tabindex="-1">\n <div class="modal-dialog" role="document" tabindex="0">\n <div class="modal-content">\n <div class="modal-header">\n <h2 id="chatLLM_title" class="modal-title">Ask a Question</h2>\n <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n <div class="modal-body">\n <div id="chatLLM_chat_history_wrapper">\n <div id="chatLLM_chat_history" aria-live="${constants.ariaMode}" aria-relevant="additions">\n </div>\n <p id="chatLLM_copy_all_wrapper"><button id="chatLLM_copy_all">Copy all to clipboard</button></p>\n </div>\n <div id="chatLLM_content">\n <p><input type="text" id="chatLLM_input" class="form-control" name="chatLLM_input" aria-labelledby="chatLLM_title" size="50"></p>\n <div class="LLM_suggestions">\n <p><button type="button">What is the title?</button></p>\n <p><button type="button">What are the high and low values?</button></p>\n <p><button type="button">What is the general shape of the chart?</button></p>\n </div>\n <div id="more_suggestions_container" class="LLM_suggestions">\n <p><button type="button">Please provide the title of this visualization, then provide a description for someone who is blind or low vision. Include general overview of axes and the data at a high-level.</button></p>\n <p><button type="button">For the visualization I shared, please provide the following (where applicable): mean, standard deviation, extreme, correlations, relational comparisons like greater than OR lesser than.</button></p>\n <p><button type="button">Based on the visualization shared, address the following: Do you observe any unforeseen trends? If yes, what? Please convey any complex multi-faceted patterns present. Can you identify any noteworthy exceptions that aren't readily apparent through non-visual methods of analysis?</button></p>\n <p><button type="button">Provide context to help explain the data depicted in this visualization based on domain-specific insight.</button></p>\n </div>\n <p><button type="button" id="chatLLM_submit">Submit</button></p>\n </div>\n </div>\n <div class="modal-footer">\n <button type="button" id="reset_chatLLM">Reset</button>\n <button type="button" id="close_chatLLM">Close</button>\n </div>\n </div>\n </div>\n </div>\n <div id="chatLLM_modal_backdrop" class="modal-backdrop hidden"></div>\n `;document.querySelector("body").insertAdjacentHTML("beforeend",t)}SetEvents(){let t=document.querySelectorAll("#close_chatLLM, #chatLLM .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){chatLLM.Toggle(!1)}]);constants.events.push([document.getElementById("chatLLM"),"keyup",function(t){"Esc"==t.key&&chatLLM.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){("?"==t.key&&(t.ctrlKey||t.metaKey)||"¿"==t.key)&&chatLLM.Toggle()}]),constants.events.push([document.getElementById("chatLLM_submit"),"click",function(t){let e=document.getElementById("chatLLM_input").value;chatLLM.DisplayChatMessage("User",e),chatLLM.Submit(e)}]),constants.events.push([document.getElementById("chatLLM_input"),"keyup",function(t){if("Enter"==t.key&&!t.shiftKey){let t=document.getElementById("chatLLM_input").value;chatLLM.DisplayChatMessage("User",t),chatLLM.Submit(t)}}]);let e=document.querySelectorAll("#chatLLM .LLM_suggestions button:not(#more_suggestions)");for(let t=0;t<e.length;t++)constants.events.push([e[t],"click",function(t){let e=t.target.innerHTML;chatLLM.DisplayChatMessage("User",e),chatLLM.Submit(e)}]);constants.events.push([document.getElementById("delete_openai_key"),"click",function(t){document.getElementById("openai_auth_key").value=""}]),constants.events.push([document.getElementById("delete_gemini_key"),"click",function(t){document.getElementById("gemini_auth_key").value=""}]),constants.events.push([document.getElementById("reset_chatLLM"),"click",function(t){chatLLM.ResetLLM()}]),constants.events.push([document.getElementById("chatLLM"),"click",function(t){chatLLM.CopyChatHistory(t)}]),constants.events.push([document.getElementById("chatLLM"),"keyup",function(t){chatLLM.CopyChatHistory(t)}])}CopyChatHistory(t){let e="";if(void 0===t)e=document.getElementById("chatLLM_chat_history").innerHTML;else if("click"==t.type)"chatLLM_copy_all"==t.target.id?e=document.getElementById("chatLLM_chat_history").innerHTML:t.target.classList.contains("chatLLM_message_copy_button")&&(e=t.target.closest("p").previousElementSibling.innerHTML);else if("keyup"==t.type)if("C"==t.key&&(t.ctrlKey||t.metaKey||t.altKey)&&t.shiftKey){t.preventDefault();let n=document.querySelector("#chatLLM_chat_history > .chatLLM_message_other:last-of-type");n&&(e=n.innerHTML)}else"A"==t.key&&(t.ctrlKey||t.metaKey||t.altKey)&&t.shiftKey&&(t.preventDefault(),e=document.getElementById("chatLLM_chat_history").innerHTML);if(""!=e){let t=document.createElement("div");t.innerHTML=e,t.querySelectorAll(".chatLLM_message_copy").forEach((t=>t.remove()));let n=this.htmlToMarkdown(t);n=n.replace(/\n{3,}/g,"\n\n");try{navigator.clipboard.writeText(n)}catch(t){console.error("Failed to copy: ",t)}return n}}htmlToMarkdown(t){let e="";const n=t=>{switch(t.tagName){case"H1":return`# ${t.textContent}`;case"H2":return`## ${t.textContent}`;case"H3":return`### ${t.textContent}`;case"H4":return`#### ${t.textContent}`;case"H5":return`##### ${t.textContent}`;case"H6":return`###### ${t.textContent}`;case"P":return t.textContent;case"DIV":return Array.from(t.childNodes).map((t=>n(t))).join("\n")+"\n\n";default:return Array.from(t.childNodes).map((t=>n(t))).join("")}};return t.nodeType===Node.ELEMENT_NODE?e+=n(t):t.nodeType===Node.TEXT_NODE&&""!==t.textContent.trim()&&(e+=t.textContent.trim()),e.trim()}async Submit(t,e=!1){let n=null;this.firstMulti=!0,(this.firstOpen||"gemini"==constants.LLMModel)&&!e&&constants.verboseText.length>0&&(t="Here is the current position in the chart; no response necessarily needed, use this info only if it's relevant to future questions: "+constants.verboseText+". My question is: "+t,this.firstOpen=!1),constants.playLLMWaitingSound&&this.WaitingSound(!0),(constants.LLMOpenAiMulti||"openai"==constants.LLMModel)&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"openai")),chatLLM.OpenAIPrompt(t,n)),(constants.LLMGeminiMulti||"gemini"==constants.LLMModel)&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"gemini")),chatLLM.GeminiPrompt(t,n))}WaitingSound(t=!0){if(constants.waitingInterval&&(clearInterval(constants.waitingInterval),constants.waitingSound=null),constants.waitingSoundOverride&&(clearTimeout(constants.waitingSoundOverride),constants.waitingSoundOverride=null),t){let t=1e3,e=440;constants.waitingInterval=setInterval((function(){audio&&chatLLM.shown&&audio.playOscillator(e,.2,0)}),t),constants.waitingSoundOverride=setTimeout((function(){chatLLM.WaitingSound(!1)}),3e4)}}InitChatMessage(){let t=resources.GetString(constants.LLMModel);this.firstTime=!1,this.DisplayChatMessage(t,resources.GetString("processing"),!0);let e=this.GetDefaultPrompt();this.Submit(e,!0)}ProcessLLMResponse(t,e){chatLLM.WaitingSound(!1);let n="",s=resources.GetString(e);if("openai"==e){n=t.choices[0].message.content;let e=this.requestJson.messages.length;this.requestJson.messages[e]={},this.requestJson.messages[e].role="assistant",this.requestJson.messages[e].content=n,t.error?(chatLLM.DisplayChatMessage(s,"Error processing request.",!0),chatLLM.WaitingSound(!1)):chatLLM.DisplayChatMessage(s,n)}else"gemini"==e&&(t.text()?(n=t.text(),chatLLM.DisplayChatMessage(s,n)):t.error||(t.error="Error processing request.",chatLLM.WaitingSound(!1)),t.error&&(chatLLM.DisplayChatMessage(s,"Error processing request.",!0),chatLLM.WaitingSound(!1)));if(constants.isTracking){let t=chatLLM.CopyChatHistory();tracker.SetData("ChatHistory",t)}}fakeLLMResponseData(){let t={};return t=this.requestJson.messages.length>2?{id:"chatcmpl-8Y44iRCRrohYbAqm8rfBbJqTUADC7",object:"chat.completion",created:1703129508,model:"gpt-4-1106-vision-preview",usage:{prompt_tokens:451,completion_tokens:16,total_tokens:467},choices:[{message:{role:"assistant",content:"A fake response from the LLM. Nice."},finish_reason:"length",index:0}]}:{id:"chatcmpl-8Y44iRCRrohYbAqm8rfBbJqTUADC7",object:"chat.completion",created:1703129508,model:"gpt-4-1106-vision-preview",usage:{prompt_tokens:451,completion_tokens:16,total_tokens:467},choices:[{message:{role:"assistant",content:"The chart you're referring to is a bar graph titled \"The Number of Diamonds"},finish_reason:"length",index:0}]},t}OpenAIPrompt(t,e=null){let n=constants.openAIAuthKey,s=chatLLM.OpenAIJson(t,e);console.log("LLM request: ",s),fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+n},body:JSON.stringify(s)}).then((t=>t.json())).then((t=>{chatLLM.ProcessLLMResponse(t,"openai")})).catch((t=>{chatLLM.WaitingSound(!1),console.error("Error:",t),chatLLM.DisplayChatMessage("OpenAI","Error processing request.",!0)}))}OpenAIJson(t,e=null){let n=constants.LLMSystemMessage;singleMaidr.type;this.requestJson||(this.requestJson={},this.requestJson.model="gpt-4-vision-preview",this.requestJson.max_tokens=constants.LLMmaxResponseTokens,this.requestJson.messages=[],this.requestJson.messages[0]={},this.requestJson.messages[0].role="system",this.requestJson.messages[0].content=n,constants.LLMPreferences&&(this.requestJson.messages[1]={},this.requestJson.messages[1].role="system",this.requestJson.messages[1].content=constants.LLMPreferences));let s=this.requestJson.messages.length;return this.requestJson.messages[s]={},this.requestJson.messages[s].role="user",this.requestJson.messages[s].content=e?[{type:"text",text:t},{type:"image_url",image_url:{url:e}}]:t,this.requestJson}async GeminiPrompt(t,e=null){try{null==e?e=constants.LLMImage:constants.LLMImage=e,constants.LLMImage=e;const{GoogleGenerativeAI:n}=await import("https://esm.run/@google/generative-ai"),s=constants.geminiAuthKey,o=new n(s).getGenerativeModel({model:"gemini-pro-vision"});let i=constants.LLMSystemMessage;constants.LLMPreferences&&(i+=constants.LLMPreferences),i+="\n\n"+t;const a={inlineData:{data:e,mimeType:"image/png"}};console.log("LLM request: ",i,a);const l=await o.generateContent([i,a]);console.log(l.response.text()),chatLLM.ProcessLLMResponse(l.response,"gemini")}catch(t){throw chatLLM.WaitingSound(!1),chatLLM.DisplayChatMessage("Gemini","Error processing request.",!0),console.error("Error in GeminiPrompt:",t),t}}DisplayChatMessage(t="User",e="",n=!1){let s="h3";if(!n&&"multi"==constants.LLMModel&&"User"!=t){if(this.firstMulti){let t=`\n <div class="chatLLM_message chatLLM_message_other">\n <h3 class="chatLLM_message_user">${resources.GetString("multi")} Responses</h3>\n </div>\n `;this.RenderChatMessage(t),this.firstMulti=!1}s="h4"}let o=`\n <div class="chatLLM_message ${"User"==t?"chatLLM_message_self":"chatLLM_message_other"}">\n <${s} class="chatLLM_message_user">${t}</${s}>\n <p class="chatLLM_message_text">${e}</p>\n </div>\n `;"User"!=t&&e!=resources.GetString("processing")&&(o+='\n <p class="chatLLM_message_copy"><button class="chatLLM_message_copy_button">Copy</button></p>\n '),this.RenderChatMessage(o)}RenderChatMessage(t){document.getElementById("chatLLM_chat_history").insertAdjacentHTML("beforeend",t),document.getElementById("chatLLM_input").value="",document.getElementById("chatLLM_chat_history").scrollTop=document.getElementById("chatLLM_chat_history").scrollHeight}ResetLLM(){document.getElementById("chatLLM_chat_history").innerHTML="",this.requestJson=null,this.firstTime=!0,(constants.autoInitLLM||chatLLM.shown)&&chatLLM.InitChatMessage()}Destroy(){let t=document.getElementById("chatLLM");t&&t.remove();let e=document.getElementById("chatLLM_modal_backdrop");e&&e.remove()}Toggle(t){void 0===t&&(t=!!document.getElementById("chatLLM").classList.contains("hidden")),chatLLM.shown=t,t?(this.whereWasMyFocus=document.activeElement,constants.tabMovement=0,document.getElementById("chatLLM").classList.remove("hidden"),document.getElementById("chatLLM_modal_backdrop").classList.remove("hidden"),document.querySelector("#chatLLM .close").focus(),this.firstTime&&this.InitChatMessage()):(document.getElementById("chatLLM").classList.add("hidden"),document.getElementById("chatLLM_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null,this.firstOpen=!0)}async ConvertSVGtoJPG(t,e){let n=document.getElementById(t);return new Promise(((t,s)=>{var o=document.createElement("canvas"),i=o.getContext("2d"),a=(new XMLSerializer).serializeToString(n);a.startsWith("<svg xmlns")||(a=`<svg xmlns="http://www.w3.org/2000/svg" ${a.slice(4)}`);var l=n.viewBox.baseVal||n.getBoundingClientRect();o.width=l.width,o.height=l.height;var r=new Image;r.onload=function(){i.drawImage(r,0,0,l.width,l.height);var n=o.toDataURL("image/jpeg",.9);if("openai"==e)t(n);else if("gemini"==e){let e=n.split(",")[1];t(e)}URL.revokeObjectURL(p)},r.onerror=function(){s(new Error("Error loading SVG"))};var c=new Blob([a],{type:"image/svg+xml;charset=utf-8"}),p=URL.createObjectURL(c);r.src=p}))}GetDefaultPrompt(){let t="Describe this chart to a blind person";return constants.skillLevel?"other"==constants.skillLevel&&constants.skillLevelOther?t+=" who has a "+constants.skillLevelOther+" understanding of statistical charts. ":t+=" who has a "+constants.skillLevel+" understanding of statistical charts. ":t+=" who has a basic understanding of statistical charts. ",t+="Here is chart in png format",singleMaidr&&(t+=" and raw data in json format: \n",t+=JSON.stringify(singleMaidr)),t}}class Description{constructor(){}CreateComponent(){document.querySelector("body").insertAdjacentHTML("beforeend",'\n <div id="description" class="modal hidden" role="dialog" tabindex="-1">\n <div class="modal-dialog" role="document" tabindex="0">\n <div class="modal-content">\n <div class="modal-header">\n <h2 id="desc_title" class="modal-title">Description</h2>\n <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n <div class="modal-body">\n <div id="desc_content">\n content here\n </div>\n <div id="desc_table">\n </div>\n </div>\n <div class="modal-footer">\n <button type="button" id="close_desc">Close</button>\n </div>\n </div>\n </div>\n </div>\n <div id="desc_modal_backdrop" class="modal-backdrop hidden"></div>\n\n ');let t=document.querySelectorAll("#close_desc, #description .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){description.Toggle(!1)}]);constants.events.push([document.getElementById("description"),"keyup",function(t){"Esc"==t.key&&description.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){"d"==t.key&&description.Toggle(!0)}])}Destroy(){let t=document.getElementById("menu");t&&t.remove();let e=document.getElementById("desc_modal_backdrop");e&&e.remove()}Toggle(t=!1){void 0===t&&(t=!!document.getElementById("description").classList.contains("hidden")),t?(this.whereWasMyFocus=document.activeElement,constants.tabMovement=0,this.PopulateData(),document.getElementById("description").classList.remove("hidden"),document.getElementById("desc_modal_backdrop").classList.remove("hidden"),document.querySelector("#description .close").focus()):(document.getElementById("description").classList.add("hidden"),document.getElementById("desc_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null)}PopulateData(){let t="",e="";"bar"==constants.chartType?e="Bar chart":"heat"==constants.chartType?e="Heatmap":"box"==constants.chartType?e="Box plot":"scatter"==constants.chartType?e="Scatter plot":"line"==constants.chartType?e="Line chart":"hist"==constants.chartType&&(e="Histogram"),e&&(t+=`<p>Type: ${e}</p>`),null!=plot.title&&(t+=`<p>Title: ${plot.title}</p>`),null!=plot.subtitle&&(t+=`<p>Subtitle: ${plot.subtitle}</p>`),null!=plot.caption&&(t+=`<p>Caption: ${plot.caption}</p>`);let n="",s=null,o=null,i=null,a=null,l=0,r=0,c=0,p=0;if("bar"==constants.chartType&&(null!=plot.plotLegend.x&&(s=plot.plotLegend.x,r+=1),null!=plot.plotLegend.y&&(o=plot.plotLegend.y,p+=1),null!=plot.columnLabels&&(i=plot.columnLabels,p+=1),null!=plot.plotData&&(a=[],a[0]=plot.plotData,l=plot.plotData.length,c=1,r+=l,p+=c)),null!=a){if(n+="<table>",null!=s||null!=i){if(n+="<thead>",null!=s&&(n+="<tr>",null!=o&&(n+="<td></td>"),n+=`<th scope="col" colspan="${l}">${s}</th>`,n+="</tr>"),null!=i){n+="<tr>",null!=o&&(n+="<td></td>");for(let t=0;t<l;t++)n+=`<th scope="col">${i[t]}</th>`;n+="</tr>"}n+="</thead>"}if(c>0){n+="<tbody>";for(let t=0;t<c;t++){n+="<tr>",null!=o&&0==t&&(n+=`<th scope="row" rowspan="${c}">${o}</th>`);for(let e=0;e<l;e++)n+=`<td>${a[t][e]}</td>`;n+="</tr>"}n+="</tbody>"}n+="</table>"}document.getElementById("desc_title").innerHTML=e+" description",document.getElementById("desc_content").innerHTML=t,document.getElementById("desc_table").innerHTML=n}}class Position{constructor(t=0,e=0,n=-1){this.x=t,this.y=e,this.z=n}}class Helper{static containsObject(t,e){for(let n=0;n<e.length;n++)if(e[n]===t)return!0;return!1}}class Tracker{constructor(){this.DataSetup(),constants.isTracking=!0}DataSetup(){if(this.GetTrackerData());else{let t={};t.userAgent=Object.assign(navigator.userAgent),t.vendor=Object.assign(navigator.vendor),t.language=Object.assign(navigator.language),t.platform=Object.assign(navigator.platform),t.events=[],t.settings=[],this.SaveTrackerData(t),this.SaveSettings()}}DownloadTrackerData(){let t=document.createElement("a"),e=this.GetTrackerData(),n=new Blob([JSON.stringify(e)],{type:"text/plain"});t.href=URL.createObjectURL(n),t.download="tracking.json",t.click()}SaveTrackerData(t){localStorage.setItem(constants.project_id,JSON.stringify(t))}GetTrackerData(){return JSON.parse(localStorage.getItem(constants.project_id))}Delete(){localStorage.removeItem(constants.project_id),this.data=null,constants.debugLevel>0&&console.log("tracking data cleared"),this.DataSetup()}SaveSettings(){let t=JSON.parse(localStorage.getItem("settings_data"));t&&(t.openAIAuthKey="hidden",t.geminiAuthKey="hidden",this.SetData("settings",t))}LogEvent(t){let e={};if(e.timestamp=Object.assign(t.timeStamp),e.time=Date().toString(),e.key=Object.assign(t.key),e.altKey=Object.assign(t.altKey),e.ctrlKey=Object.assign(t.ctrlKey),e.shiftKey=Object.assign(t.shiftKey),t.path&&(e.focus=Object.assign(t.path[0].tagName)),this.isUndefinedOrNull(constants.position)||(e.position=Object.assign(constants.position)),this.isUndefinedOrNull(constants.minX)||(e.min_x=Object.assign(constants.minX)),this.isUndefinedOrNull(constants.maxX)||(e.max_x=Object.assign(constants.maxX)),this.isUndefinedOrNull(constants.minY)||(e.min_y=Object.assign(constants.minY)),this.isUndefinedOrNull(constants.MAX_FREQUENCY)||(e.max_frequency=Object.assign(constants.MAX_FREQUENCY)),this.isUndefinedOrNull(constants.MIN_FREQUENCY)||(e.min_frequency=Object.assign(constants.MIN_FREQUENCY)),this.isUndefinedOrNull(constants.NULL_FREQUENCY)||(e.null_frequency=Object.assign(constants.NULL_FREQUENCY)),this.isUndefinedOrNull(constants.MAX_SPEED)||(e.max_speed=Object.assign(constants.MAX_SPEED)),this.isUndefinedOrNull(constants.MIN_SPEED)||(e.min_speed=Object.assign(constants.MIN_SPEED)),this.isUndefinedOrNull(constants.INTERVAL)||(e.interval=Object.assign(constants.INTERVAL)),this.isUndefinedOrNull(constants.vol)||(e.volume=Object.assign(constants.vol)),this.isUndefinedOrNull(constants.autoPlayRate)||(e.autoplay_rate=Object.assign(constants.autoPlayRate)),this.isUndefinedOrNull(constants.colorSelected)||(e.color=Object.assign(constants.colorSelected)),this.isUndefinedOrNull(constants.brailleDisplayLength)||(e.braille_display_length=Object.assign(constants.brailleDisplayLength)),this.isUndefinedOrNull(constants.duration)||(e.tone_duration=Object.assign(constants.duration)),this.isUndefinedOrNull(constants.autoPlayOutlierRate)||(e.autoplay_outlier_rate=Object.assign(constants.autoPlayOutlierRate)),this.isUndefinedOrNull(constants.autoPlayPointsRate)||(e.autoplay_points_rate=Object.assign(constants.autoPlayPointsRate)),this.isUndefinedOrNull(constants.textMode)||(e.text_mode=Object.assign(constants.textMode)),this.isUndefinedOrNull(constants.sonifMode)||(e.sonification_mode=Object.assign(constants.sonifMode)),this.isUndefinedOrNull(constants.brailleMode)||(e.braille_mode=Object.assign(constants.brailleMode)),this.isUndefinedOrNull(constants.chartType)||(e.chart_type=Object.assign(constants.chartType)),!this.isUndefinedOrNull(constants.infoDiv.innerHTML)){let t=Object.assign(constants.infoDiv.innerHTML);t=t.replaceAll(/<[^>]*>?/gm,""),e.text_display=t}this.isUndefinedOrNull(location.href)||(e.location=Object.assign(location.href));let n="",s="",o="",i="",a="",l="";if("bar"==constants.chartType)this.isUndefinedOrNull(plot.columnLabels[position.x])||(n=plot.columnLabels[position.x]),this.isUndefinedOrNull(plot.plotLegend.x)||(o=plot.plotLegend.x),this.isUndefinedOrNull(plot.plotLegend.y)||(i=plot.plotLegend.y),this.isUndefinedOrNull(plot.plotData[position.x])||(a=plot.plotData[position.x]);else if("heat"==constants.chartType)this.isUndefinedOrNull(plot.x_labels[position.x])||(n=plot.x_labels[position.x].trim()),this.isUndefinedOrNull(plot.y_labels[position.y])||(s=plot.y_labels[position.y].trim()),this.isUndefinedOrNull(plot.x_group_label)||(o=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),this.isUndefinedOrNull(plot.values)||this.isUndefinedOrNull(plot.values[position.x][position.y])||(a=plot.values[position.x][position.y]),this.isUndefinedOrNull(plot.group_labels[2])||(l=plot.group_labels[2]);else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.x:position.y,e="vert"==constants.plotOrientation?position.y:position.x,l=plot.sections[e];this.isUndefinedOrNull(plot.x_group_label)||(o=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),"vert"==constants.plotOrientation?t>-1&&e>-1&&(this.isUndefinedOrNull(l)||(s=l),this.isUndefinedOrNull(plot.x_labels[position.x])||(n=plot.x_labels[position.x]),this.isUndefinedOrNull(plot.plotData[t][l])||(a=plot.plotData[t][l])):t>-1&&e>-1&&(this.isUndefinedOrNull(l)||(n=l),this.isUndefinedOrNull(plot.y_labels[position.y])||(s=plot.y_labels[position.y]),this.isUndefinedOrNull(plot.plotData[t][l])||(a=plot.plotData[t][l]))}else"point"==constants.chartType&&(this.isUndefinedOrNull(plot.x_group_label)||(o=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),this.isUndefinedOrNull(plot.x[position.x])||(n=plot.x[position.x]),this.isUndefinedOrNull(plot.y[position.x])||(s=plot.y[position.x]),a=[n,s]);e.x_tickmark=Object.assign(n),e.y_tickmark=Object.assign(s),e.x_label=Object.assign(o),e.y_label=Object.assign(i),e.value=Object.assign(a),e.fill_value=Object.assign(l),this.SetData("events",e)}SetData(t,e){let n=this.GetTrackerData();["events","ChatHistory","settings"].includes(t)?(n[t]||(n[t]=[]),n[t].push(e)):n[t]=e,this.SaveTrackerData(n)}isUndefinedOrNull(t){try{return null==t}catch{return!0}}}class Review{constructor(){}ToggleReviewMode(t=!0){t?(constants.reviewSaveSpot=document.activeElement,constants.review_container.classList.remove("hidden"),constants.reviewSaveBrailleMode=constants.brailleMode,constants.review.focus(),display.announceText("Review on")):(constants.review_container.classList.add("hidden"),"on"==constants.reviewSaveBrailleMode?display.toggleBrailleMode("on"):constants.reviewSaveSpot.focus(),display.announceText("Review off"))}}class LogError{constructor(){}LogAbsentElement(t){console.log(t,"not found. Visual highlighting is turned off.")}LogCriticalElement(t){consolelog(t,"is critical. MAIDR unable to run")}LogDifferentLengths(t,e){console.log(t,"and",e,"do not have the same length. Visual highlighting is turned off.")}LogTooManyElements(t,e){console.log("Too many",t,"elements. Only the first",e,"will be highlighted.")}LogNotArray(t){console.log(t,"is not an array. Visual highlighting is turned off.")}}class Audio{constructor(){this.AudioContext=window.AudioContext||window.webkitAudioContext,this.audioContext=new AudioContext,this.compressor=this.compressorSetup(this.audioContext)}compressorSetup(){let t=this.audioContext.createDynamicsCompressor();t.threshold.value=-50,t.knee.value=40,t.ratio.value=12,t.attack.value=0,t.release.value=.25;let e=this.audioContext.createGain();return e.gain.value=constants.vol,t.connect(e),e.connect(this.audioContext.destination),t}playTone(t=null){let e=constants.duration,n=constants.vol;null!=t&&null!=t.volScale&&(n=t.volScale*constants.vol);let s=0,o=0,i=0,a=0,l="sine";if("bar"==constants.chartType)o=plot.plotData[position.x],s=position.x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1);else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.x:position.y,e=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);o=Array.isArray(plot.plotData[t][e])?plot.plotData[t][e][position.z]:plot.plotData[t][e],null!=plot.plotData[t][e]?"vert"==constants.plotOrientation?(i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(o,constants.minY,constants.maxY,-1,1)):(i=this.SlideBetween(o,constants.minX,constants.maxX,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(o,constants.minX,constants.maxX,-1,1)):(i=constants.MIN_FREQUENCY,a=0)}else if("heat"==constants.chartType)o=plot.data[position.y][position.x],s=position.x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1);else if("point"==constants.chartType||"smooth"==constants.chartType){constants.globalMinMax=!0;let t=constants.minY,e=constants.maxY;"smooth"==constants.chartType&&(t=plot.curveMinY,e=plot.curveMaxY),constants.globalMinMax&&(t=Math.min(constants.minY,plot.curveMinY),e=Math.max(constants.maxY,plot.curveMaxY)),"point"==constants.chartType?(o=plot.y[position.x][position.z],n=1==plot.max_count?constants.vol:this.SlideBetween(plot.points_count[position.x][position.z],1,plot.max_count,constants.vol,constants.MAX_VOL),s=position.x,i=this.SlideBetween(o,t,e,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,t,e,-1,1)):"smooth"==constants.chartType&&(o=plot.curvePoints[positionL1.x],s=positionL1.x,i=this.SlideBetween(o,t,e,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,t,e,-1,1))}else if("hist"==constants.chartType)o=plot.plotData[position.x].y,s=plot.plotData[position.x].x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1);else if("line"==constants.chartType)o=plot.pointValuesY[position.x],s=position.x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1);else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType){if(o=plot.plotData[position.x][position.y],0==o)return void this.PlayNull();Array.isArray(o)&&(o=o[position.z]),s=position.x,i=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),a=this.SlideBetween(s,constants.minX,constants.maxX,-1,1),l=["triangle","square","sawtooth","sine"][position.y]}if(constants.debugLevel>5&&(console.log("will play tone at freq",i),"box"==constants.chartType?console.log("based on",constants.minY,"<",o,"<",constants.maxY," | freq min",constants.MIN_FREQUENCY,"max",constants.MAX_FREQUENCY):console.log("based on",constants.minX,"<",o,"<",constants.maxX," | freq min",constants.MIN_FREQUENCY,"max",constants.MAX_FREQUENCY)),"box"==constants.chartType){let t=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);"lower_outlier"!=t&&"upper_outlier"!=t||(e=constants.outlierDuration)}if(this.playOscillator(i,e,a,n,l),"box"==constants.chartType){let t=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);if("q1"==t||"q2"==t||"q3"==t){let t=i/2;this.playOscillator(t,e,a,constants.vol/4,"triangle")}}else"heat"==constants.chartType&&0==o&&this.PlayNull()}playOscillator(t,e,n,s=1,o="sine"){const i=this.audioContext.currentTime,a=this.audioContext.createOscillator();a.type=o,a.frequency.value=parseFloat(t),a.start();const l=this.audioContext.createGain();l.gain.setValueCurveAtTime([.5*s,1*s,.5*s,.5*s,.5*s,.1*s,1e-4*s],i,e);const r=new PannerNode(this.audioContext,{panningModel:"HRTF",distanceModel:"linear",positionX:position.x,positionY:position.y,positionZ:1,plotOrientationX:0,plotOrientationY:0,plotOrientationZ:-1,refDistance:1,maxDistance:1e4,rolloffFactor:10,coneInnerAngle:40,coneOuterAngle:50,coneOuterGain:.4}),c=this.audioContext.createStereoPanner();c.pan.value=n,a.connect(l),l.connect(c),c.connect(r),r.connect(this.compressor),setTimeout((()=>{r.disconnect(),l.disconnect(),a.stop(),a.disconnect()}),1e3*e*2)}playSmooth(t=[600,500,400,300],e=2,n=[-1,0,1],s=1,o="sine"){let i=new Array(3*t.length).fill(.5*s);i.push(1e-4*s);const a=this.audioContext.currentTime,l=this.audioContext.createOscillator();l.type=o,l.frequency.setValueCurveAtTime(t,a,e),l.start(),constants.isSmoothAutoplay=!0,this.smoothGain=this.audioContext.createGain(),this.smoothGain.gain.setValueCurveAtTime(i,a,e);const r=new PannerNode(this.audioContext,{panningModel:"HRTF",distanceModel:"linear",positionX:position.x,positionY:position.y,positionZ:1,plotOrientationX:0,plotOrientationY:0,plotOrientationZ:-1,refDistance:1,maxDistance:1e4,rolloffFactor:10,coneInnerAngle:40,coneOuterAngle:50,coneOuterGain:.4}),c=this.audioContext.createStereoPanner();c.pan.setValueCurveAtTime(n,a,e),l.connect(this.smoothGain),this.smoothGain.connect(c),c.connect(r),r.connect(this.compressor),constants.smoothId=setTimeout((()=>{r.disconnect(),this.smoothGain.disconnect(),l.stop(),l.disconnect(),constants.isSmoothAutoplay=!1}),1e3*e*2)}PlayNull(){let t=constants.NULL_FREQUENCY,e=constants.duration,n=constants.vol,s="triangle";this.playOscillator(t,e,0,n,s),setTimeout((function(o){o.playOscillator(23*t/24,e,0,n,s)}),Math.round(e/5*1e3),this)}playEnd(){if(constants.canPlayEndChime){let t=constants.endChime.cloneNode(!0);t.play(),t=null}}KillSmooth(){constants.smoothId&&(this.smoothGain.gain.cancelScheduledValues(0),this.smoothGain.gain.exponentialRampToValueAtTime(1e-4,this.audioContext.currentTime+.03),clearTimeout(constants.smoothId),constants.isSmoothAutoplay=!1)}SlideBetween(t,e,n,s,o){t=Number(t),e=Number(e),n=Number(n),s=Number(s);let i=(t-e)/(n-e)*((o=Number(o))-s)+s;return 0==e&&0==n&&(i=0),i}}class Display{constructor(){this.infoDiv=constants.infoDiv,this.x={},this.x.id="x",this.x.textBase="x-value: ",this.y={},this.y.id="y",this.y.textBase="y-value: ",this.boxplotGridPlaceholders=[resources.GetString("lower_outlier"),resources.GetString("min"),resources.GetString("25"),resources.GetString("50"),resources.GetString("75"),resources.GetString("max"),resources.GetString("upper_outlier")]}toggleTextMode(){"off"==constants.textMode?constants.textMode="terse":"terse"==constants.textMode?constants.textMode="verbose":"verbose"==constants.textMode&&(constants.textMode="off"),this.announceText('<span aria-hidden="true">Text mode:</span> '+constants.textMode)}toggleBrailleMode(t){if(position.x<0&&(position.x=0),position.y<0&&(position.y=0),"point"!=constants.chartType){if(void 0===t&&(void 0===constants.brailleMode?(constants.brailleMode="off",t="on"==constants.brailleMode):(t="on"==constants.brailleMode?"off":"on",constants.brailleMode=t)),"on"==t){if("box"==constants.chartType&&("vert"!=constants.plotOrientation&&-1==position.x&&position.y==plot.plotData.length?(position.x+=1,position.y-=1):"vert"==constants.plotOrientation&&0==position.x&&(position.y,plot.plotData[0].length)),constants.brailleMode="on",document.getElementById(constants.braille_container_id).classList.remove("hidden"),constants.brailleInput.focus(),constants.brailleInput.setSelectionRange(position.x,position.x),this.SetBraille(),"heat"==constants.chartType){let t=position.y*(plot.num_cols+1)+position.x;constants.brailleInput.setSelectionRange(t,t)}-1==position.x&&-1==position.y&&constants.brailleInput.setSelectionRange(0,0)}else constants.brailleMode="off",document.getElementById(constants.braille_container_id).classList.add("hidden"),constants.review_container?constants.review_container.classList.contains("hidden")?constants.chart.focus():constants.review.focus():constants.chart.focus();this.announceText("Braille "+constants.brailleMode)}else this.announceText("Braille is not supported in point layer.")}toggleSonificationMode(){"point"==constants.chartType||"stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType?"off"==constants.sonifMode?(constants.sonifMode="on",this.announceText(resources.GetString("son_sep"))):"on"==constants.sonifMode?(constants.sonifMode="same",this.announceText(resources.GetString("son_same"))):"same"==constants.sonifMode&&(constants.sonifMode="off",this.announceText(resources.GetString("son_off"))):"off"==constants.sonifMode?(constants.sonifMode="on",this.announceText(resources.GetString("son_on"))):(constants.sonifMode="off",this.announceText(resources.GetString("son_off")))}changeChartLayer(t="down"){let e=maidr.type;if(Array.isArray(e)){let n=e.indexOf(constants.chartType);"down"==t?0==n||(constants.chartType=e[n-1],this.announceText("Switched to "+constants.chartType)):n==e.length-1||(constants.chartType=e[n+1],this.announceText("Switched to "+constants.chartType))}"point"==constants.chartType?position.x=Math.round((plot.x.length-1)*positionL1.x/(plot.curvePoints.length-1)):"smooth"==constants.chartType&&(positionL1.x=Math.round((plot.curvePoints.length-1)*position.x/(plot.x.length-1)))}announceText(t){this.displayInfo("announce",t,constants.announceContainer)}UpdateBraillePos(){if("bar"==constants.chartType||"hist"==constants.chartType||"line"==constants.chartType)constants.brailleInput.setSelectionRange(position.x,position.x);else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType){let t=null;t=position.y<plot.plotData[0].length-1?position.x:position.x*(plot.fill.length+1)+position.y,constants.brailleInput.setSelectionRange(t,t)}else if("heat"==constants.chartType){let t=position.y*(plot.num_cols+1)+position.x;constants.brailleInput.setSelectionRange(t,t)}else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.y:position.x,e=this.boxplotGridPlaceholders[t],n=!1,s=0;if(!constants.brailleData)throw"Braille data not set up, cannot move cursor in braille, sorry.";for(let t=0;t<constants.brailleData.length;t++){if("blank"!=constants.brailleData[t].type&&resources.GetString(constants.brailleData[t].type)==e){n=!0;break}s+=constants.brailleData[t].numChars}n||(s=0),constants.brailleInput.setSelectionRange(s,s)}else("smooth"==singleMaidr.type||singleMaidr.type.includes("smooth"))&&constants.brailleInput.setSelectionRange(positionL1.x,positionL1.x)}displayValues(){let t="",e="",n="";if("bar"==constants.chartType)plot.columnLabels[position.x]&&(plot.plotLegend.x.length>0&&(e+=plot.plotLegend.x+" is "),e+=plot.columnLabels[position.x]+", "),plot.plotData[position.x]&&(plot.plotLegend&&(e+=plot.plotLegend.y+" is "),e+=plot.plotData[position.x]),n+="<p>"+plot.columnLabels[position.x]+" "+plot.plotData[position.x]+"</p>\n",e="<p>"+e+"</p>\n";else if("heat"==constants.chartType)1==constants.navigation?(e+=plot.x_group_label+" "+plot.x_labels[position.x]+", "+plot.y_group_label+" "+plot.y_labels[position.y]+", "+plot.fill+" is ",e+=plot.data[position.y][position.x]):(e+=plot.y_group_label+" "+plot.y_labels[position.y]+", "+plot.x_group_label+" "+plot.x_labels[position.x]+", "+plot.fill+" is ",e+=plot.data[position.y][position.x]),1==constants.navigation?n+="<p>"+plot.x_labels[position.x]+", "+plot.data[position.y][position.x]+"</p>\n":n+="<p>"+plot.y_labels[position.y]+", "+plot.data[position.y][position.x]+"</p>\n",e="<p>"+e+"</p>\n";else if("box"==constants.chartType){let t=0,s=1,o=!1,i="vert"==constants.plotOrientation?position.x:position.y,a=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);"lower_outlier"!=a&&"upper_outlier"!=a||(o=!0),null==plot.plotData[i][a]?(t="",o&&(s=0)):o?(t=plot.plotData[i][a].join(", "),s=plot.plotData[i][a].length):t=plot.plotData[i][a],constants.navigation?plot.x_group_label&&(e+=plot.x_group_label):constants.navigation||plot.y_group_label&&(e+=plot.y_group_label),constants.navigation?plot.x_labels[i]?(e+=" is ",n+=plot.x_labels[i]+", ",e+=plot.x_labels[i]+", "):e+=", ":constants.navigation||(plot.y_labels[i]?(e+=" is ",n+=plot.y_labels[i]+", ",e+=plot.y_labels[i]+", "):e+=", "),o&&(n+=s+" ",e+=s+" "),e+=resources.GetString(a),1==s?e+=" is ":(e+="s ",s>1&&(e+=" are ")),(o||constants.navigation&&"horz"==constants.plotOrientation||!constants.navigation&&"vert"==constants.plotOrientation)&&(n+=resources.GetString(a),1!=s&&(n+="s"),n+=" "),null!=plot.plotData[i][a]||o?(n+=t,e+=t):(n+="empty",e+="empty"),e="<p>"+e+"</p>\n",n="<p>"+n+"</p>\n"}else[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")?("point"==constants.chartType?(e+=plot.x_group_label+" "+plot.x[position.x]+", "+plot.y_group_label+" ["+plot.y[position.x].join(", ")+"]",n+="<p>"+plot.x[position.x]+", ["+plot.y[position.x].join(", ")+"]</p>\n"):"smooth"==constants.chartType&&(e+=plot.x_group_label+" "+plot.curveX[positionL1.x]+", "+plot.y_group_label+" "+plot.curvePoints[positionL1.x],n+="<p>"+plot.curvePoints[positionL1.x]+"<p>\n"),e="<p>"+e+"</p>\n"):"hist"==constants.chartType?(n="<p>"+plot.plotData[position.x].x+", "+plot.plotData[position.x].y+"</p>\n",e="<p>",plot.legendX&&(e=plot.legendX+" is "),e+=plot.plotData[position.x].xmin,e+=" through "+plot.plotData[position.x].xmax+", ",plot.legendY&&(e+=plot.legendY+" is "),e+=plot.plotData[position.x].y):"line"==constants.chartType?(plot.plotLegend&&(e+=plot.plotLegend.x+" is "),e+=plot.pointValuesX[position.x]+", ",plot.plotLegend&&plot.plotLegend.y,e+=plot.pointValuesY[position.x],n+="<p>"+plot.pointValuesX[position.x]+", "+plot.pointValuesY[position.x]+"</p>\n",e="<p>"+e+"</p>\n"):"stacked_bar"!=constants.chartType&&"stacked_normalized_bar"!=constants.chartType&&"dodged_bar"!=constants.chartType||(plot.plotLegend&&(e+=plot.plotLegend.x+" is "),e+=plot.level[position.x]+", ",plot.plotLegend&&(e+=plot.plotLegend.y+" is "),e+=plot.fill[position.y]+", ",e+="value is "+plot.plotData[position.x][position.y],1==constants.navigation?n+="<p>"+plot.level[position.x]+" is "+plot.plotData[position.x][position.y]+"</p>\n":n+="<p>"+plot.fill[position.y]+" is "+plot.plotData[position.x][position.y]+"</p>\n",e="<p>"+e+"</p>\n");"verbose"==constants.textMode?t=e:"terse"==constants.textMode&&(t=n),constants.verboseText=e,constants.infoDiv&&(constants.infoDiv.innerHTML=t),constants.review&&(t.length>0?constants.review.value=t.replace(/<[^>]*>?/gm,""):constants.review.value=e)}displayInfo(t,e,n=constants.infoDiv){let s="";if("announce"==t)e&&(s=e);else if(t)if(e){if("terse"==constants.textMode)s=e;else if("verbose"==constants.textMode){s=t.charAt(0).toUpperCase()+t.slice(1)+" is "+e}}else{s="Plot does not have "+(["a","e","i","o","u"].includes(t.charAt(0))?"an":"a")+" "+t}if(s.length>0){n.innerHTML=null;let t=document.createElement("p");t.innerHTML=s,n.appendChild(t)}}SetBraille(){let t=[];if("heat"==constants.chartType){let e=(constants.maxY-constants.minY)/3,n=constants.minY+e,s=n+e;for(let e=0;e<plot.data.length;e++){for(let o=0;o<plot.data[e].length;o++)0==plot.data[e][o]?t.push("⠀"):plot.data[e][o]<=n?t.push("⠤"):plot.data[e][o]<=s?t.push("⠒"):t.push("⠉");t.push("⠳")}}else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType)if(position.y<plot.plotData[0].length-1){let e=null,n=null;for(let t=0;t<plot.plotData.length;t++)0==t?(e=plot.plotData[t][position.y],n=plot.plotData[t][position.y]):(plot.plotData[t][position.y]<e&&(e=plot.plotData[t][position.y]),plot.plotData[t][position.y]>n&&(n=plot.plotData[t][position.y]));let s=(n-e)/4,o=e+s,i=o+s,a=i+s;for(let e=0;e<plot.plotData.length;e++)0==plot.plotData[e][position.y]?t.push("⠀"):plot.plotData[e][position.y]<=o?t.push("⣀"):plot.plotData[e][position.y]<=i?t.push("⠤"):plot.plotData[e][position.y]<=a?t.push("⠒"):t.push("⠉")}else for(let e=0;e<plot.plotData.length;e++){let n=(constants.maxY-constants.minY)/4,s=constants.minY+n,o=s+n,i=o+n;for(let n=0;n<plot.plotData[e].length;n++)0==plot.plotData[e][n]?t.push("⠀"):plot.plotData[e][n]<=s?t.push("⣀"):plot.plotData[e][n]<=o?t.push("⠤"):plot.plotData[e][n]<=i?t.push("⠒"):t.push("⠉");t.push("⠳")}else if("bar"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,s=n+e,o=s+e;for(let e=0;e<plot.plotData.length;e++)plot.plotData[e]<=n?t.push("⣀"):plot.plotData[e]<=s?t.push("⠤"):plot.plotData[e]<=o?t.push("⠒"):t.push("⠉")}else if("smooth"==constants.chartType){let e=(plot.curveMaxY-plot.curveMinY)/4,n=plot.curveMinY+e,s=n+e,o=s+e,i=o+e;for(let e=0;e<plot.curvePoints.length;e++)plot.curvePoints[e]<=n?t.push("⣀"):plot.curvePoints[e]<=s?t.push("⠤"):plot.curvePoints[e]<=o?t.push("⠒"):plot.curvePoints[e]<=i&&t.push("⠉")}else if("hist"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,s=n+e,o=s+e;for(let e=0;e<plot.plotData.length;e++)plot.plotData[e].y<=n?t.push("⣀"):plot.plotData[e].y<=s?t.push("⠤"):plot.plotData[e].y<=o?t.push("⠒"):t.push("⠉")}else if("box"==constants.chartType&&position.y>-1){let e,n,s,o=plot.sections.length;"vert"==constants.plotOrientation?(e=position.x,n=constants.minY,s=constants.maxY):(e=position.y,n=constants.minX,s=constants.maxX);let i=[];i.push({type:"global_min",value:n});for(let t=0;t<o;t++){let n=plot.sections[t],s=plot.plotData[e][n],o={};if(null!=s)if("lower_outlier"==n||"upper_outlier"==n)for(let t=0;t<s.length;t++)o={type:n,value:s[t]},i.push(o);else o={type:n,value:s},i.push(o)}i.push({type:"global_max",value:s});let a=[],l=!0;for(let t=0;t<i.length;t++){let e;e=l?Math.abs(i[t+1].value-i[t].value):Math.abs(i[t].value-i[t-1].value),"global_min"==i[t].type||"global_max"==i[t].type?a.push({type:"blank",length:e}):"lower_outlier"==i[t].type?(a.push({type:i[t].type,length:0}),a.push({type:"blank",length:e})):"upper_outlier"==i[t].type?(a.push({type:"blank",length:e}),a.push({type:i[t].type,length:0})):"q2"==i[t].type?(l=!1,a.push({type:i[t].type,length:0})):a.push({type:i[t].type,length:e})}let r=-1,c=-1,p=-1,d=-1,h=0;for(let t=0;t<a.length;t++)"blank"!=a[t].type&&(a[t].length>0||"lower_outlier"==a[t].type||"upper_outlier"==a[t].type)?(a[t].numChars=1,h++):a[t].numChars=0,"min"==a[t].type&&a[t].length>0&&(r=t),"max"==a[t].type&&a[t].length>0&&(d=t),"q1"==a[t].type&&(c=t),"q3"==a[t].type&&(p=t),"q2"==a[t].type&&(a[t].numChars=2,h++);r>-1&&d>-1&&a[r].length!=a[d].length&&(a[r].length>a[d].length?(a[r].numChars++,h++):(a[d].numChars++,h++)),a[c].length!=a[p].length&&(a[c].length>a[p].length?(a[c].numChars++,h++):(a[p].numChars++,h++));let u=constants.brailleDisplayLength-h,y=this.AllocateCharacters(a,u),g=a;for(let t=0;t<y.length;t++)y[t]&&(g[t].numChars+=y[t]);constants.brailleData=g,constants.debugLevel>5&&(console.log("plotData[i]",plot.plotData[e]),console.log("valData",i),console.log("lenData",a),console.log("brailleData",g));for(let e=0;e<g.length;e++)for(let n=0;n<g[e].numChars;n++){let s="⠀";"min"==g[e].type||"max"==g[e].type?s="⠒":"q1"==g[e].type||"q3"==g[e].type?s="⠿":"q2"==g[e].type?s=0==n?"⠸":"⠇":"lower_outlier"!=g[e].type&&"upper_outlier"!=g[e].type||(s="⠂"),t.push(s)}}else if("line"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,s=n+e,o=s+e,i=o+e;for(let e=0;e<plot.pointValuesY.length;e++)plot.pointValuesY[e]<=n&&e-1>=0&&plot.pointValuesY[e-1]>n?plot.pointValuesY[e-1]<=s?t.push("⢄"):plot.pointValuesY[e-1]<=o?t.push("⢆"):plot.pointValuesY[e-1]>o&&t.push("⢇"):plot.pointValuesY[e]<=n?t.push("⣀"):e-1>=0&&plot.pointValuesY[e-1]<=n?plot.pointValuesY[e]<=s?t.push("⡠"):plot.pointValuesY[e]<=o?t.push("⡰"):plot.pointValuesY[e]>o&&t.push("⡸"):plot.pointValuesY[e]<=s&&e-1>=0&&plot.pointValuesY[e-1]>s?plot.pointValuesY[e-1]<=o?t.push("⠢"):plot.pointValuesY[e-1]>o&&t.push("⠣"):plot.pointValuesY[e]<=s?t.push("⠤"):e-1>=0&&plot.pointValuesY[e-1]<=s?plot.pointValuesY[e]<=o?t.push("⠔"):plot.pointValuesY[e]>o&&t.push("⠜"):plot.pointValuesY[e]<=o&&e-1>=0&&plot.pointValuesY[e-1]>o?t.push("⠑"):plot.pointValuesY[e]<=o?t.push("⠒"):e-1>=0&&plot.pointValuesY[e-1]<=o?t.push("⠊"):plot.pointValuesY[e]<=i&&t.push("⠉")}constants.brailleInput.value=t.join(""),constants.brailleInput.value=t.join(""),constants.debugLevel>5&&console.log("braille:",constants.brailleInput.value),this.UpdateBraillePos()}CharLenImpact(t){return t.length/t.numChars}AllocateCharacters(t,e){let n=[],s=0;for(let e=0;e<t.length;e++)s+=t[e].length;let o=["lower_outlier","upper_outlier","50"];for(let i=0;i<t.length;i++)o.includes(t[i].type)||(n[i]=Math.round(t[i].length/s*e));let i=n.reduce(((t,e)=>t+e),0),a=e-i,l=t.length;for(;0!==a&&l>0;){for(let e=0;e<t.length;e++)o.includes(t[e].type)||(n[e]+=Math.round(t[e].length/s*a));i=n.reduce(((t,e)=>t+e),0),a=e-i,l--}if(0!==a){let e=[];for(let n=0;n<t.length;n++)e.push(n);e.sort(((t,e)=>n[t]-n[e]));let s=-1;a>0&&(s=1);let o=0,i=3*e.length;for(;a>0&&i>0;)n[e[o]]+=s,a+=-s,o+=1,o>=e.length&&(o=0),i+=-1}return n}}class BarChart{constructor(){let t=null;"axes"in singleMaidr&&singleMaidr.axes.x&&singleMaidr.axes.x.level&&(t=singleMaidr.axes.x.level);let e=null;"data"in singleMaidr&&(e=singleMaidr.data);let n=null;"selector"in singleMaidr?n=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(n=singleMaidr.elements),t&&e&&n?n.length!=e.length?(constants.hasRect=0,logError.LogDifferentLengths("elements","data")):t.length!=n.length?(constants.hasRect=0,logError.LogDifferentLengths("x level","elements")):e.length!=t.length?(constants.hasRect=0,logError.LogDifferentLengths("x level","data")):(this.bars=n,constants.hasRect=1):e&&n?e.length!=n.length?(constants.hasRect=0,logError.LogDifferentLengths("data","elements")):(this.bars=n,constants.hasRect=1):t&&e?(t.length!=e.length&&(constants.hasRect=0,logError.LogDifferentLengths("x level","data")),logError.LogAbsentElement("elements")):e&&(logError.LogAbsentElement("x level"),logError.LogAbsentElement("elements")),this.columnLabels=[];let s="",o="";"labels"in singleMaidr&&("x"in singleMaidr.labels&&(s=singleMaidr.labels.x),"y"in singleMaidr.labels&&(o=singleMaidr.labels.y)),"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&""==s&&(s=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&""==o&&(o=singleMaidr.axes.y.label),singleMaidr.axes.x&&singleMaidr.axes.x.level&&(this.columnLabels=singleMaidr.axes.x.level),singleMaidr.axes.y&&singleMaidr.axes.y.level&&(this.columnLabels=singleMaidr.axes.y.level)),this.plotLegend={x:s,y:o},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),Array.isArray(singleMaidr)?this.plotData=singleMaidr:"data"in singleMaidr&&(this.plotData=singleMaidr.data),this.SetMaxMin(),this.autoplay=null}SetMaxMin(){for(let t=0;t<this.plotData.length;t++)0==t?(constants.maxY=this.plotData[t],constants.minY=this.plotData[t]):(this.plotData[t]>constants.maxY&&(constants.maxY=this.plotData[t]),this.plotData[t]<constants.minY&&(constants.minY=this.plotData[t]));constants.maxX=this.columnLabels.length,constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}PlayTones(){audio.playTone()}GetLegendFromManualData(){let t={};return t.x=barplotLegend.x,t.y=barplotLegend.y,t}GetData(){let t=[];if(this.bars)for(let e=0;e<this.bars.length;e++)t.push(this.bars[e].getAttribute("height"));return t}GetColumns(){let t=[],e=constants.chart.querySelectorAll('tspan[dy="10"]');for(var n=0;n<e.length;n++)t.push(e[n].innerHTML);return t}GetLegend(){let t={},e=constants.chart.querySelectorAll('tspan[dy="12"]');return t.x=e[1].innerHTML,t.y=e[0].innerHTML,t}ParseInnerHTML(t){let e=[];for(var n=0;n<t.length;n++)e.push(t[n].innerHTML);return e}Select(){if(this.UnSelectPrevious(),this.bars&&(this.activeElement=this.bars[position.x],this.activeElement))if(this.activeElement.hasAttribute("fill"))this.activeElementColor=this.activeElement.getAttribute("fill"),this.activeElement.setAttribute("fill",constants.GetBetterColor(this.activeElementColor));else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);this.activeElementColor=e[e.indexOf("fill")+1],e[e.indexOf("fill")+1]=constants.GetBetterColor(this.activeElementColor),t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t)}}UnSelectPrevious(){if(this.activeElement)if(this.activeElement.hasAttribute("fill"))this.activeElement.setAttribute("fill",this.activeElementColor),this.activeElement=null;else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);e[e.indexOf("fill")+1]=this.activeElementColor,t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t),this.activeElement=null}}}class BoxPlot{constructor(){if(this.sections=["lower_outlier","min","q1","q2","q3","max","upper_outlier"],constants.plotOrientation="horz","axes"in singleMaidr&&"x"in singleMaidr.axes&&"level"in singleMaidr.axes.x&&(constants.plotOrientation="vert"),this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),this.subtitle="","labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),this.caption="","labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),"labels"in singleMaidr&&(this.x_group_label||"x"in singleMaidr.labels&&(this.x_group_label=singleMaidr.labels.x),this.y_group_label||"y"in singleMaidr.labels&&(this.y_group_label=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&("label"in singleMaidr.axes.x&&(this.x_group_label||(this.x_group_label=singleMaidr.axes.x.label)),"level"in singleMaidr.axes.x?this.x_labels=singleMaidr.axes.x.level:this.x_labels=[]),"y"in singleMaidr.axes&&("label"in singleMaidr.axes.y&&(this.y_group_label||(this.y_group_label=singleMaidr.axes.y.label)),"level"in singleMaidr.axes.y?this.y_labels=singleMaidr.axes.y.level:this.y_labels=[])),this.plotData=singleMaidr.data,"selector"in singleMaidr){let t=document.querySelector(singleMaidr.selector);this.plotBounds=this.GetPlotBounds(t),constants.hasRect=!0}else"elements"in singleMaidr?(this.plotBounds=this.GetPlotBounds(singleMaidr.elements),constants.hasRect=!0):constants.hasRect=!1;this.CleanData()}CleanData(){let t,e;for(let n=0;n<this.plotData.length;n++){if(this.plotData[n].lower_outlier){let s=Math.min(...this.plotData[n].lower_outlier),o=Math.max(...this.plotData[n].lower_outlier);(null==t||s<t)&&(t=s),(null==e||o>e)&&(e=o)}if(this.plotData[n].min&&((null==t||this.plotData[n].min<t)&&(t=this.plotData[n].min),(null==e||this.plotData[n].max>e)&&(e=this.plotData[n].max)),this.plotData[n].q1&&((null==t||this.plotData[n].q1<t)&&(t=this.plotData[n].q1),(null==e||this.plotData[n].q1>e)&&(e=this.plotData[n].q1)),this.plotData[n].q2&&((null==t||this.plotData[n].q2<t)&&(t=this.plotData[n].q2),(null==e||this.plotData[n].q2>e)&&(e=this.plotData[n].q2)),this.plotData[n].q3&&((null==t||this.plotData[n].q3<t)&&(t=this.plotData[n].q3),(null==e||this.plotData[n].q3>e)&&(e=this.plotData[n].q3)),this.plotData[n].max&&((null==t||this.plotData[n].max<t)&&(t=this.plotData[n].max),(null==e||this.plotData[n].max>e)&&(e=this.plotData[n].max)),this.plotData[n].upper_outlier){let s=Math.min(...this.plotData[n].upper_outlier),o=Math.max(...this.plotData[n].upper_outlier);(null==t||s<t)&&(t=s),(null==e||o>e)&&(e=o)}}"vert"==constants.plotOrientation?(constants.minY=t,constants.maxY=e,constants.minX=0,constants.maxX=this.plotData.length-1):(constants.minX=t,constants.maxX=e,constants.minY=0,constants.maxY=this.plotData.length-1),constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/this.plotData.length),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}GetPlotBounds(t){let e=[],n=this.GetAllSegmentTypes(),s=/(?:\d+(?:\.\d*)?|\.\d+)/g,o=[],i=t.children;for(let t=0;t<i.length;t++){let e={},n=i[t].children;for(let t=0;t<n.length;t++){e[this.GetBoxplotSegmentType(n[t].getAttribute("id"))]=n[t]}o.push(e)}for(let t=0;t<o.length;t++){let i=[],a=o[t].range.getBoundingClientRect(),l=o[t].range.querySelector('polyline[id^="GRID"]').getAttribute("points").match(s),r=o[t].range.querySelector('polygon[id^="geom_polygon"]').getAttribute("points").match(s),c=0;c="vert"==constants.plotOrientation?(l[1]-r[3])/(r[1]-r[3]):(l[0]-r[2])/(r[0]-r[2]),c=Number.isNaN(c)?0:c;let p=0;if(p="vert"==constants.plotOrientation?a.height*c:a.width*c,i[2]=this.convertBoundingClientRectToObj(a),i[2].label=n[2],i[2].type="range","vert"==constants.plotOrientation?(i[2].height=p,i[2].top=i[2].bottom-p,i[2].y=i[2].top):i[2].width=p,i[3]=this.convertBoundingClientRectToObj(a),i[3].label=n[3],i[3].type="range","vert"==constants.plotOrientation?(i[3].height=0,i[3].top=a.bottom-p,i[3].y=i[3].top,i[3].bottom=i[3].top):(i[3].width=0,i[3].left=a.left+p),i[4]=this.convertBoundingClientRectToObj(a),i[4].label=n[4],i[4].type="range","vert"==constants.plotOrientation?(i[4].height=a.height-p,i[4].bottom=i[3].top):(i[4].width=a.width-p,i[4].left=i[3].left),Object.hasOwn(o[t],"whisker")){let e=o[t].whisker.getBoundingClientRect(),s=!1,l=!1;"vert"==constants.plotOrientation?(e.bottom>a.bottom&&(s=!0),e.top<a.top&&(l=!0)):(e.left<a.left&&(s=!0),e.right>a.right&&(l=!0)),s?(i[1]=this.convertBoundingClientRectToObj(e),i[1].label=n[1],i[1].type="whisker","vert"==constants.plotOrientation?(i[1].top=i[2].bottom,i[1].y=i[1].top,i[1].height=i[1].bottom-i[1].top):i[1].width=i[2].left-i[1].left):(i[1]={},i[1].label=n[1],i[1].type="blank"),l?(i[5]=this.convertBoundingClientRectToObj(e),i[5].label=n[5],i[5].type="whisker","vert"==constants.plotOrientation?(i[5].bottom=i[4].top,i[5].height=i[5].bottom-i[5].top):(i[5].left=i[4].right,i[5].x=i[4].right,i[5].width=i[5].right-i[5].left)):(i[5]={},i[5].label=n[5],i[5].type="blank")}if(Object.hasOwn(o[t],"outlier")){let e=o[t].outlier.children,s=null,l=null;for(let t=0;t<e.length;t++){let n=e[t].getBoundingClientRect();"vert"==constants.plotOrientation?n.y<a.y?s?(n.y<s.y&&(s.y=n.y),n.top<s.top&&(s.top=n.top),n.bottom>s.bottom&&(s.bottom=n.bottom)):s=this.convertBoundingClientRectToObj(n):l?(n.y<l.y&&(l.y=n.y),n.top<l.top&&(l.top=n.top),n.bottom>l.bottom&&(l.bottom=n.bottom)):l=this.convertBoundingClientRectToObj(n):n.x>a.x?s?(n.x<s.x&&(s.x=n.x),n.left<s.left&&(s.left=n.left),n.right>s.right&&(s.right=n.right)):s=this.convertBoundingClientRectToObj(n):l?(n.x<l.x&&(l.x=n.x),n.left<l.left&&(l.left=n.left),n.right>l.right&&(l.right=n.right)):l=this.convertBoundingClientRectToObj(n)}l?(l.height=l.bottom-l.top,l.width=l.right-l.left,i[0]=this.convertBoundingClientRectToObj(l),i[0].label=n[0],i[0].type="outlier"):(i[0]={},i[0].label=n[0],i[0].type="blank"),s?(s.height=s.bottom-s.top,s.width=s.right-s.left,i[6]=this.convertBoundingClientRectToObj(s),i[6].label=n[6],i[6].type="outlier"):(i[6]={},i[6].label=n[6],i[6].type="blank")}else i[0]={},i[0].label=n[0],i[0].type="blank",i[6]={},i[6].label=n[6],i[6].type="blank";e.push(i)}return constants.debugLevel>5&&console.log("plotBounds",e),e}GetAllSegmentTypes(){let t=[];for(let e=0;e<this.sections.length;e++)t.push(resources.GetString(this.sections[e]));return t}GetBoxplotSegmentType(t){let e="outlier";return t.includes("geom_crossbar")?e="range":t.includes("GRID")?e="whisker":t.includes("points")&&(e="outlier"),e}GetBoxplotSegmentPoints(t,e){let n=/(?:\d+(?:\.\d*)?|\.\d+)/g,s=[];if("range"==e){let e=t.children[0].getAttribute("points").match(n);s.push(e[0],e[1]),e[0]!=e[2]&&s.push(e[2],e[3])}else if("outlier"==e)s.push(t.getAttribute("x"),t.getAttribute("y"));else{let e=t.getAttribute("points").match(n);"vert"==constants.plotOrientation?e[1]!=e[3]&&s.push(e[0],e[1],e[2],e[3]):e[0]!=e[2]&&s.push(e[0],e[1],e[2],e[3])}return s}GetAllSegmentTypes(){return[resources.GetString("lower_outlier"),resources.GetString("min"),resources.GetString("25"),resources.GetString("50"),resources.GetString("75"),resources.GetString("max"),resources.GetString("upper_outlier")]}convertBoundingClientRectToObj(t){return{top:t.top,right:t.right,bottom:t.bottom,left:t.left,width:t.width,height:t.height,x:t.x,y:t.y}}PlayTones(){let t=null,e=null;constants.outlierInterval&&clearInterval(constants.outlierInterval),"vert"==constants.plotOrientation?(t=position.x,e=this.GetSectionKey(position.y)):(t=position.y,e=this.GetSectionKey(position.x)),null==plot.plotData[t][e]?audio.PlayNull():"lower_outlier"!=e&&"upper_outlier"!=e?audio.playTone():0==plot.plotData[t][e].length?audio.PlayNull():(position.z=0,constants.outlierInterval=setInterval((function(){audio.playTone(),position.z+=1,(null==plot.plotData[t][e]||position.z+1>plot.plotData[t][e].length)&&(clearInterval(constants.outlierInterval),position.z=-1)}),constants.autoPlayOutlierRate))}GetSectionKey(t){return this.sections[t]}}class BoxplotRect{rectPadding=15;rectStrokeWidth=4;constructor(){this.x1=0,this.width=0,this.y1=0,this.height=0,this.chartOffsetLeft=constants.chart.getBoundingClientRect().left,this.chartOffsetTop=constants.chart.getBoundingClientRect().top}UpdateRect(){document.getElementById("highlight_rect")&&document.getElementById("highlight_rect").remove();let t=position.x,e=position.y,n=plot.GetSectionKey(position.y);if("vert"==constants.plotOrientation||(t=position.y,e=position.x,n=plot.GetSectionKey(position.x)),"vert"==constants.plotOrientation&&position.y>-1||"horz"==constants.plotOrientation&&position.x>-1){let s=plot.plotBounds[t][e];"blank"!=s.type&&(this.x1=s.left-this.rectPadding-this.chartOffsetLeft,this.width=s.width+2*this.rectPadding,this.y1=s.top-this.rectPadding-this.chartOffsetTop,this.height=s.height+2*this.rectPadding,constants.debugLevel>5&&(console.log("Point",n,"bottom:",s.bottom,"top:",s.top),console.log("x1:",this.x1,"y1:",this.y1,"width:",this.width,"height:",this.height)),this.CreateRectDisplay())}}CreateRectDisplay(){let t=document.createElementNS("http://www.w3.org/2000/svg","rect");t.setAttribute("id","highlight_rect"),t.setAttribute("x",this.x1),t.setAttribute("y",this.y1),t.setAttribute("width",this.width),t.setAttribute("height",this.height),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.rectStrokeWidth),t.setAttribute("fill","none"),constants.chart.appendChild(t)}}class HeatMap{constructor(){let t=null,e=null;"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.level&&(t=singleMaidr.axes.x.level),singleMaidr.axes.y&&singleMaidr.axes.y.level&&(e=singleMaidr.axes.y.level)),"data"in singleMaidr?(this.data=singleMaidr.data,this.num_rows=this.data.length,this.num_cols=this.data[0].length):console.error("No data found in singleMaidr object"),"selector"in singleMaidr?(this.elements=document.querySelectorAll(singleMaidr.selector),constants.hasRect=1):"elements"in singleMaidr?(this.elements=singleMaidr.elements,constants.hasRect=1):(this.elements=null,constants.hasRect=0),this.group_labels=this.getGroupLabels(),this.x_labels=t,this.y_labels=e,this.title=this.getTitle(),this.fill=this.getFill(),constants.hasRect&&this.SetHeatmapRectData(),this.updateConstants(),this.x_group_label=this.group_labels[0].trim(),this.y_group_label=this.group_labels[1].trim()}SetHeatmapRectData(){let t=[],e=[],n=[],s=[];for(let n=0;n<this.elements.length;n++)if(this.elements[n])if(this.elements[n]instanceof SVGPathElement){const s=this.elements[n].getAttribute("d"),o=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(s),i=[Number(o[1]),Number(o[3])],a=i[0],l=i[1];t.push(parseFloat(a)),e.push(parseFloat(l))}else t.push(parseFloat(this.elements[n].getAttribute("x"))),e.push(parseFloat(this.elements[n].getAttribute("y")));t.sort((function(t,e){return t-e})),e.sort((function(t,e){return t-e}));let o=this.GetSVGScaler();-1==o[0]&&(t=t.reverse()),-1==o[1]&&(e=e.reverse()),n=[...new Set(t)],s=[...new Set(e)],this.x_coord=n,this.y_coord=s}updateConstants(){constants.minX=0,constants.maxX=this.data[0].length-1,constants.minY=Math.min(...this.data.map((t=>Math.min(...t)))),constants.maxY=Math.max(...this.data.map((t=>Math.max(...t)))),constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}PlayTones(){audio.playTone()}GetSVGScaler(){let t=1,e=1,n=!1,s=this.elements[0];for(;s&&"body"!=s.tagName.toLowerCase();)s.tagName&&"svg"===s.tagName.toLowerCase()&&(n=!0),s=s.parentNode;if(n){let n=this.elements[0];for(;n&&"body"!=n.tagName.toLowerCase();){if(n.getAttribute("transform")){let s=n.getAttribute("transform").match(/scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/);s&&(isNaN(s[1])||(t*=parseFloat(s[1])),isNaN(s[3])||(e*=parseFloat(s[3])))}n=n.parentNode}}return[t,e]}getRGBNorm(t){return this.elements[t].getAttribute("fill").slice(4,-1).split(",").map((function(t){return Math.pow(t,2)})).reduce((function(t,e){return t+e}))}getGroupLabels(){let t,e="",n="";return"labels"in singleMaidr&&("x"in singleMaidr.labels&&(e=singleMaidr.labels.x),"y"in singleMaidr.labels&&(n=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&"label"in singleMaidr.axes.x&&""==e&&(e=singleMaidr.axes.x.label),"y"in singleMaidr.axes&&"label"in singleMaidr.axes.y&&""==n&&(n=singleMaidr.axes.y.label)),t=[e,n],t}getXLabels(){if("axes"in singleMaidr&&"x"in singleMaidr.axes&&"level"in singleMaidr.axes.x)return singleMaidr.axes.x.level}getYLabels(){if("axes"in singleMaidr&&"y"in singleMaidr.axes&&"level"in singleMaidr.axes.y)return singleMaidr.axes.y.level}getTitle(){return"title"in singleMaidr?singleMaidr.title:"labels"in singleMaidr&&"title"in singleMaidr.labels?singleMaidr.labels.title:void 0}getSubtitle(){if("labels"in singleMaidr&&"subtitle"in singleMaidr.labels)return singleMaidr.labels.subtitle}getCaption(){if("labels"in singleMaidr&&"caption"in singleMaidr.labels)return singleMaidr.labels.caption}getFill(){if("labels"in singleMaidr&&"fill"in singleMaidr.labels)return singleMaidr.labels.fill}}class HeatMapRect{constructor(){constants.hasRect&&(this.x=plot.x_coord[0],this.y=plot.y_coord[0],this.squareIndex=0,this.rectStrokeWidth=4,this.height=Math.abs(plot.y_coord[1]-plot.y_coord[0]),this.width=Math.abs(plot.x_coord[1]-plot.x_coord[0]))}UpdateRect(){this.x=plot.x_coord[position.x],this.y=plot.y_coord[position.y];for(let t=0;t<plot.elements.length;t++)if(plot.elements[t].getAttribute("x")==this.x&&plot.elements[t].getAttribute("y")==this.y){this.squareIndex=t;break}}UpdateRectDisplay(){this.UpdateRect(),document.getElementById("highlight_rect")&&document.getElementById("highlight_rect").remove();var t=document.createElementNS("http://www.w3.org/2000/svg","rect");t.setAttribute("id","highlight_rect"),t.setAttribute("x",this.x),t.setAttribute("y",this.y),t.setAttribute("width",this.width),t.setAttribute("height",this.height),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.rectStrokeWidth),t.setAttribute("fill","none"),plot.elements[this.squareIndex].parentNode.appendChild(t)}}class ScatterPlot{constructor(){this.prefix=this.GetPrefix(),this.SetScatterLayer(),this.SetLineLayer(),this.SetAxes(),this.svgScaler=this.GetSVGScaler()}SetAxes(){this.x_group_label="",this.y_group_label="",this.title="","labels"in singleMaidr&&("x"in singleMaidr.labels&&(this.x_group_label=singleMaidr.labels.x),"y"in singleMaidr.labels&&(this.y_group_label=singleMaidr.labels.y),"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&""==this.x_group_label&&(this.x_group_label=singleMaidr.axes.x.label),"y"in singleMaidr.axes&&""==this.y_group_label&&(this.y_group_label=singleMaidr.axes.y.label)),"title"in singleMaidr&&""==this.title&&(this.title=singleMaidr.title)}SetScatterLayer(){let t=this.GetElementIndex("point");-1!=t?"selector"in singleMaidr?this.plotPoints=document.querySelectorAll(singleMaidr.selector[t]):"elements"in singleMaidr&&(this.plotPoints=singleMaidr.elements[t]):"point"==singleMaidr.type&&("selector"in singleMaidr?this.plotPoints=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(this.plotPoints=singleMaidr.elements));let e=this.GetSvgPointCoords(),n=this.GetPointValues();this.chartPointsX=e[0],this.chartPointsY=e[1],this.x=n[0],this.y=n[1],this.points_count=n[2],this.max_count=n[3]}SetLineLayer(){let t=this.GetElementIndex("smooth");-1!=t?"selector"in singleMaidr?this.plotLine=document.querySelectorAll(singleMaidr.selector[t])[0]:"elements"in singleMaidr&&(this.plotLine=singleMaidr.elements[t][0]):"smooth"==singleMaidr.type&&("selector"in singleMaidr?this.plotLine=document.querySelectorAll(singleMaidr.selector)[0]:"elements"in singleMaidr&&(this.plotLine=singleMaidr.elements));let e=this.GetSvgLineCoords(),n=this.GetSmoothCurvePoints();this.chartLineX=e[0],this.chartLineY=e[1],this.curveX=n[0],this.curvePoints=n[1],this.curvePoints&&this.curvePoints.length>0?(this.curveMinY=Math.min(...this.curvePoints),this.curveMaxY=Math.max(...this.curvePoints)):(this.curveMinY=Number.MAX_VALUE,this.curveMaxY=Number.MIN_VALUE),this.gradient=this.GetGradient()}GetSvgPointCoords(){let t=new Map;if(this.plotPoints)for(let e=0;e<this.plotPoints.length;e++){let n,s;if(this.plotPoints[e]instanceof SVGPathElement){let t=this.plotPoints[e].getAttribute("d"),o=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(o[1]),s=parseFloat(o[3])}else n=parseFloat(this.plotPoints[e].getAttribute(this.prefix+"x")),s=parseFloat(this.plotPoints[e].getAttribute(this.prefix+"y"));t.has(n)?t.get(n).add(s):t.set(n,new Set([s]))}else if([].concat(singleMaidr.type).includes("point")){let e,n=this.GetElementIndex("point"),s=this.GetDataXYFormat(n);e=n>-1?singleMaidr.data[n]:singleMaidr.data;let o=[],i=[];if("array"==s)"x"in e&&(o=e.x),"y"in e&&(i=e.y);else if("object"==s)for(let t=0;t<e.length;t++){let n=e[t].x,s=e[t].y;o.push(n),i.push(s)}for(let e=0;e<o.length;e++){let n=o[e],s=i[e];t.has(n)?t.get(n).add(s):t.set(n,new Set([s]))}}t=new Map([...t].sort((function(t,e){return t[0]-e[0]}))),t.forEach((function(e,n){t[n]=Array.from(e).sort((function(t,e){return t-e}))}));let e=[...t.keys()],n=[];for(let s=0;s<e.length;s++)n.push(t[e[s]]);return[e,n]}GetElementIndex(t="point"){let e=-1;return"type"in singleMaidr&&Array.isArray(singleMaidr.type)&&(e=singleMaidr.type.indexOf(t)),e}GetDataXYFormat(t){let e,n;return e=t>-1?singleMaidr.data[t]:singleMaidr.data,n=Array.isArray(e)?"object":"array",n}GetSVGScaler(){let t=1,e=1,n=!1;if(this.plotPoints){let s=this.plotPoints[0];for(;s&&"body"!=s.tagName.toLowerCase();)s.tagName&&"svg"===s.tagName.toLowerCase()&&(n=!0),s=s.parentNode;if(n){let n=this.plotPoints[0];for(;n&&"body"!=n.tagName.toLowerCase();){if(n.getAttribute("transform")){let s=n.getAttribute("transform").match(/scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/);s&&(isNaN(s[1])||(t*=parseFloat(s[1])),isNaN(s[3])||(e*=parseFloat(s[3])))}n=n.parentNode}}}return[t,e]}GetPrefix(){let t=this.GetElementIndex("point"),e=null;-1!=t?"selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector[t])[0]:"elements"in singleMaidr&&(e=singleMaidr.elements[t][0]):"point"==singleMaidr.type&&("selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector)[0]:"elements"in singleMaidr&&(e=singleMaidr.elements[0]));let n="";return e&&"circle"===e.tagName.toLowerCase()&&(n="c"),n}GetPointValues(){let t,e,n=new Map,s=[],o=[],i=[],a=this.GetElementIndex("point"),l=this.GetDataXYFormat(a);if(a>-1?e=singleMaidr.data[a]:"point"==singleMaidr.type&&(e=singleMaidr.data),void 0!==e){let a=[],r=[];if("array"==l)"x"in e&&(a=e.x),"y"in e&&(r=e.y);else if("object"==l)for(let t=0;t<e.length;t++){let n=e[t].x,s=e[t].y;a.push(n),r.push(s)}for(let t=0;t<a.length;t++){let e=a[t],s=r[t];if(n.has(e))if(n.get(e).has(s)){let t=n.get(e);t.set(s,t.get(s)+1)}else n.get(e).set(s,1);else n.set(e,new Map([[s,1]]))}constants.minX=0,constants.maxX=[...new Set(a)].length,constants.minY=Math.min(...r),constants.maxY=Math.max(...r),constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate),n=new Map([...n].sort((function(t,e){return t[0]-e[0]}))),n.forEach((function(t,e){n[e]=Array.from(t).sort((function(t,e){return t[0]-e[0]}))}));for(const[t,e]of n){s.push(t);let n=[],a=[];for(const[t,s]of e)n.push(t),a.push(s);o.push(n.sort()),i.push(a)}t=Math.max(...i.map((t=>Math.max(...t))))}return[s,o,i,t]}PlayTones(){constants.sepPlayId&&constants.KillSepPlay(),"point"==constants.chartType?(position.z=0,constants.sepPlayId=setInterval((function(){audio.playTone(),position.z+=1,position.z+1>plot.y[position.x].length&&(constants.KillSepPlay(),position.z=-1)}),"on"==constants.sonifMode?constants.autoPlayPointsRate:0)):"smooth"==constants.chartType&&audio.playTone()}GetSvgLineCoords(){let t=[],e=[];if(this.plotLine){if(this.plotLine instanceof SVGPathElement){const n=this.plotLine.getAttribute("d"),s=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;let o;for(;null!==(o=s.exec(n));)t.push(o[1]),e.push(o[3])}else if(this.plotLine instanceof SVGPolylineElement){let n=this.plotLine.getAttribute("points").split(" ");for(let s=0;s<n.length;s++){let o=n[s].split(",");t.push(parseFloat(o[0])),e.push(parseFloat(o[1]))}}}else if([].concat(singleMaidr.type).includes("smooth")){let n,s=this.GetElementIndex("smooth"),o=this.GetDataXYFormat(s);if(n=s>-1?singleMaidr.data[s]:singleMaidr.data,"object"==o)for(let s=0;s<n.length;s++)t.push(n[s].x),e.push(n[s].y);else"array"==o&&("x"in n&&(t=n.x),"y"in n&&(e=n.y))}return[t,e]}GetSmoothCurvePoints(){let t,e=[],n=[],s=this.GetElementIndex("smooth"),o=this.GetDataXYFormat(s);if(s>-1?t=singleMaidr.data[s]:"smooth"==singleMaidr.type&&(t=singleMaidr.data),void 0!==t)if("object"==o)for(let s=0;s<t.length;s++)e.push(t[s].x),n.push(t[s].y);else"array"==o&&("x"in t&&(e=t.x),"y"in t&&(n=t.y));return[e,n]}GetGradient(){let t=[];for(let e=0;e<this.curvePoints.length-1;e++){let n=Math.abs((this.curvePoints[e+1]-this.curvePoints[e])/(this.curveX[e+1]-this.curveX[e])).toFixed(3);t.push(n)}return t.push("end"),t}GetRectStatus(t){let e=this.GetElementIndex(t);if(e>-1){if("selector"in singleMaidr)return!!singleMaidr.selector[e];if("elements"in singleMaidr)return!!singleMaidr.elements[e]}else{if("selector"in singleMaidr)return!!singleMaidr.selector;if("elements"in singleMaidr)return!!singleMaidr.elements}}}class Layer0Point{constructor(){[].concat(singleMaidr.type).includes("point")&&(this.x=plot.chartPointsX[0],this.y=plot.chartPointsY[0],this.strokeWidth=1.35,this.hasRect=plot.GetRectStatus("point"),this.circleIndex=[])}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartPointsX[position.x],this.y=plot.chartPointsY[position.x],this.circleIndex=[];for(let t=0;t<this.y.length;t++)for(let e=0;e<plot.plotPoints.length;e++){let n,s;if(plot.plotPoints[e]instanceof SVGPathElement){const t=plot.plotPoints[e].getAttribute("d");let o=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(o[1]),s=parseFloat(o[3])}else(plot.plotPoints[e]instanceof SVGUseElement||plot.plotPoints[e]instanceof SVGCircleElement)&&(n=plot.plotPoints[e].getAttribute(plot.prefix+"x"),s=plot.plotPoints[e].getAttribute(plot.prefix+"y"));if(n==this.x&&s==this.y[t]){this.circleIndex.push(e);break}}}async PrintPoints(){await this.ClearPoints(),await this.UpdatePoints();for(let e=0;e<this.circleIndex.length;e++){const n="http://www.w3.org/2000/svg";var t=document.createElementNS(n,"circle");if(t.setAttribute("class","highlight_point"),t.setAttribute("cx",this.x),-1==plot.svgScaler[1])t.setAttribute("cy",constants.chart.getBoundingClientRect().height-this.y[e]);else{let n;if(plot.plotPoints[this.circleIndex[e]]instanceof SVGPathElement){const t=plot.plotPoints[this.circleIndex[e]].getAttribute("d");let s=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(s[3])}else(plot.plotPoints[this.circleIndex[e]]instanceof SVGUseElement||plot.plotPoints[this.circleIndex[e]]instanceof SVGCircleElement)&&(n=plot.plotPoints[this.circleIndex[e]].getAttribute(plot.prefix+"y"));t.setAttribute("cy",n)}t.setAttribute("r",3.95),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.strokeWidth),t.setAttribute("fill",constants.colorSelected),constants.chart.appendChild(t)}}async ClearPoints(){document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove();let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove()}UpdatePointDisplay(){this.ClearPoints(),this.UpdatePoints(),this.PrintPoints()}}class Layer1Point{constructor(){[].concat(singleMaidr.type).includes("smooth")&&(this.x=plot.chartLineX[0],this.y=plot.chartLineY[0],this.strokeWidth=1.35,this.hasRect=plot.GetRectStatus("point"))}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartLineX[positionL1.x],this.y=plot.chartLineY[positionL1.x]}async PrintPoints(){await this.ClearPoints(),await this.UpdatePoints();var t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("id","highlight_point"),t.setAttribute("cx",this.x),-1==plot.svgScaler[1]?t.setAttribute("cy",constants.chart.getBoundingClientRect().height-this.y):t.setAttribute("cy",this.y),t.setAttribute("r",3.95),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.strokeWidth),t.setAttribute("fill",constants.colorSelected),-1==plot.svgScaler[1]?constants.chart.appendChild(t):plot.plotLine.parentNode.appendChild(t)}async ClearPoints(){let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove();document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove()}UpdatePointDisplay(){this.ClearPoints(),this.UpdatePoints(),this.PrintPoints()}}class Histogram{constructor(){"data"in singleMaidr?(this.plotData=singleMaidr.data,this.bars=null,"selector"in singleMaidr?this.bars=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(this.bars=singleMaidr.elements),this.legendX=null,this.legendY=null,"labels"in singleMaidr&&("x"in singleMaidr.labels&&(this.legendX=singleMaidr.labels.x),"y"in singleMaidr.labels&&(this.legendY=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&"label"in singleMaidr.axes.x&&(this.legendX||(this.legendX=singleMaidr.axes.x.label)),"y"in singleMaidr.axes&&"label"in singleMaidr.axes.y&&(this.legendY||(this.legendY=singleMaidr.axes.y.label))),this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),this.SetMaxMin(),this.autoplay=null):console.log("Error: no data found")}PlayTones(){audio.playTone()}SetMaxMin(){for(let t=0;t<this.plotData.length;t++)0==t?(constants.maxY=this.plotData[t].y,constants.minY=this.plotData[t].y,constants.maxX=this.plotData[t].xmax,constants.minX=this.plotData[t].xmin):(this.plotData[t].y>constants.maxY&&(constants.maxY=this.plotData[t].y),this.plotData[t].y<constants.minY&&(constants.minY=this.plotData[t].y),this.plotData[t].xmax>constants.maxX&&(constants.maxX=this.plotData[t].xmax),this.plotData[t].xmin<constants.minX&&(constants.minX=this.plotData[t].xmin));constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}Select(){if(this.UnSelectPrevious(),this.bars&&(this.activeElement=this.bars[position.x],this.activeElement))if(this.activeElement.hasAttribute("fill"))this.activeElementColor=this.activeElement.getAttribute("fill"),this.activeElement.setAttribute("fill",constants.GetBetterColor(this.activeElementColor));else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);this.activeElementColor=e[e.indexOf("fill")+1],e[e.indexOf("fill")+1]=constants.GetBetterColor(this.activeElementColor),t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t)}}UnSelectPrevious(){if(this.activeElement)if(this.activeElement.hasAttribute("fill"))this.activeElement.setAttribute("fill",this.activeElementColor),this.activeElement=null;else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);e[e.indexOf("fill")+1]=this.activeElementColor,t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t),this.activeElement=null}}}class LinePlot{constructor(){this.SetLineLayer(),this.SetAxes(),this.UpdateConstants()}SetLineLayer(){let t;"selector"in singleMaidr?t=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(t=singleMaidr.elements),t?this.plotLine=t[t.length-1]:constants.hasRect=0;let e=this.GetPointCoords(),n=this.GetPoints();this.chartLineX=e[0],this.chartLineY=e[1],this.pointValuesX=n[0],this.pointValuesY=n[1],this.curveMinY=Math.min(...this.pointValuesY),this.curveMaxY=Math.max(...this.pointValuesY)}UpdateConstants(){constants.minX=0,constants.maxX=singleMaidr.data.length-1,constants.minY=singleMaidr.data.reduce(((t,e)=>e.y<t?e.y:t),singleMaidr.data[0].y),constants.maxY=singleMaidr.data.reduce(((t,e)=>e.y>t?e.y:t),singleMaidr.data[0].y),constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}GetPointCoords(){let t=[[],[]];if(!this.plotLine){let t,e=[],n=[];if("data"in singleMaidr&&(t=singleMaidr.data),void 0!==t)for(let s=0;s<t.length;s++)e.push(t[s].x),n.push(t[s].y);return[e,n]}if(this.plotLine instanceof SVGPathElement){const e=this.plotLine.getAttribute("d"),n=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;let s;for(;null!==(s=n.exec(e));)t[0].push(s[1]),t[1].push(s[3])}else{let e=this.plotLine.getAttribute("points").split(" ");for(let n=0;n<e.length;n++)if(""!==e[n]){let s=e[n].split(",");t[0].push(s[0]),t[1].push(s[1])}}return t}GetPoints(){let t,e=[],n=[];if("data"in singleMaidr&&(t=singleMaidr.data),void 0!==t){for(let s=0;s<t.length;s++)e.push(t[s].x),n.push(t[s].y);return[e,n]}}SetAxes(){let t="",e="";"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&""==t&&(t=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&""==e&&(e=singleMaidr.axes.y.label)),this.plotLegend={x:t,y:e},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption)}PlayTones(){audio.playTone()}}class Point{constructor(){this.x=plot.chartLineX[0],this.y=plot.chartLineY[0]}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartLineX[position.x],this.y=plot.chartLineY[position.x]}async PrintPoints(){await this.ClearPoints(),await this.UpdatePoints();var t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("id","highlight_point"),t.setAttribute("cx",this.x),t.setAttribute("cy",this.y),t.setAttribute("r",1.75),t.setAttribute("style","fill:"+constants.colorSelected+";stroke:"+constants.colorSelected),constants.chart.appendChild(t)}async ClearPoints(){let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove();document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove()}UpdatePointDisplay(){this.ClearPoints(),this.UpdatePoints(),this.PrintPoints()}}class Segmented{constructor(){let t=null,e=null;if("axes"in singleMaidr&&("x"in singleMaidr.axes?"level"in singleMaidr.axes.x&&(this.level=singleMaidr.axes.x.level):"y"in singleMaidr.axes&&"level"in singleMaidr.axes.y&&(this.level=singleMaidr.axes.y.level),"fill"in singleMaidr.axes&&"level"in singleMaidr.axes.fill&&(this.fill=singleMaidr.axes.fill.level)),"data"in singleMaidr&&(t=singleMaidr.data),"selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(e=singleMaidr.elements),null==e&&(logError.LogAbsentElement("elements"),constants.hasRect=0),!t)return void console.log("Segmented chart missing level, fill, or data. Unable to create chart.");{this.fill&&(this.fill=this.fill.reverse());let n=this.ParseData(t,e);this.plotData=n[0],this.elements=n[1]}let n="",s="";"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&(n=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&(s=singleMaidr.axes.y.label)),"labels"in singleMaidr&&("x"in singleMaidr.labels&&(n=singleMaidr.labels.x),"y"in singleMaidr.labels&&(s=singleMaidr.labels.y)),this.plotLegend={x:n,y:s},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),this.SetMaxMin(),this.CreateSummaryLevel(),this.CreateAllLevel(),this.autoplay=null}ParseData(t,e=null){let n=[],s=[];e?e.length!=t.length&&(s=null):s=null;for(let o=0;o<this.level.length;o++)for(let i=0;i<this.fill.length;i++)for(let a=0;a<t.length;a++)if(n[o]||(n[o]=[],null!=s&&(s[o]||(s[o]=[]))),n[o][i]||(n[o][i]=0,null!=s&&(s[o][i]||(s[o][i]=null))),t[a].x==this.level[o]&&t[a].fill==this.fill[i]){n[o][i]=t[a].y,e&&(s[o][i]=e[a]);break}return[n,s]}CreateSummaryLevel(){for(let t=0;t<this.plotData.length;t++){let e=0;for(let n=0;n<this.plotData[t].length;n++)e+=this.plotData[t][n];this.plotData[t].push(e)}this.fill.push("Sum")}CreateAllLevel(){for(let t=0;t<this.plotData.length;t++){let e=[];for(let n=0;n<this.fill.length;n++)"Sum"!=this.fill[n]&&e.push(this.plotData[t][n]);this.plotData[t].push(e)}this.fill.push("All")}PlayTones(){if(Array.isArray(this.plotData[position.x][position.y]))if("on"==constants.sonifMode)position.z=0,constants.KillSepPlay(),constants.sepPlayId=setInterval((function(){audio.playTone(),position.z+=1,Array.isArray(plot.plotData[position.x][position.y])?position.z+1>plot.plotData[position.x][position.y].length&&(constants.KillSepPlay(),position.z=-1):(constants.KillSepPlay(),position.z=-1)}),"on"==constants.sonifMode?constants.autoPlayPointsRate:0);else{let t=Math.min(...this.plotData[position.x][position.y]),e=Math.max(...this.plotData[position.x][position.y]);for(let n=0;n<this.plotData[position.x][position.y].length;n++){position.z=n;let s=audio.SlideBetween(this.plotData[position.x][position.y][n],t,e,constants.combinedVolMin,constants.combinedVolMax);audio.playTone({volScale:s})}}else audio.playTone()}SetMaxMin(){for(let t=0;t<singleMaidr.data.length;t++)0==t?(constants.maxY=singleMaidr.data[t].y,constants.minY=singleMaidr.data[t].y):(singleMaidr.data[t].y>constants.maxY&&(constants.maxY=singleMaidr.data[t].y),singleMaidr.data[t].y<constants.minY&&(constants.minY=singleMaidr.data[t].y));constants.maxX=this.level.length,constants.autoPlayRate=Math.min(Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.MAX_SPEED),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}Select(){if(this.UnSelectPrevious(),this.elements&&(this.activeElement=this.elements[position.x][position.y],this.activeElement)){this.activeElementColor=this.activeElement.style.fill;let t=constants.GetBetterColor(this.activeElementColor);this.activeElement.style.fill=t}}UnSelectPrevious(){this.activeElement&&(this.activeElement.style.fill=this.activeElementColor,this.activeElement=null)}}class Control{constructor(){this.SetControls()}SetControls(){let t=[constants.chart,constants.brailleInput,constants.review_container],e=!1,n=null;for(let s=0;s<t.length;s++)constants.events.push([t[s],"keydown",function(t){if(!e&&("b"==t.key&&(constants.tabMovement=0,t.preventDefault(),display.toggleBrailleMode()),"t"==t.key&&display.toggleTextMode(),"s"==t.key&&display.toggleSonificationMode(),"r"!=t.key||t.ctrlKey||t.shiftKey||(constants.tabMovement=0,t.preventDefault(),constants.review_container.classList.contains("hidden")?review.ToggleReviewMode(!0):review.ToggleReviewMode(!1))," "==t.key&&(position.x<0&&(position.x=0),position.y<0&&(position.y=0),constants.showDisplay&&display.displayValues(),"off"!=constants.sonifMode&&plot.PlayTones()),Array.isArray(singleMaidr.type)&&[].concat(singleMaidr.type).includes("point")&&[].concat(singleMaidr.type).includes("smooth")&&("PageDown"==t.key&&"off"==constants.brailleMode&&display.changeChartLayer("down"),"PageUp"==t.key&&"off"==constants.brailleMode&&display.changeChartLayer("up")),"-"==t.key)){}}]);for(let o=0;o<t.length;o++)constants.events.push([t[o],"keydown",function(t){"Tab"==t.key&&(t.shiftKey?constants.tabDirection=-1:constants.tabDirection=1)}]);if(constants.events.push([document,"keydown",function(t){if("l"==t.key&&(e=!0,null!=n&&(clearTimeout(n),n=null),n=setTimeout((function(){e=!1}),constants.keypressInterval)),(constants.isMac?t.metaKey:t.ctrlKey)&&("Home"==t.key?("bar"==constants.chartType||"hist"==constants.chartType?position.x=0:"box"==constants.chartType?(position.x=0,position.y=plot.sections.length-1):"heat"==constants.chartType?(position.x=0,position.y=0):"point"==constants.chartType?position.x=0:"smooth"==constants.chartType&&(positionL1.x=0),UpdateAllBraille()):"End"==t.key&&("bar"==constants.chartType||"hist"==constants.chartType?position.x=plot.bars.length-1:"box"==constants.chartType?(position.x=plot.sections.length-1,position.y=0):"heat"==constants.chartType?(position.x=plot.num_cols-1,position.y=plot.num_rows-1):"point"==constants.chartType?position.x=plot.y.length-1:"smooth"==constants.chartType&&(positionL1.x=plot.curvePoints.length-1),UpdateAllBraille())),e)if("x"==t.key){let t="";"bar"==constants.chartType||"line"==singleMaidr.type?t=plot.plotLegend.x:("heat"==constants.chartType||"box"==constants.chartType||"point"==singleMaidr.type||singleMaidr.type.includes("point"))&&(t=plot.x_group_label),display.displayInfo("x label",t),e=!1}else if("y"==t.key){let t="";"bar"==constants.chartType||"line"==singleMaidr.type?t=plot.plotLegend.y:("heat"==constants.chartType||"box"==constants.chartType||"point"==singleMaidr.type||"line"==singleMaidr.type||singleMaidr.type.includes("point"))&&(t=plot.y_group_label),display.displayInfo("y label",t),e=!1}else"t"==t.key?(display.displayInfo("title",plot.title),e=!1):"s"==t.key?(display.displayInfo("subtitle",plot.subtitle),e=!1):"c"==t.key?(display.displayInfo("caption",plot.caption),e=!1):"f"==t.key?(display.displayInfo("fill",plot.fill),e=!1):"l"!=t.key&&(e=!1)}]),[].concat(singleMaidr.type).includes("bar")){window.position=new Position(-1,-1),window.plot=new BarChart,constants.lastx=0;let i="";constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,u("right",position.x,plot.plotData.length)):(position.x=plot.plotData.length-1,e=!0,n=c()):t.altKey&&t.shiftKey&&position.x!=plot.bars.length-1?(constants.lastx=position.x,u("reverse-right",plot.bars.length,position.x)):(position.x+=1,e=!0,n=c()):"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,u("left",position.x,-1)):(position.x=0,e=!0,n=c()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,u("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=c())),e&&!n&&p(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(t.preventDefault(),t.target.selectionStart>t.target.value.length-2||((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,u("right",position.x,plot.plotData.length)):(position.x=plot.bars.length-1,e=!0,n=c()):t.altKey&&t.shiftKey&&position.x!=plot.bars.length-1?(constants.lastx=position.x,u("reverse-right",plot.bars.length,position.x)):(position.x+=1,e=!0,n=c()))):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,u("left",position.x,-1)):(position.x=0,e=!0,n=c()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,u("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=c())):"Tab"==t.key||t.preventDefault(),e&&!n&&h(),n&&audio.playEnd()}]);let a=[constants.chart,constants.brailleInput],l=0;for(let y=0;y<a.length;y++)constants.events.push([a[y],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),r(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),r(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),r(),display.announceText("Speed reset"))}]);function r(){null!=constants.autoplayId&&(constants.KillAutoplay(),u("reverse-left"==i?"right":"reverse-right"==i?"left":i,position.x,l))}function c(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.plotData.length-1&&(position.x=plot.plotData.length-1,t=!0),t}function p(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones()}function d(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function h(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function u(t,e,n){i=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),c()):position.x==n?(constants.KillAutoplay(),d()):d()}),constants.autoPlayRate)}}else if([].concat(singleMaidr.type).includes("box")){let g;constants.plotId="geom_boxplot.gTree.78.1",window.plot=new BoxPlot,"vert"==constants.plotOrientation?window.position=new Position(0,6):window.position=new Position(-1,plot.plotData.length),constants.hasRect&&(g=new BoxplotRect);let m="";constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;if("ArrowRight"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?w("right",position.x,plot.plotData.length-1):w("right",position.x,plot.sections.length-1):(n=L(),"vert"==constants.plotOrientation?position.x=plot.plotData.length-1:position.x=plot.sections.length-1,e=!0,n=L()):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&plot.sections.length-1!=position.x?(lastY=position.y,w("reverse-right",plot.plotData.length-1,position.x)):(-1==position.x&&position.y==plot.sections.length&&(position.y-=1),position.x+=1,e=!0,n=L()):t.altKey&&t.shiftKey&&plot.sections.length-1!=position.x?(constants.lastx=position.x,w("reverse-right",plot.sections.length-1,position.x)):(-1==position.x&&position.y==plot.plotData.length&&(position.y-=1),position.x+=1,e=!0,n=L()),constants.navigation=1),"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?w("left",position.x,-1):(position.x=0,e=!0,n=L()):t.altKey&&t.shiftKey&&position.x>0?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,w("reverse-left",0,position.x)):(position.x+=-1,e=!0,n=L()),constants.navigation=1),"ArrowUp"==t.key){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?w("up",position.y,plot.sections.length):w("up",position.y,plot.plotData.length):("vert"==constants.plotOrientation?position.y=plot.sections.length-1:position.y=plot.plotData.length-1,e=!0,n=L()):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&position.y!=plot.sections.length-1?(lastY=position.y,w("reverse-up",plot.sections.length-1,position.y)):(position.y+=1,e=!0,n=L()):t.altKey&&t.shiftKey&&position.y!=plot.sections.length-1?(constants.lastx=position.x,w("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,e=!0,n=L()),constants.navigation=0}if("ArrowDown"==t.key){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?w("down",position.y,-1):(position.y=0,e=!0,n=L()):t.altKey&&t.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,w("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.sections.length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,e=!0,n=L()),constants.navigation=0}e&&!n&&M(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1,s=!1;if("ArrowRight"==t.key)t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?w("right",position.x,plot.plotData.length-1):w("right",position.x,plot.sections.length):("vert"==constants.plotOrientation?position.x=plot.plotData.length-1:position.x=plot.sections.length-1,e=!0,s=L()):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&plot.plotData.length-1!=position.x?(lastY=position.y,w("reverse-right",plot.plotData.length-1,position.x)):(-1==position.x&&position.y==plot.plotData[position.x].length&&(position.y-=1),position.x+=1,e=!0,s=L()):t.altKey&&t.shiftKey&&plot.sections.length-1!=position.x?(constants.lastx=position.x,w("reverse-right",plot.sections.length-1,position.x)):(-1==position.x&&position.y==plot.plotData.length&&(position.y-=1),position.x+=1,e=!0,s=L()),n=!0,constants.navigation=1;else if("ArrowLeft"==t.key)t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?w("left",position.x,-1):(position.x=0,e=!0,s=L()):t.altKey&&t.shiftKey&&position.x>0?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,w("reverse-left",0,position.x)):(position.x+=-1,e=!0,s=L()),n=!0,constants.navigation=1;else if("ArrowUp"==t.key){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?(position.x<0&&(position.x=0),w("up",position.y,plot.sections.length)):w("up",position.y,plot.plotData.length):"vert"==constants.plotOrientation?(position.y=plot.sections.length-1,e=!0):(position.y=plot.plotData.length-1,e=!0):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&position.y!=plot.sections.length-1?(lasY=position.y,w("reverse-up",plot.sections.length-1,position.y)):(position.y+=1,e=!0,s=L()):t.altKey&&t.shiftKey&&position.y!=plot.plotData.length-1?(constants.lastx=position.x,w("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,e=!0,s=L()),"vert"==constants.plotOrientation||(n=!0),constants.navigation=0}else if("ArrowDown"==t.key){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?w("down",position.y,-1):(position.y=0,e=!0,s=L()):t.altKey&&t.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,w("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.sections.length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,e=!0,s=L()),constants.navigation=0,"vert"==constants.plotOrientation||(n=!0),constants.navigation=0}else"Tab"==t.key||t.preventDefault();e&&!s&&(n&&display.SetBraille(plot),setTimeout(_,50)),s&&audio.playEnd()}]);let f=[constants.chart,constants.brailleInput],x=0;for(let E=0;E<f.length;E++)constants.events.push([f[E],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),v(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),v(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),v(),display.announceText("Speed reset"))}]);function v(){null!=constants.autoplayId&&(constants.KillAutoplay(),"reverse-left"==m?"vert"==constants.plotOrientation?w("right",position.y,lastY):w("right",position.x,x):"reverse-right"==m?"vert"==constants.plotOrientation?w("left",position.y,lastY):w("left",position.x,x):"reverse-up"==m?"vert"==constants.plotOrientation?w("down",position.y,lastY):w("down",position.x,x):"reverse-down"==m?"vert"==constants.plotOrientation?w("up",position.y,lastY):w("up",position.x,x):"vert"==constants.plotOrientation?w(m,position.y,lastY):w(m,position.x,x))}function M(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&g.UpdateRect(),"off"!=constants.sonifMode&&plot.PlayTones()}function b(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&g.UpdateRect(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function _(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&constants.hasRect&&g.UpdateRect(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function L(){let t=!1;return position.y<0&&(position.y=0,t=!0),position.x<0&&(position.x=0,t=!0),"vert"==constants.plotOrientation?(position.x>plot.plotData.length-1&&(position.x=plot.plotData.length-1,t=!0),position.y>plot.sections.length-1&&(position.y=plot.sections.length-1,t=!0)):(position.y>plot.plotData.length-1&&(position.y=plot.plotData.length-1,t=!0),position.x>plot.sections.length-1&&(position.x=plot.sections.length-1,t=!0)),t}function w(t,e,n){m=t;let s=1;"left"!=t&&"down"!=t&&"reverse-right"!=t&&"reverse-up"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.debugLevel>0&&console.log("starting autoplay",t,e,n),b(),constants.autoplayId=setInterval((function(){let e=!1;"left"==t||"right"==t||"up"==t||"down"==t?(position.x<1&&"left"==t||"vert"==constants.plotOrientation&&"up"==t&&position.y>plot.sections.length-2||"horz"==constants.plotOrientation&&"up"==t&&position.y>plot.plotData.length-2||"horz"==constants.plotOrientation&&"right"==t&&position.x>plot.sections.length-2||"vert"==constants.plotOrientation&&"right"==t&&position.x>plot.plotData.length-2||"horz"==constants.plotOrientation&&"down"==t&&position.y<1||"vert"==constants.plotOrientation&&"down"==t&&position.y<1)&&(e=!0):("reverse-left"==t&&position.x>=n||"reverse-right"==t&&position.x<=n||"reverse-up"==t&&position.y<=n||"reverse-down"==t&&position.y>=n)&&(e=!0),e?constants.KillAutoplay():("left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?position.x+=s:position.y+=s,b()),constants.debugLevel>5&&console.log("autoplay pos",position)}),constants.autoPlayRate)}}else if([].concat(singleMaidr.type).includes("heat")){constants.plotId="geom_rect.rect.2.1",window.position=new Position(-1,-1),window.plot=new HeatMap;let S=new HeatMapRect,D="";constants.lastx=0,constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,R("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,e=!0):t.altKey&&t.shiftKey&&position.x!=plot.num_cols-1?(constants.lastx=position.x,R("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,e=!0,n=k()),constants.navigation=1),"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,R("left",position.x,-1)):(position.x=0,e=!0):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,R("reverse-left",-1,position.x)):(position.x-=1,e=!0,n=k()),constants.navigation=1),"ArrowUp"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.y+=1,R("up",position.y,-1)):(position.y=0,e=!0):t.altKey&&t.shiftKey&&0!=position.y?(constants.lastx=position.x,R("reverse-up",-1,position.y)):(position.y-=1,e=!0,n=k()),constants.navigation=0),"ArrowDown"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.y-=1,R("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,e=!0):t.altKey&&t.shiftKey&&position.y!=plot.num_rows-1?(constants.lastx=position.x,R("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,e=!0,n=k()),constants.navigation=0),e&&!n&&T(),n&&audio.playEnd()}]);let A=[constants.chart,constants.brailleInput],I=0;for(let B=0;B<A.length;B++)constants.events.push([A[B],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),P(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),P(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),P(),display.announceText("Speed reset"))}]);function P(){null!=constants.autoplayId&&(constants.KillAutoplay(),R("reverse-left"==D?"right":"reverse-right"==D?"left":"reverse-up"==D?"down":"reverse-down"==D?"up":D,position.x,I))}function k(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.num_cols-1&&(position.x=plot.num_cols-1,t=!0),position.y<0&&(position.y=0,t=!0),position.y>plot.num_rows-1&&(position.y=plot.num_rows-1,t=!0),t}function T(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&S.UpdateRectDisplay(),"off"!=constants.sonifMode&&plot.PlayTones()}function K(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&S.UpdateRectDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function C(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&constants.hasRect&&S.UpdateRectDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function R(t,e,n){D=t;let s=1;"left"!=t&&"up"!=t&&"reverse-right"!=t&&"reverse-down"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.autoplayId=setInterval((function(){"left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?(position.x+=s,position.x<0||plot.num_cols-1<position.x?(constants.KillAutoplay(),k()):position.x==n?(constants.KillAutoplay(),K()):K()):(position.y+=s,position.y<0||plot.num_rows-1<position.y?(constants.KillAutoplay(),k()):position.y==n?(constants.KillAutoplay(),K()):K())}),constants.autoPlayRate)}constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;if("ArrowRight"==t.key)if(t.target.selectionStart>t.target.value.length-3||"⠳"==t.target.value.substring(t.target.selectionStart+1,t.target.selectionStart+2))t.preventDefault();else{(constants.isMac?t.metaKey:t.ctrlKey)?(-1==position.x&&-1==position.y&&(position.x+=1,position.y+=1),t.shiftKey?(position.x-=1,R("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,e=!0)):t.altKey&&t.shiftKey&&position.x!=plot.num_cols-1?(constants.lastx=position.x,R("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,e=!0,n=k());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=1}else if("ArrowLeft"==t.key)if(0==t.target.selectionStart||"⠳"==t.target.value.substring(t.target.selectionStart-1,t.target.selectionStart))t.preventDefault();else{(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,R("left",position.x,-1)):(position.x=0,e=!0):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,R("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=k());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=1}else if("ArrowDown"==t.key)if(position.y+1==plot.num_rows)t.preventDefault();else{(constants.isMac?t.metaKey:t.ctrlKey)?(-1==position.x&&-1==position.y&&(position.x+=1,position.y+=1),t.shiftKey?(position.y-=1,R("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,e=!0)):t.altKey&&t.shiftKey&&position.y!=plot.num_rows-1?(constants.lastx=position.x,R("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,e=!0,n=k());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=0}else if("ArrowUp"==t.key)if(t.target.selectionStart-plot.num_cols-1<0)t.preventDefault();else{(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.y+=1,R("up",position.y,-1)):(position.y=0,e=!0):t.altKey&&t.shiftKey&&0!=position.y?(constants.lastx=position.x,R("reverse-up",-1,position.y)):(position.y+=-1,e=!0,n=k());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=0}else"Tab"==t.key||t.preventDefault();e&&!n&&C(),n&&audio.playEnd()}])}else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")){constants.plotId="geom_point.points.12.1",window.position=new Position(-1,-1),window.plot=new ScatterPlot;let O=new Layer0Point,N=new Layer1Point,Y="";constants.lastx=0;let U=0;window.positionL1=new Position(U,U),constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;"point"==constants.chartType?("ArrowRight"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,Q("right",position.x,plot.x.length)):(position.x=plot.x.length-1,e=!0,n=V()):t.altKey&&t.shiftKey&&position.x!=plot.x.length-1?(constants.lastx=position.x,Q("reverse-right",plot.x.length,position.x)):(position.x+=1,e=!0,n=V())),"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,Q("left",position.x,-1)):(position.x=0,e=!0,n=V()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,Q("reverse-left",-1,position.x)):(position.x-=1,e=!0,n=V()))):"smooth"==constants.chartType&&(positionL1.x||(positionL1.x=U),"ArrowRight"==t.key&&t.shiftKey&&((constants.isMac?t.metaKey:t.ctrlKey)&&"off"!=constants.sonifMode?z("right"):t.altKey&&"off"!=constants.sonifMode&&z("reverse-right")),"ArrowLeft"==t.key&&t.shiftKey&&((constants.isMac?t.metaKey:t.ctrlKey)&&"off"!=constants.sonifMode?z("left"):t.altKey&&"off"!=constants.sonifMode&&z("reverse-left"))),e&&"point"==constants.chartType&&!n&&X(),n&&audio.playEnd()}]);let G=[constants.chart,constants.brailleInput],q=0;for(let $=0;$<G.length;$++)constants.events.push([G[$],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),F(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),F(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),F(),display.announceText("Speed reset"))}]);function F(){null!=constants.autoplayId&&(constants.KillAutoplay(),audio.KillSmooth(),"reverse-left"==Y?"point"==constants.chartType?Q("right",position.x,q):"smooth"==constants.chartType&&Q("right",positionL1.x,U):"reverse-right"==Y?"point"==constants.chartType?Q("left",position.x,q):"smooth"==constants.chartType&&Q("left",positionL1.x,U):"point"==constants.chartType?Q(Y,position.x,q):"smooth"==constants.chartType&&Q(Y,positionL1.x,U))}function V(){let t=!1;return"point"==constants.chartType?(position.x<0&&(position.x=0,t=!0),position.x>plot.x.length-1&&(position.x=plot.x.length-1,t=!0)):"smooth"==constants.chartType&&(positionL1.x<0&&(positionL1.x=0,t=!0),positionL1.x>plot.curvePoints.length-1&&(positionL1.x=plot.curvePoints.length-1,t=!0)),t}function X(){constants.showDisplay&&display.displayValues(),O.hasRect&&O.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones()}function j(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&("point"==constants.chartType&&O.hasRect?O.UpdatePointDisplay():"smooth"==constants.chartType&&N.hasRect&&N.UpdatePointDisplay()),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function H(){constants.showDisplayInBraille&&display.displayValues(),N.hasRect&&N.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function Q(t,e,n){Y=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),constants.autoplayId&&constants.KillAutoplay(),constants.isSmoothAutoplay&&audio.KillSmooth(),"reverse-left"!=t&&"reverse-right"!=t||(position.x=e,position.L1x=e),"point"==constants.chartType?constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||position.x>plot.y.length-1?(constants.KillAutoplay(),V()):position.x==n?(constants.KillAutoplay(),j()):j()}),constants.autoPlayRate):"smooth"==constants.chartType&&(constants.autoplayId=setInterval((function(){positionL1.x+=s,positionL1.x<0||positionL1.x>plot.curvePoints.length-1?(constants.KillAutoplay(),V()):positionL1.x==n?(constants.KillAutoplay(),j()):j()}),constants.autoPlayRate))}function z(t){Y=t;let e=[],n=[],s=audio.SlideBetween(positionL1.x,0,plot.curvePoints.length-1,-1,1),o=positionL1.x<0?0:positionL1.x,i=0;if("right"==t){for(let t=o;t<plot.curvePoints.length;t++)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[s,1],i=Math.abs(plot.curvePoints.length-o)/plot.curvePoints.length*3}else if("left"==t){for(let t=o;t>=0;t--)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[s,-1],i=Math.abs(o)/plot.curvePoints.length*3}else if("reverse-right"==t){for(let t=plot.curvePoints.length-1;t>=o;t--)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[1,s],i=Math.abs(plot.curvePoints.length-o)/plot.curvePoints.length*3}else if("reverse-left"==t){for(let t=0;t<=o;t++)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[-1,s],i=Math.abs(o)/plot.curvePoints.length*3}constants.isSmoothAutoplay&&audio.KillSmooth(),audio.playSmooth(e,i,n,constants.vol,"sine")}constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"smooth"==constants.chartType?(V(),"ArrowRight"==t.key?(t.preventDefault(),constants.brailleInput.setSelectionRange(positionL1.x,positionL1.x),t.target.selectionStart>t.target.value.length-2?t.preventDefault():(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(positionL1.x-=1,Q("right",positionL1.x,plot.curvePoints.length)):(positionL1.x=plot.curvePoints.length-1,e=!0,n=V()):t.altKey&&t.shiftKey&&positionL1.x!=plot.curvePoints.length-1?(U=positionL1.x,Q("reverse-right",plot.curvePoints.length,positionL1.x)):(positionL1.x+=1,e=!0,n=V())):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(positionL1.x+=1,Q("left",positionL1.x,-1)):(positionL1.x=0,e=!0,n=V()):t.altKey&&t.shiftKey&&0!=positionL1.x?Q("reverse-left",-1,positionL1.x):(positionL1.x-=1,e=!0,n=V())):t.preventDefault()):"Tab"==t.key||t.preventDefault(),U=positionL1.x,e&&!n&&H(),n&&audio.playEnd()}])}else if([].concat(singleMaidr.type).includes("hist")){window.position=new Position(-1,-1),window.plot=new Histogram;let J="";constants.lastx=0,constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;"ArrowRight"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(t.preventDefault(),position.x-=1,it("right",position.x,plot.plotData.length)):"ArrowRight"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(t.preventDefault(),constants.lastx=position.x,it("reverse-right",plot.bars.length,position.x)):"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(t.preventDefault(),position.x=plot.plotData.length-1,e=!0,n=et()):(t.preventDefault(),position.x+=1,e=!0,n=et()),"ArrowLeft"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(t.preventDefault(),position.x+=1,it("left",position.x,-1)):"ArrowLeft"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(t.preventDefault(),constants.lastx=position.x,it("reverse-left",-1,position.x)):"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(t.preventDefault(),position.x=0,e=!0,n=et()):(t.preventDefault(),position.x+=-1,e=!0,n=et()),e&&!n&&("off"==constants.brailleMode?nt():ot()),n&&audio.playEnd()}]);let W=[constants.chart,constants.brailleInput],Z=0;for(let at=0;at<W.length;at++)constants.events.push([W[at],"keydown",function(t){"."==t.key&&(t.preventDefault(),constants.SpeedUp(),tt(),display.announceText("Speed up")),","==t.key&&(t.preventDefault(),constants.SpeedDown(),tt(),display.announceText("Speed down")),"/"==t.key&&(t.preventDefault(),constants.SpeedReset(),tt(),display.announceText("Speed reset"))}]);function tt(){null!=constants.autoplayId&&(constants.KillAutoplay(),it("reverse-left"==J?"right":"reverse-right"==J?"left":J,position.x,Z))}function et(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.plotData.length-1&&(position.x=plot.plotData.length-1,t=!0),t}function nt(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones()}function st(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function ot(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function it(t,e,n){J=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),et()):position.x==n?(constants.KillAutoplay(),st()):st()}),constants.autoPlayRate)}}else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar")){window.position=new Position(-1,-1),window.plot=new Segmented;let lt="";constants.lastx=0,constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;constants.navigation=0,"on"==constants.brailleMode&&("Tab"==t.key||t.preventDefault()),"ArrowRight"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(position.x-=1,gt("right",position.x,plot.plotData.length)):"ArrowRight"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,gt("reverse-right",plot.plotData.length,position.x)):"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.x=plot.plotData.length-1,e=!0,n=dt()):(position.x+=1,e=!0,constants.navigation=1,n=dt()),"ArrowLeft"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(position.x+=1,gt("left",position.x,-1)):"ArrowLeft"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,gt("reverse-left",-1,position.x)):"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.x=0,e=!0,n=dt()):(position.x+=-1,e=!0,constants.navigation=1,n=dt()),"ArrowUp"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowUp"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?gt("up",position.y,plot.plotData[0].length):"ArrowUp"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,gt("reverse-up",-1,plot.plotData[0].length)):"ArrowUp"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.y=plot.plotData[0].length-1,e=!0):(position.y+=1,e=!0,constants.navigation=0,n=dt()),"ArrowDown"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowDown"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?gt("down",position.y,-1):"ArrowDown"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,gt("reverse-down",-1,position.y)):"ArrowDown"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.y=0,e=!0):(position.y+=-1,e=!0,constants.navigation=0,n=dt()),e&&!n&&("off"==constants.brailleMode?ht():yt()),n&&audio.playEnd()}]);let rt=[constants.chart,constants.brailleInput],ct=0;for(let mt=0;mt<rt.length;mt++)constants.events.push([rt[mt],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),pt(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),pt(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),pt(),display.announceText("Speed reset"))}]);function pt(){null!=constants.autoplayId&&(constants.KillAutoplay(),gt("reverse-left"==lt?"right":"reverse-right"==lt?"left":"reverse-up"==lt?"down":"reverse-down"==lt?"up":lt,position.x,ct))}function dt(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.level.length-1&&(position.x=plot.plotData.length-1,t=!0),position.y<0&&(position.y=0,t=!0),position.y>plot.fill.length-1&&(position.y=plot.fill.length-1,t=!0),t}function ht(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones()}function ut(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function yt(){constants.showDisplayInBraille&&(display.SetBraille(),display.displayValues()),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function gt(t,e,n){lt=t;let s=1;"left"!=t&&"down"!=t&&"reverse-right"!=t&&"reverse-up"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.autoplayId=setInterval((function(){"left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?(position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),dt()):position.x==n?(constants.KillAutoplay(),ut()):ut()):(position.y+=s,position.y<0||plot.plotData[0].length-1<position.y?(constants.KillAutoplay(),dt()):position.y==n?(constants.KillAutoplay(),ut()):ut())}),constants.autoPlayRate)}}else if("line"==singleMaidr.type){window.position=new Position(-1,-1),window.plot=new LinePlot;let ft=new Point,xt="";constants.lastx=0,constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,St("right",position.x,plot.pointValuesY.length)):(position.x=plot.pointValuesY.length-1,e=!0,n=_t()):t.altKey&&t.shiftKey&&position.x!=plot.pointValuesY.length-1?(constants.lastx=position.x,St("reverse-right",plot.pointValuesY.length,position.x)):(position.x+=1,e=!0,n=_t()):"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,St("left",position.x,-1)):(position.x=0,e=!0,n=_t()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,St("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=_t())),e&&!n&&Lt(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(t.preventDefault(),t.target.selectionStart>t.target.value.length-2||((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,St("right",position.x,plot.pointValuesY.length)):(position.x=plot.pointValuesY.length-1,e=!0,n=_t()):t.altKey&&t.shiftKey&&position.x!=plot.pointValues.length-1?(constants.lastx=position.x,St("reverse-right",plot.pointValuesY.length,position.x)):(position.x+=1,e=!0,n=_t()))):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,St("left",position.x,-1)):(position.x=0,e=!0,n=_t()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,St("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=_t())):"Tab"==t.key||t.preventDefault(),e&&!n&&Et(),n&&audio.playEnd()}]);let vt=[constants.chart,constants.brailleInput],Mt=0;for(let Dt=0;Dt<vt.length;Dt++)constants.events.push([vt[Dt],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),bt(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),bt(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),bt(),display.announceText("Speed reset"))}]);function bt(){null!=constants.autoplayId&&(constants.KillAutoplay(),St("reverse-left"==xt?"right":"reverse-right"==xt?"left":xt,position.x,Mt))}function _t(){let t=!1;return position.x<0&&(position.x=0,t=!0),position.x>plot.pointValuesY.length-1&&(position.x=plot.pointValuesY.length-1,t=!0),t}function Lt(){constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect&&ft.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones()}function wt(){constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&ft.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}function Et(){constants.showDisplayInBraille&&display.displayValues(),constants.showRect&&ft.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}function St(t,e,n){xt=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.pointValuesY.length-1<position.x?(constants.KillAutoplay(),_t()):position.x==n?(constants.KillAutoplay(),wt()):wt()}),constants.autoPlayRate)}}}GetNextPrevFocusable(t="next"){let e='a[href], button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';constants.focusables=Array.from(document.querySelectorAll(e));let n=constants.focusables.indexOf(constants.chart),s=constants.main_container.querySelectorAll(e);for(let t=0;t<s.length;t++){let e=constants.focusables.indexOf(s[t]);e>-1&&constants.focusables.splice(e,1),n>e&&n--}}}function InitMaidr(t){if("undefined"!=typeof constants){window.singleMaidr=t,constants.chartId=singleMaidr.id,Array.isArray(singleMaidr.type)?constants.chartType=singleMaidr.type[0]:constants.chartType=singleMaidr.type,CreateChartComponents(singleMaidr),window.control=new Control,window.review=new Review,window.display=new Display,window.audio=new Audio;let e=[constants.chart,constants.brailleInput,constants.review];for(let t=0;t<e.length;t++)constants.events.push([e[t],"blur",ShouldWeDestroyMaidr]);constants.events.push([document,"keydown",KillAutoplayEvent]),this.SetEvents(),"name"in singleMaidr?display.announceText(singleMaidr.name):"title"in singleMaidr&&display.announceText(singleMaidr.title)}}function ShouldWeInitMaidr(t){"undefined"==typeof singleMaidr?InitMaidr(t):singleMaidr?t.id!==singleMaidr.id&&(DestroyMaidr(),InitMaidr(t)):InitMaidr(t)}function ShouldWeDestroyMaidr(t){setTimeout((()=>{0==constants.tabMovement?constants.tabMovement=null:(1!=constants.tabMovement&&-1!=constants.tabMovement||FocusBeforeOrAfter(),DestroyMaidr())}),0)}function FocusBeforeOrAfter(){if(1==constants.tabMovement){let t=document.createElement("div");t.setAttribute("tabindex","0"),constants.main_container.after(t),t.focus(),t.remove()}else if(-1==constants.tabMovement){let t=document.createElement("div");t.setAttribute("tabindex","0"),constants.main_container.before(t),t.focus(),t.remove()}}function DestroyMaidr(){"bar"!=constants.chartType&&"hist"!=constants.chartType||("function"==typeof plot.DeselectAll&&plot.DeselectAll(),"function"==typeof plot.UnSelectPrevious&&plot.UnSelectPrevious());for(let t=0;t<constants.events.length;t++)if(Array.isArray(constants.events[t][0]))for(let e=0;e<constants.events[t][0].length;e++)constants.events[t][0][e].removeEventListener(constants.events[t][1],constants.events[t][2]);else constants.events[t][0].removeEventListener(constants.events[t][1],constants.events[t][2]);for(let t=0;t<constants.postLoadEvents.length;t++)if(Array.isArray(constants.postLoadEvents[t][0]))for(let e=0;e<constants.postLoadEvents[t][0].length;e++)constants.postLoadEvents[t][0][e].removeEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);else constants.postLoadEvents[t][0].removeEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);constants.events=[],constants.postLoadEvents=[],constants.chartId=null,constants.chartType=null,constants.tabMovement=null,DestroyChartComponents(),window.review=null,window.display=null,window.control=null,window.plot=null,window.audio=null,window.singleMaidr=null}function KillAutoplayEvent(t){(constants.isMac?"Meta"==t.key||"ContextMenu"==t.key:"Control"==t.key)&&constants.KillAutoplay()}function SetEvents(){for(let t=0;t<constants.events.length;t++)if(Array.isArray(constants.events[t][0]))for(let e=0;e<constants.events[t][0].length;e++)constants.events[t][0][e].addEventListener(constants.events[t][1],constants.events[t][2]);else constants.events[t][0].addEventListener(constants.events[t][1],constants.events[t][2]);setTimeout((function(){for(let t=0;t<constants.postLoadEvents.length;t++)if(Array.isArray(constants.postLoadEvents[t][0]))for(let e=0;e<constants.postLoadEvents[t][0].length;e++)constants.postLoadEvents[t][0][e].addEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);else constants.postLoadEvents[t][0].addEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2])}),100)}function CreateChartComponents(){let t=document.getElementById(singleMaidr.id),e=document.createElement("div");e.id=constants.main_container_id;let n=document.createElement("div");n.id=constants.chart_container_id,t.parentNode.replaceChild(e,t),e.appendChild(t),t.parentNode.replaceChild(n,t),n.appendChild(t),t.focus(),constants.chart=t,constants.chart_container=n,constants.main_container=e,constants.chart_container.insertAdjacentHTML("beforebegin",'<div class="hidden" id="'+constants.braille_container_id+'">\n<input id="'+constants.braille_input_id+'" class="braille-input" type="text" size="'+constants.brailleDisplayLength+'" aria-brailleroledescription="" />\n</div>\n'),constants.chart_container.insertAdjacentHTML("afterend",'<br>\n<div id="'+constants.info_id+'" aria-live="assertive" aria-atomic="true">\n<p id="x"></p>\n<p id="y"></p>\n</div>\n'),document.getElementById(constants.info_id).insertAdjacentHTML("afterend",'<div id="announcements" aria-live="assertive" aria-atomic="true" class="mb-3"></div>\n'),document.getElementById(constants.info_id).insertAdjacentHTML("beforebegin",'<div id="'+constants.review_id_container+'" class="hidden sr-only sr-only-focusable"><input id="'+constants.review_id+'" type="text" readonly size="50" /></div>'),constants.chart_container.setAttribute("role","application"),constants.brailleContainer=document.getElementById(constants.braille_container_id),constants.brailleInput=document.getElementById(constants.braille_input_id),constants.infoDiv=document.getElementById(constants.info_id),constants.announceContainer=document.getElementById(constants.announcement_container_id),constants.nonMenuFocus=constants.chart,constants.endChime=document.getElementById(constants.end_chime_id),constants.review_container=document.querySelector("#"+constants.review_id_container),constants.review=document.querySelector("#"+constants.review_id),window.menu=new Menu,window.chatLLM=new ChatLLM,window.description=new Description}function DestroyChartComponents(){null!=constants.chart_container&&(null!=constants.chart&&null!=constants.chart_container.parentNode&&constants.chart_container.parentNode.replaceChild(constants.chart,constants.chart_container),constants.chart_container.remove()),null!=constants.brailleContainer&&constants.brailleContainer.remove(),null!=constants.infoDiv&&constants.infoDiv.remove(),null!=constants.announceContainer&&constants.announceContainer.remove(),null!=constants.endChime&&constants.endChime.remove(),null!=constants.review_container&&constants.review_container.remove(),"undefined"!=typeof menu&&menu.Destroy(),"undefined"!=typeof description&&description.Destroy(),constants.chart=null,constants.chart_container=null,constants.brailleContainer=null,constants.brailleInput=null,constants.infoDiv=null,constants.announceContainer=null,constants.endChime=null,constants.review_container=null,menu=null,description=null}document.addEventListener("DOMContentLoaded",(function(t){window.constants=new Constants,window.resources=new Resources,window.logError=new LogError;let e=[];"undefined"!=typeof maidr&&(Array.isArray(maidr)?e=maidr:e.push(maidr)),DestroyMaidr(),window.maidrIds=[];for(let t=0;t<e.length;t++){let n=e[t].id;maidrIds.push(n);let s=document.getElementById(n);s&&(s.setAttribute("tabindex","0"),s.addEventListener("focus",(function(n){ShouldWeInitMaidr(e[t])})))}constants.canTrack&&(window.tracker=new Tracker,document.getElementById("download_data_trigger")&&document.getElementById("download_data_trigger").addEventListener("click",(function(t){tracker.DownloadTrackerData()})),document.addEventListener("keydown",(function(t){("F5"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)||"R"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey))&&(t.preventDefault(),tracker.Delete(),location.reload(!0)),"F10"==t.key?tracker.DownloadTrackerData():plot&&tracker.LogEvent(t),document.getElementById("info")})))}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maidr",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.0",
|
|
4
4
|
"description": "maidr: Multimodal Access and Interactive Data Representation. maidr is a system for non-visual access and control of statistical charts. It aims to provide an inclusive experience for users with visual impairments by offering multiple modes of interaction: braille, text, and sonification. This comprehensive approach enhances the accessibility of data visualization and encourages a multi-model exploration on visualization. Check out the current build: [MAIDR Demo](https://xability.github.io/maidr/user_study_pilot/intro.html).",
|
|
5
5
|
"main": "dist/maidr.js",
|
|
6
6
|
"scripts": {
|