diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..323143d
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,17 @@
+# Check http://editorconfig.org for more information
+# This is the main config file for this project:
+root = true
+
+[*]
+charset = utf-8
+trim_trailing_whitespace = true
+end_of_line = lf
+indent_style = space
+insert_final_newline = true
+indent_size = 2
+
+[*.{rs,py,pyi}]
+indent_size = 4
+
+[*.md]
+max_line_length = 120
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 25735ea..aaefea5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,172 @@
-__pycache__/*
+docs/source
+
+# From https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
.conda/*
+*.py[cod]
+*$py.class
+*.pyc
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+junit/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# Vscode config files
+# .vscode/
+
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+.idea/
+
+.DS_Store
diff --git a/example/bar/example_bar_plot.html b/example/bar/example_bar_plot.html
new file mode 100644
index 0000000..1a6f2c6
--- /dev/null
+++ b/example/bar/example_bar_plot.html
@@ -0,0 +1,338 @@
+
+
+
+ MAIDR
+
+
+
+
+
+
+
+
+
+
+ 2024-02-13T10:29:47.645879
+ image/svg+xml
+
+
+ Matplotlib v3.7.4, https://matplotlib.org/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example/bar/example_bar_plot.py b/example/bar/example_bar_plot.py
new file mode 100644
index 0000000..133cf4a
--- /dev/null
+++ b/example/bar/example_bar_plot.py
@@ -0,0 +1,36 @@
+import os
+
+import matplotlib.pyplot as plt
+import maidr
+import seaborn as sns
+
+
+def get_filepath(filename: str) -> str:
+ current_file_path = os.path.abspath(__file__)
+ directory = os.path.dirname(current_file_path)
+ return os.path.join(directory, filename)
+
+
+def plot():
+ # Load dataset
+ tips = sns.load_dataset("tips")
+
+ # Create a bar plot
+ cut_counts = tips["day"].value_counts()
+ plt.figure(figsize=(10, 6))
+ b_plot = plt.bar(cut_counts.index, list(cut_counts.values), color="skyblue")
+ plt.title("The Number of Tips by Day")
+ plt.xlabel("Day")
+ plt.ylabel("Count")
+
+ return b_plot
+
+
+def main():
+ bar_plot = plot()
+ bar_maidr = maidr.bar(bar_plot)
+ bar_maidr.save(get_filepath("example_bar_plot.html"))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/maidr/__init__.py b/maidr/__init__.py
index d36945c..57c6d78 100644
--- a/maidr/__init__.py
+++ b/maidr/__init__.py
@@ -1,5 +1,6 @@
# __version__ will be automatically updated by python-semantic-release
__version__ = "0.0.1"
-# Import everything from the maidr module
-from .maidr import *
+from .maidr import bar
+
+__all__ = ["bar"]
diff --git a/maidr/core/__init__.py b/maidr/core/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/maidr/core/enum/__init__.py b/maidr/core/enum/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/maidr/core/enum/maidr_key.py b/maidr/core/enum/maidr_key.py
new file mode 100644
index 0000000..fcd93a0
--- /dev/null
+++ b/maidr/core/enum/maidr_key.py
@@ -0,0 +1,18 @@
+from enum import Enum
+
+
+class MaidrKey(Enum):
+ AXES = "axes"
+ CAPTION = "caption"
+ DATA = "data"
+ FILL = "fill"
+ LABEL = "label"
+ LEVEL = "level"
+ ID = "id"
+ ORIENTATION = "orientation"
+ SELECTOR = "selector"
+ SUBTITLE = "subtitle"
+ TITLE = "title"
+ TYPE = "type"
+ X = "x"
+ Y = "y"
diff --git a/maidr/core/enum/plot_type.py b/maidr/core/enum/plot_type.py
new file mode 100644
index 0000000..3cc5faa
--- /dev/null
+++ b/maidr/core/enum/plot_type.py
@@ -0,0 +1,5 @@
+from enum import Enum
+
+
+class PlotType(Enum):
+ BAR = "bar"
diff --git a/maidr/core/maidr.py b/maidr/core/maidr.py
new file mode 100644
index 0000000..dc57d13
--- /dev/null
+++ b/maidr/core/maidr.py
@@ -0,0 +1,87 @@
+from __future__ import annotations
+
+import io
+import json
+from uuid import uuid4
+
+from lxml import html, etree
+from matplotlib.figure import Figure
+
+from maidr.core.maidr_data import MaidrData
+
+
+class Maidr:
+ def __init__(self, fig: Figure, maidr_data: list[MaidrData]) -> None:
+ self._fig = fig
+ self._maidr_data = maidr_data
+ self._html = self.__create_html()
+
+ def save(self, filename: str) -> None:
+ with open(filename, "w") as f:
+ f.write(self._html)
+ print("Successfully saved the MAIDR file to {0}.".format(filename))
+
+ def __create_html(self) -> str:
+ # create svg from `Figure` with maidr.id
+ self._svg = self.__get_svg()
+
+ # unflatten maidr if there is only one plot
+ maidr = self.__unflatten_maidr()
+
+ # inject svg and maidr into html
+ str_html = Maidr.__get_html_template()
+ str_html = str_html.replace("", "\n{0}\n".format(self._svg))
+ str_html = str_html.replace(
+ "",
+ "\nlet maidr = {0}\n".format(json.dumps(maidr, indent=2)),
+ )
+
+ # format html with indentation
+ tree_html = html.fromstring(str_html)
+ return etree.tostring(tree_html, pretty_print=True, encoding="unicode")
+
+ def __unflatten_maidr(self) -> dict | list[dict]:
+ maidr = [m_data.data() for m_data in self._maidr_data]
+ return maidr if len(maidr) != 1 else maidr[0]
+
+ def __get_svg(self) -> str:
+ svg_buffer = io.StringIO()
+ self._fig.savefig(svg_buffer, format="svg")
+ str_svg = svg_buffer.getvalue()
+
+ etree.register_namespace("svg", "http://www.w3.org/2000/svg")
+ tree_svg = etree.fromstring(str_svg.encode(), parser=None)
+ root_svg = None
+ # find the `svg` tag and set unique id if not present else use it
+ for element in tree_svg.iter(tag="{http://www.w3.org/2000/svg}svg"):
+ if "id" not in element.attrib:
+ element.attrib["id"] = Maidr.__get_unique_id()
+ root_svg = element
+ self.__set_maidr_id(element.attrib["id"])
+ break
+
+ svg_buffer = io.StringIO() # Reset the buffer
+ svg_buffer.write(
+ etree.tostring(root_svg, encoding="unicode", pretty_print=True)
+ )
+
+ return svg_buffer.getvalue()
+
+ def __set_maidr_id(self, maidr_id: str) -> None:
+ for maidr in self._maidr_data:
+ maidr.set_id(maidr_id)
+
+ @staticmethod
+ def __get_unique_id() -> str:
+ return str(uuid4())
+
+ @staticmethod
+ def __get_html_template() -> str:
+ return (
+ 'MAIDR'
+ ' -->
"
+ ""
+ )
diff --git a/maidr/core/maidr_data.py b/maidr/core/maidr_data.py
new file mode 100644
index 0000000..c028c98
--- /dev/null
+++ b/maidr/core/maidr_data.py
@@ -0,0 +1,31 @@
+from __future__ import annotations
+
+from abc import ABC, abstractmethod
+
+from matplotlib.axes import Axes
+
+from maidr.core.enum.maidr_key import MaidrKey
+from maidr.core.enum.plot_type import PlotType
+
+
+class MaidrData(ABC):
+ def __init__(self, axes: Axes, plot, plot_type: PlotType) -> None:
+ # graphic object
+ self.axes = axes
+ self.plot = plot
+
+ # common maidr data
+ self.type = plot_type
+
+ # extract maidr data from `Axes`
+ self.maidr = self._extract_maidr()
+
+ @abstractmethod
+ def _extract_maidr(self) -> dict:
+ pass
+
+ def data(self):
+ return self.maidr
+
+ def set_id(self, maidr_id: str) -> None:
+ self.maidr[MaidrKey.ID.value] = maidr_id
diff --git a/maidr/core/maidr_data_factory.py b/maidr/core/maidr_data_factory.py
new file mode 100644
index 0000000..7cf7f46
--- /dev/null
+++ b/maidr/core/maidr_data_factory.py
@@ -0,0 +1,16 @@
+from __future__ import annotations
+
+from matplotlib.axes import Axes
+
+from maidr.core.enum.plot_type import PlotType
+from maidr.core.maidr_data import MaidrData
+from maidr.core.plot.bar_data import BarData
+
+
+class MaidrDataFactory:
+ @staticmethod
+ def create(axes: Axes, plot, plot_type: PlotType) -> MaidrData:
+ if PlotType.BAR == plot_type:
+ return BarData(axes, plot, plot_type)
+ else:
+ raise ValueError("Unsupported plot type: {0}".format(plot_type))
diff --git a/maidr/core/plot/__init__.py b/maidr/core/plot/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/maidr/core/plot/bar_data.py b/maidr/core/plot/bar_data.py
new file mode 100644
index 0000000..7ca22a4
--- /dev/null
+++ b/maidr/core/plot/bar_data.py
@@ -0,0 +1,60 @@
+from __future__ import annotations
+
+from typing import Iterable
+
+import numpy as np
+from matplotlib.axes import Axes
+from matplotlib.container import BarContainer
+
+from maidr.core.maidr_data import MaidrData
+from maidr.core.enum.maidr_key import MaidrKey
+from maidr.core.enum.plot_type import PlotType
+
+
+class BarData(MaidrData):
+ def __init__(self, axes: Axes, plot, plot_type: PlotType) -> None:
+ super().__init__(axes, plot, plot_type)
+
+ def _extract_maidr(self) -> dict:
+ plt_type = self.type.value
+ ax = self.axes
+
+ maidr = {
+ MaidrKey.TYPE.value: plt_type,
+ MaidrKey.TITLE.value: ax.get_title(),
+ MaidrKey.SELECTOR.value: "TODO: Enter your bar plot selector here",
+ MaidrKey.AXES.value: {
+ MaidrKey.X.value: {
+ MaidrKey.LABEL.value: ax.get_xlabel(),
+ MaidrKey.LEVEL.value: self.__extract_level(),
+ },
+ MaidrKey.Y.value: {
+ MaidrKey.LABEL.value: ax.get_ylabel(),
+ },
+ },
+ MaidrKey.DATA.value: self.__extract_data(),
+ }
+
+ return maidr
+
+ def __extract_level(self) -> list | None:
+ return [label.get_text() for label in self.axes.get_xticklabels()]
+
+ def __extract_data(self) -> list | None:
+ plot = self.plot
+
+ if isinstance(plot, BarContainer) and isinstance(plot.datavalues, Iterable):
+ bc_data = []
+ for value in plot.datavalues:
+ if isinstance(value, np.integer):
+ bc_data.append(int(value))
+ elif isinstance(value, np.floating):
+ bc_data.append(float(value))
+ else:
+ bc_data.append(value)
+ data = bc_data
+ else:
+ # TODO: What would be the right exception? ExtractionError?
+ raise TypeError("")
+
+ return data
diff --git a/maidr/example/js/maidr.js b/maidr/example/js/maidr.js
deleted file mode 100644
index e849415..0000000
--- a/maidr/example/js/maidr.js
+++ /dev/null
@@ -1,6333 +0,0 @@
-class Constants {
- // element ids
- svg_container_id = 'svg-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;
-
- // default constructor for boxplot
- constructor() {
- // page elements
- this.svg_container = document.getElementById(this.svg_container_id);
- this.svg = document.querySelector('#' + this.svg_container_id + ' > svg');
- this.brailleContainer = document.getElementById(this.braille_container_id);
- this.brailleInput = document.getElementById(this.braille_input_id);
- this.infoDiv = document.getElementById(this.info_id);
- this.announceContainer = document.getElementById(
- this.announcement_container_id
- );
- this.nonMenuFocus = this.svg;
- this.endChime = document.getElementById(this.end_chime_id);
- }
-
- // BTS modes
- textMode = 'verbose'; // off / terse / verbose
- brailleMode = 'on'; // on / off
- sonifMode = 'on'; // sep / same / off
- reviewMode = 'off'; // on / off
- layer = 2; // 1 = points; 2 = best fit line => for scatterplot
-
- // basic chart properties
- minX = 0;
- maxX = 0;
- minY = 0;
- maxY = 0;
- plotId = ''; // update with id in chart specific js
- chartType = ''; // set as 'boxplot' or whatever later in chart specific js file
- navigation = 1; // 0 = row navigation (up/down), 1 = col navigation (left/right)
-
- // basic audio properties
- MAX_FREQUENCY = 1000;
- MIN_FREQUENCY = 200;
- NULL_FREQUENCY = 100;
-
- // autoplay speed
- MAX_SPEED = 2000;
- MIN_SPEED = 50;
- INTERVAL = 50;
-
- // user settings
- vol = 0.5;
- MAX_VOL = 30;
- autoPlayRate = 250; // ms per tone
- colorSelected = '#03C809';
- brailleDisplayLength = 40; // num characters in user's braille display. Common length for desktop / mobile applications
-
- // advanced user settings
- showRect = 1; // true / false
- hasRect = 1; // true / false
- duration = 0.3;
- outlierDuration = 0.06;
- autoPlayOutlierRate = 50; // ms per tone
- autoPlayPointsRate = 30;
- colorUnselected = '#595959'; // we don't use this yet, but remember: don't rely on color! also do a shape or pattern fill
- isTracking = 1; // 0 / 1, is tracking on or off
- visualBraille = false; // do we want to represent braille based on what's visually there or actually there. Like if we have 2 outliers with the same position, do we show 1 (visualBraille true) or 2 (false)
-
- // user controls (not exposed to menu, with shortcuts usually)
- showDisplay = 1; // true / false
- showDisplayInBraille = 1; // true / false
- showDisplayInAutoplay = 0; // true / false
- outlierInterval = null;
-
- // platform controls
- isMac = navigator.userAgent.toLowerCase().includes('mac'); // true if macOS
- 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 = 2000; // ms or 2s
-
- // debug stuff
- debugLevel = 3; // 0 = no console output, 1 = some console, 2 = more console, etc
- canPlayEndChime = false; //
- manualData = true; // pull from manual data like chart2music (true), or do the old method where we pull from the svg (false)
-
- PrepChartHelperComponents() {
- // init html stuff. aria live regions, braille input, etc
-
- // info aria live
- if (!document.getElementById(this.info_id)) {
- if (document.getElementById(this.svg_container_id)) {
- document
- .getElementById(this.svg_container_id)
- .insertAdjacentHTML(
- 'afterend',
- ' \n\n'
- );
- }
- }
-
- // announcements aria live
- if (!document.getElementById(this.announcement_container_id)) {
- if (document.getElementById(this.info_id)) {
- document
- .getElementById(this.info_id)
- .insertAdjacentHTML(
- 'afterend',
- '\n
\n'
- );
- }
- }
-
- // braille
- if (!document.getElementById(this.braille_container_id)) {
- if (document.getElementById(this.container_id)) {
- document
- .getElementById(this.container_id)
- .insertAdjacentHTML(
- 'afterbegin',
- '\n \n
\n'
- );
- }
- }
-
- // role app on svg
- if (document.getElementById(this.svg_container_id)) {
- document
- .querySelector('#' + this.svg_container_id + ' > svg')
- .setAttribute('role', 'application');
- document
- .querySelector('#' + this.svg_container_id + ' > svg')
- .setAttribute('tabindex', '0');
- }
-
- // end chime audio element
- if (!document.getElementById(this.end_chime_id)) {
- if (document.getElementById(this.info_id)) {
- document
- .getElementById(this.info_id)
- .insertAdjacentHTML(
- 'afterend',
- ''
- );
- }
- }
- }
-
- KillAutoplay() {
- if (this.autoplayId) {
- clearInterval(this.autoplayId);
- this.autoplayId = null;
- }
- }
-
- KillSepPlay() {
- if (this.sepPlayId) {
- clearInterval(this.sepPlayId);
- this.sepPlayId = null;
- }
- }
-
- SpeedUp() {
- if (constants.autoPlayRate - this.INTERVAL > this.MIN_SPEED) {
- constants.autoPlayRate -= this.INTERVAL;
- }
- }
-
- SpeedDown() {
- if (constants.autoPlayRate + this.INTERVAL <= this.MAX_SPEED) {
- constants.autoPlayRate += this.INTERVAL;
- }
- }
-}
-
-class Resources {
- constructor() {}
-
- language = 'en'; // 2 char lang code
- knowledgeLevel = 'basic'; // basic, intermediate, expert
-
- // these strings run on getters, which pull in language, knowledgeLevel, chart, and actual requested string
- strings = {
- en: {
- basic: {
- upper_outlier: 'Upper Outlier',
- lower_outlier: 'Lower Outlier',
- min: 'Minimum',
- max: 'Maximum',
- 25: '25%',
- 50: '50%',
- 75: '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',
- },
- },
- };
-
- GetString(id) {
- return this.strings[this.language][this.knowledgeLevel][id];
- }
-}
-
-class Menu {
- constructor() {
- this.CreateMenu();
- this.LoadDataFromLocalStorage();
- }
-
- menuHtml = `
-
-
- `;
-
- CreateMenu() {
- document
- .querySelector('body')
- .insertAdjacentHTML('beforeend', this.menuHtml);
- }
-
- Toggle(onoff) {
- if (typeof onoff == 'undefined') {
- if (document.getElementById('menu').classList.contains('hidden')) {
- onoff = true;
- } else {
- onoff = false;
- }
- }
- if (onoff) {
- // open
- this.PopulateData();
- document.getElementById('menu').classList.remove('hidden');
- document.getElementById('modal_backdrop').classList.remove('hidden');
- document.querySelector('#menu .close').focus();
- } else {
- // close
- document.getElementById('menu').classList.add('hidden');
- document.getElementById('modal_backdrop').classList.add('hidden');
- constants.nonMenuFocus.focus();
- }
- }
-
- PopulateData() {
- document.getElementById('vol').value = constants.vol;
- //document.getElementById('show_rect').checked = constants.showRect;
- 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;
- }
-
- SaveData() {
- constants.vol = document.getElementById('vol').value;
- //constants.showRect = document.getElementById('show_rect').checked;
- 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;
- }
-
- SaveDataToLocalStorage() {
- // save all data in this.SaveData() to local storage
- let data = {};
- data.vol = constants.vol;
- //data.showRect = constants.showRect;
- data.autoPlayRate = constants.autoPlayRate;
- data.brailleDisplayLength = constants.brailleDisplayLength;
- data.colorSelected = constants.colorSelected;
- data.MIN_FREQUENCY = constants.MIN_FREQUENCY;
- data.MAX_FREQUENCY = constants.MAX_FREQUENCY;
- data.keypressInterval = constants.keypressInterval;
- localStorage.setItem('settings_data', JSON.stringify(data));
- }
- LoadDataFromLocalStorage() {
- let data = JSON.parse(localStorage.getItem('settings_data'));
- if (data) {
- constants.vol = data.vol;
- //constants.showRect = data.showRect;
- constants.autoPlayRate = data.autoPlayRate;
- constants.brailleDisplayLength = data.brailleDisplayLength;
- constants.colorSelected = data.colorSelected;
- constants.MIN_FREQUENCY = data.MIN_FREQUENCY;
- constants.MAX_FREQUENCY = data.MAX_FREQUENCY;
- constants.keypressInterval = data.keypressInterval;
- }
- }
-}
-
-class Position {
- constructor(x, y, z = -1) {
- this.x = x;
- this.y = y;
- this.z = z; // rarely used
- }
-}
-
-// HELPER FUNCTIONS
-class Helper {
- static containsObject(obj, arr) {
- for (let i = 0; i < arr.length; i++) {
- if (arr[i] === obj) return true;
- }
- return false;
- }
-}
-
-class Tracker {
- constructor() {
- this.DataSetup();
- }
-
- DataSetup() {
- let prevData = this.GetTrackerData();
- if (prevData) {
- // good to go already, do nothing
- } else {
- let data = {};
- data.userAgent = Object.assign(navigator.userAgent);
- data.vendor = Object.assign(navigator.vendor);
- data.language = Object.assign(navigator.language);
- data.platform = Object.assign(navigator.platform);
- data.events = [];
-
- this.SaveTrackerData(data);
- }
- }
-
- DownloadTrackerData() {
- let link = document.createElement('a');
- let data = this.GetTrackerData();
- let fileStr = new Blob([JSON.stringify(data)], { type: 'text/plain' });
- link.href = URL.createObjectURL(fileStr);
- link.download = 'tracking.json';
- link.click();
- }
-
- SaveTrackerData(data) {
- localStorage.setItem(constants.project_id, JSON.stringify(data));
- }
-
- GetTrackerData() {
- let data = JSON.parse(localStorage.getItem(constants.project_id));
- return data;
- }
-
- Delete() {
- localStorage.removeItem(constants.project_id);
- this.data = null;
-
- if (constants.debugLevel > 0) {
- console.log('tracking data cleared');
- }
-
- this.DataSetup();
- }
-
- LogEvent(e) {
- let eventToLog = {};
-
- // computer stuff
- eventToLog.timestamp = Object.assign(e.timeStamp);
- eventToLog.time = Date().toString();
- eventToLog.key = Object.assign(e.key);
- eventToLog.which = Object.assign(e.which);
- eventToLog.altKey = Object.assign(e.altKey);
- eventToLog.ctrlKey = Object.assign(e.ctrlKey);
- eventToLog.shiftKey = Object.assign(e.shiftKey);
- if (e.path) {
- eventToLog.focus = Object.assign(e.path[0].tagName);
- }
-
- // settings etc, which we have to reassign otherwise they'll all be the same val
- if (!this.isUndefinedOrNull(constants.position)) {
- eventToLog.position = Object.assign(constants.position);
- }
- if (!this.isUndefinedOrNull(constants.minX)) {
- eventToLog.min_x = Object.assign(constants.minX);
- }
- if (!this.isUndefinedOrNull(constants.maxX)) {
- eventToLog.max_x = Object.assign(constants.maxX);
- }
- if (!this.isUndefinedOrNull(constants.minY)) {
- eventToLog.min_y = Object.assign(constants.minY);
- }
- if (!this.isUndefinedOrNull(constants.MAX_FREQUENCY)) {
- eventToLog.max_frequency = Object.assign(constants.MAX_FREQUENCY);
- }
- if (!this.isUndefinedOrNull(constants.MIN_FREQUENCY)) {
- eventToLog.min_frequency = Object.assign(constants.MIN_FREQUENCY);
- }
- if (!this.isUndefinedOrNull(constants.NULL_FREQUENCY)) {
- eventToLog.null_frequency = Object.assign(constants.NULL_FREQUENCY);
- }
- if (!this.isUndefinedOrNull(constants.MAX_SPEED)) {
- eventToLog.max_speed = Object.assign(constants.MAX_SPEED);
- }
- if (!this.isUndefinedOrNull(constants.MIN_SPEED)) {
- eventToLog.min_speed = Object.assign(constants.MIN_SPEED);
- }
- if (!this.isUndefinedOrNull(constants.INTERVAL)) {
- eventToLog.interval = Object.assign(constants.INTERVAL);
- }
- if (!this.isUndefinedOrNull(constants.vol)) {
- eventToLog.volume = Object.assign(constants.vol);
- }
- if (!this.isUndefinedOrNull(constants.autoPlayRate)) {
- eventToLog.autoplay_rate = Object.assign(constants.autoPlayRate);
- }
- if (!this.isUndefinedOrNull(constants.colorSelected)) {
- eventToLog.color = Object.assign(constants.colorSelected);
- }
- if (!this.isUndefinedOrNull(constants.brailleDisplayLength)) {
- eventToLog.braille_display_length = Object.assign(
- constants.brailleDisplayLength
- );
- }
- if (!this.isUndefinedOrNull(constants.duration)) {
- eventToLog.tone_duration = Object.assign(constants.duration);
- }
- if (!this.isUndefinedOrNull(constants.autoPlayOutlierRate)) {
- eventToLog.autoplay_outlier_rate = Object.assign(
- constants.autoPlayOutlierRate
- );
- }
- if (!this.isUndefinedOrNull(constants.autoPlayPointsRate)) {
- eventToLog.autoplay_points_rate = Object.assign(
- constants.autoPlayPointsRate
- );
- }
- if (!this.isUndefinedOrNull(constants.textMode)) {
- eventToLog.text_mode = Object.assign(constants.textMode);
- }
- if (!this.isUndefinedOrNull(constants.sonifMode)) {
- eventToLog.sonification_mode = Object.assign(constants.sonifMode);
- }
- if (!this.isUndefinedOrNull(constants.brailleMode)) {
- eventToLog.braille_mode = Object.assign(constants.brailleMode);
- }
- if (!this.isUndefinedOrNull(constants.layer)) {
- eventToLog.layer = Object.assign(constants.layer);
- }
- if (!this.isUndefinedOrNull(constants.chartType)) {
- eventToLog.chart_type = Object.assign(constants.chartType);
- }
- if (!this.isUndefinedOrNull(constants.infoDiv.innerHTML)) {
- let textDisplay = Object.assign(constants.infoDiv.innerHTML);
- textDisplay = textDisplay.replaceAll(/<[^>]*>?/gm, '');
- eventToLog.text_display = textDisplay;
- }
- if (!this.isUndefinedOrNull(location.href)) {
- eventToLog.location = Object.assign(location.href);
- }
-
- // chart specific values
- let x_tickmark = '';
- let y_tickmark = '';
- let x_label = '';
- let y_label = '';
- let value = '';
- let fill_value = '';
- if (constants.chartType == 'barplot') {
- if (!this.isUndefinedOrNull(plot.columnLabels[position.x])) {
- x_tickmark = plot.columnLabels[position.x];
- }
- if (!this.isUndefinedOrNull(plot.plotLegend.x)) {
- x_label = plot.plotLegend.x;
- }
- if (!this.isUndefinedOrNull(plot.plotLegend.y)) {
- y_label = plot.plotLegend.y;
- }
- if (!this.isUndefinedOrNull(plot.plotData[position.x])) {
- value = plot.plotData[position.x];
- }
- } else if (constants.chartType == 'heatmap') {
- if (!this.isUndefinedOrNull(plot.x_labels[position.x])) {
- x_tickmark = plot.x_labels[position.x].trim();
- }
- if (!this.isUndefinedOrNull(plot.y_labels[position.y])) {
- y_tickmark = plot.y_labels[position.y].trim();
- }
- if (!this.isUndefinedOrNull(plot.x_group_label)) {
- x_label = plot.x_group_label;
- }
- if (!this.isUndefinedOrNull(plot.y_group_label)) {
- y_label = plot.y_group_label;
- }
- if (!this.isUndefinedOrNull(plot.values)) {
- if (!this.isUndefinedOrNull(plot.values[position.x][position.y])) {
- value = plot.values[position.x][position.y];
- }
- }
- if (!this.isUndefinedOrNull(plot.group_labels[2])) {
- fill_value = plot.group_labels[2];
- }
- } else if (constants.chartType == 'boxplot') {
- let plotPos =
- constants.plotOrientation == 'vert' ? position.x : position.y;
- let sectionPos =
- constants.plotOrientation == 'vert' ? position.y : position.x;
-
- if (!this.isUndefinedOrNull(plot.x_group_label)) {
- x_label = plot.x_group_label;
- }
- if (!this.isUndefinedOrNull(plot.y_group_label)) {
- y_label = plot.y_group_label;
- }
- if (constants.plotOrientation == 'vert') {
- if (plotPos > -1 && sectionPos > -1) {
- if (
- !this.isUndefinedOrNull(plot.plotData[plotPos][sectionPos].label)
- ) {
- y_tickmark = plot.plotData[plotPos][sectionPos].label;
- }
- if (!this.isUndefinedOrNull(plot.x_labels[position.x])) {
- x_tickmark = plot.x_labels[position.x];
- }
- if (
- !this.isUndefinedOrNull(plot.plotData[plotPos][sectionPos].values)
- ) {
- value = plot.plotData[plotPos][sectionPos].values;
- } else if (
- !this.isUndefinedOrNull(plot.plotData[plotPos][sectionPos].y)
- ) {
- value = plot.plotData[plotPos][sectionPos].y;
- }
- }
- } else {
- if (plotPos > -1 && sectionPos > -1) {
- if (
- !this.isUndefinedOrNull(plot.plotData[plotPos][sectionPos].label)
- ) {
- x_tickmark = plot.plotData[plotPos][sectionPos].label;
- }
- if (!this.isUndefinedOrNull(plot.y_labels[position.y])) {
- y_tickmark = plot.y_labels[position.y];
- }
- if (
- !this.isUndefinedOrNull(plot.plotData[plotPos][sectionPos].values)
- ) {
- value = plot.plotData[plotPos][sectionPos].values;
- } else if (
- !this.isUndefinedOrNull(plot.plotData[plotPos][sectionPos].x)
- ) {
- value = plot.plotData[plotPos][sectionPos].x;
- }
- }
- }
- } else if (constants.chartType == 'scatterplot') {
- if (!this.isUndefinedOrNull(plot.x_group_label)) {
- x_label = plot.x_group_label;
- }
- if (!this.isUndefinedOrNull(plot.y_group_label)) {
- y_label = plot.y_group_label;
- }
-
- if (!this.isUndefinedOrNull(plot.x[position.x])) {
- x_tickmark = plot.x[position.x];
- }
- if (!this.isUndefinedOrNull(plot.y[position.x])) {
- y_tickmark = plot.y[position.x];
- }
-
- value = [x_tickmark, y_tickmark];
- }
-
- eventToLog.x_tickmark = Object.assign(x_tickmark);
- eventToLog.y_tickmark = Object.assign(y_tickmark);
- eventToLog.x_label = Object.assign(x_label);
- eventToLog.y_label = Object.assign(y_label);
- eventToLog.value = Object.assign(value);
- eventToLog.fill_value = Object.assign(fill_value);
-
- //console.log("x_tickmark: '", x_tickmark, "', y_tickmark: '", y_tickmark, "', x_label: '", x_label, "', y_label: '", y_label, "', value: '", value, "', fill_value: '", fill_value);
-
- let data = this.GetTrackerData();
- data.events.push(eventToLog);
- this.SaveTrackerData(data);
- }
-
- isUndefinedOrNull(item) {
- try {
- return item === undefined || item === null;
- } catch {
- return true;
- }
- }
-}
-
-class Review {
- constructor() {
- // review mode form field
- if (!document.getElementById(constants.review_id)) {
- if (document.getElementById(constants.info_id)) {
- document
- .getElementById(constants.info_id)
- .insertAdjacentHTML(
- 'beforebegin',
- '
'
- );
- }
- }
-
- if (constants) {
- constants.review_container = document.querySelector(
- '#' + constants.review_id_container
- );
- constants.review = document.querySelector('#' + constants.review_id);
- }
- }
-
- ToggleReviewMode(onoff = true) {
- // true means on or show
- if (onoff) {
- constants.reviewSaveSpot = document.activeElement;
- constants.review_container.classList.remove('hidden');
- constants.reviewSaveBrailleMode = constants.brailleMode;
- constants.review.focus();
-
- display.announceText('Review on');
- } else {
- constants.review_container.classList.add('hidden');
- if (constants.reviewSaveBrailleMode == 'on') {
- // we have to turn braille mode back on
- display.toggleBrailleMode('on');
- } else {
- constants.reviewSaveSpot.focus();
- }
- display.announceText('Review off');
- }
- }
-}
-
-// Audio class
-// Sets up audio stuff (compressor, gain),
-// sets up an oscillator that has good falloff (no clipping sounds) and can be instanced to be played anytime and can handle overlaps,
-// sets up an actual playTone function that plays tones based on current chart position
-class Audio {
- constructor() {
- this.AudioContext = window['AudioContext'] || window['webkitAudioContext'];
- this.audioContext = new AudioContext();
- this.compressor = this.compressorSetup(this.audioContext);
- }
-
- compressorSetup() {
- let compressor = this.audioContext.createDynamicsCompressor(); // create compressor for better audio quality
-
- compressor.threshold.value = -50;
- compressor.knee.value = 40;
- compressor.ratio.value = 12;
- compressor.attack.value = 0;
- compressor.release.value = 0.25;
- let gainMaster = this.audioContext.createGain(); // create master gain
- gainMaster.gain.value = constants.vol;
- compressor.connect(gainMaster);
- gainMaster.connect(this.audioContext.destination);
-
- return compressor;
- }
-
- // an oscillator is created and destroyed after some falloff
- playTone() {
- let currentDuration = constants.duration;
- let volume = constants.vol;
-
- let rawPanning = 0;
- let rawFreq = 0;
- let frequency = 0;
- let panning = 0;
- // freq goes between min / max as rawFreq goes between min(0) / max
- if (constants.chartType == 'barplot') {
- rawFreq = plot.plotData[position.x];
- rawPanning = position.x;
- frequency = this.SlideBetween(
- rawFreq,
- constants.minY,
- constants.maxY,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- );
- panning = this.SlideBetween(
- rawPanning,
- constants.minX,
- constants.maxX,
- -1,
- 1
- );
- } else if (constants.chartType == 'boxplot') {
- let plotPos =
- constants.plotOrientation == 'vert' ? position.x : position.y;
- let sectionPos =
- constants.plotOrientation == 'vert' ? position.y : position.x;
- if (
- position.z > -1 &&
- Object.hasOwn(plot.plotData[plotPos][sectionPos], 'values')
- ) {
- // outliers are stored in values with a seperate itterator
- rawFreq = plot.plotData[plotPos][sectionPos].values[position.z];
- } else {
- // normal points
- if (constants.plotOrientation == 'vert') {
- rawFreq = plot.plotData[plotPos][sectionPos].y;
- } else {
- rawFreq = plot.plotData[plotPos][sectionPos].x;
- }
- }
- if (plot.plotData[plotPos][sectionPos].type != 'blank') {
- if (constants.plotOrientation == 'vert') {
- frequency = this.SlideBetween(
- rawFreq,
- constants.minY,
- constants.maxY,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- );
- panning = this.SlideBetween(
- rawFreq,
- constants.minY,
- constants.maxY,
- -1,
- 1
- );
- } else {
- frequency = this.SlideBetween(
- rawFreq,
- constants.minX,
- constants.maxX,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- );
- panning = this.SlideBetween(
- rawFreq,
- constants.minX,
- constants.maxX,
- -1,
- 1
- );
- }
- } else {
- frequency = constants.MIN_FREQUENCY;
- panning = 0;
- }
- } else if (constants.chartType == 'heatmap') {
- rawFreq = plot.values[position.y][position.x];
- rawPanning = position.x;
- frequency = this.SlideBetween(
- rawFreq,
- constants.minY,
- constants.maxY,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- );
- panning = this.SlideBetween(
- rawPanning,
- constants.minX,
- constants.maxX,
- -1,
- 1
- );
- } else if (constants.chartType == 'scatterplot') {
- if (constants.layer == 1) {
- // point layer
- // more than one point with same x-value
- rawFreq = plot.y[position.x][position.z];
- if (plot.max_count == 1) {
- volume = constants.vol;
- } else {
- volume = this.SlideBetween(
- plot.points_count[position.x][position.z],
- 1,
- plot.max_count,
- constants.vol,
- constants.MAX_VOL
- );
- }
-
- rawPanning = position.x;
- frequency = this.SlideBetween(
- rawFreq,
- constants.minY,
- constants.maxY,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- );
- panning = this.SlideBetween(
- rawPanning,
- constants.minX,
- constants.maxX,
- -1,
- 1
- );
- } else if (constants.layer == 2) {
- // best fit line layer
-
- rawFreq = plot.curvePoints[positionL1.x];
- rawPanning = positionL1.x;
- frequency = this.SlideBetween(
- rawFreq,
- plot.curveMinY,
- plot.curveMaxY,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- );
- panning = this.SlideBetween(
- rawPanning,
- constants.minX,
- constants.maxX,
- -1,
- 1
- );
- }
- }
-
- if (constants.debugLevel > 5) {
- console.log('will play tone at freq', frequency);
- if (constants.chartType == 'boxplot') {
- console.log(
- 'based on',
- constants.minY,
- '<',
- rawFreq,
- '<',
- constants.maxY,
- ' | freq min',
- constants.MIN_FREQUENCY,
- 'max',
- constants.MAX_FREQUENCY
- );
- } else {
- console.log(
- 'based on',
- constants.minX,
- '<',
- rawFreq,
- '<',
- constants.maxX,
- ' | freq min',
- constants.MIN_FREQUENCY,
- 'max',
- constants.MAX_FREQUENCY
- );
- }
- }
-
- if (constants.chartType == 'boxplot') {
- // different types of sounds for different regions.
- // outlier = short tone
- // whisker = normal tone
- // range = chord
- let plotPos =
- constants.plotOrientation == 'vert' ? position.x : position.y;
- let sectionPos =
- constants.plotOrientation == 'vert' ? position.y : position.x;
- let sectionType = plot.plotData[plotPos][sectionPos].type;
- if (sectionType == 'outlier') {
- currentDuration = constants.outlierDuration;
- } else if (sectionType == 'whisker') {
- //currentDuration = constants.duration * 2;
- } else {
- //currentDuration = constants.duration * 2;
- }
- }
-
- // create tones
- this.playOscillator(frequency, currentDuration, panning, volume, 'sine');
- if (constants.chartType == 'boxplot') {
- let plotPos =
- constants.plotOrientation == 'vert' ? position.x : position.y;
- let sectionPos =
- constants.plotOrientation == 'vert' ? position.y : position.x;
- let sectionType = plot.plotData[plotPos][sectionPos].type;
- if (sectionType == 'range') {
- // also play an octive below at lower vol
- let freq2 = frequency / 2;
- this.playOscillator(
- freq2,
- currentDuration,
- panning,
- constants.vol / 4,
- 'triangle'
- );
- }
- } else if (constants.chartType == 'heatmap') {
- // Added heatmap tone feature
- if (rawFreq == 0) {
- this.PlayNull();
- }
- }
- }
-
- playOscillator(
- frequency,
- currentDuration,
- panning,
- currentVol = 1,
- wave = 'sine'
- ) {
- const t = this.audioContext.currentTime;
- const oscillator = this.audioContext.createOscillator();
- oscillator.type = wave;
- oscillator.frequency.value = parseFloat(frequency);
- oscillator.start();
-
- // create gain for this event
- const gainThis = this.audioContext.createGain();
- gainThis.gain.setValueCurveAtTime(
- [
- 0.5 * currentVol,
- 1 * currentVol,
- 0.5 * currentVol,
- 0.5 * currentVol,
- 0.5 * currentVol,
- 0.1 * currentVol,
- 1e-4 * currentVol,
- ],
- t,
- currentDuration
- ); // this is what makes the tones fade out properly and not clip
-
- let MAX_DISTANCE = 10000;
- let posZ = 1;
- const panner = new PannerNode(this.audioContext, {
- panningModel: 'HRTF',
- distanceModel: 'linear',
- positionX: position.x,
- positionY: position.y,
- positionZ: posZ,
- plotOrientationX: 0.0,
- plotOrientationY: 0.0,
- plotOrientationZ: -1.0,
- refDistance: 1,
- maxDistance: MAX_DISTANCE,
- rolloffFactor: 10,
- coneInnerAngle: 40,
- coneOuterAngle: 50,
- coneOuterGain: 0.4,
- });
-
- // create panning
- const stereoPanner = this.audioContext.createStereoPanner();
- stereoPanner.pan.value = panning;
- oscillator.connect(gainThis);
- gainThis.connect(stereoPanner);
- stereoPanner.connect(panner);
- panner.connect(this.compressor);
-
- // create panner node
-
- // play sound for duration
- setTimeout(() => {
- panner.disconnect();
- gainThis.disconnect();
- oscillator.stop();
- oscillator.disconnect();
- }, currentDuration * 1e3 * 2);
- }
-
- playSmooth(
- freqArr = [600, 500, 400, 300],
- currentDuration = 2,
- panningArr = [-1, 0, 1],
- currentVol = 1,
- wave = 'sine'
- ) {
- // todo: make smooth duration dependant on how much line there is to do. Like, at max it should be max duration, but if we only have like a tiny bit to play we should just play for a tiny bit
-
- let gainArr = new Array(freqArr.length * 3).fill(0.5 * currentVol);
- gainArr.push(1e-4 * currentVol);
-
- const t = this.audioContext.currentTime;
- const smoothOscillator = this.audioContext.createOscillator();
- smoothOscillator.type = wave;
- smoothOscillator.frequency.setValueCurveAtTime(freqArr, t, currentDuration);
- smoothOscillator.start();
- constants.isSmoothAutoplay = true;
-
- // create gain for this event
- this.smoothGain = this.audioContext.createGain();
- this.smoothGain.gain.setValueCurveAtTime(gainArr, t, currentDuration); // this is what makes the tones fade out properly and not clip
-
- let MAX_DISTANCE = 10000;
- let posZ = 1;
- const panner = new PannerNode(this.audioContext, {
- panningModel: 'HRTF',
- distanceModel: 'linear',
- positionX: position.x,
- positionY: position.y,
- positionZ: posZ,
- plotOrientationX: 0.0,
- plotOrientationY: 0.0,
- plotOrientationZ: -1.0,
- refDistance: 1,
- maxDistance: MAX_DISTANCE,
- rolloffFactor: 10,
- coneInnerAngle: 40,
- coneOuterAngle: 50,
- coneOuterGain: 0.4,
- });
-
- // create panning
- const stereoPanner = this.audioContext.createStereoPanner();
- stereoPanner.pan.setValueCurveAtTime(panningArr, t, currentDuration);
- smoothOscillator.connect(this.smoothGain);
- this.smoothGain.connect(stereoPanner);
- stereoPanner.connect(panner);
- panner.connect(this.compressor);
-
- // play sound for duration
- constants.smoothId = setTimeout(() => {
- panner.disconnect();
- this.smoothGain.disconnect();
- smoothOscillator.stop();
- smoothOscillator.disconnect();
- constants.isSmoothAutoplay = false;
- }, currentDuration * 1e3 * 2);
- }
-
- PlayNull() {
- console.log('playing null');
- let frequency = constants.NULL_FREQUENCY;
- let duration = constants.duration;
- let panning = 0;
- let vol = constants.vol;
- let wave = 'triangle';
-
- this.playOscillator(frequency, duration, panning, vol, wave);
-
- setTimeout(
- function (audioThis) {
- audioThis.playOscillator(
- (frequency * 23) / 24,
- duration,
- panning,
- vol,
- wave
- );
- },
- Math.round((duration / 5) * 1000),
- this
- );
- }
-
- playEnd() {
- // play a pleasent end chime. We'll use terminal chime from VSCode
- if (constants.canPlayEndChime) {
- let chimeClone = constants.endChime.cloneNode(true); // we clone so that we can trigger a tone while one is already playing
- /*
- * the following (panning) only works if we're on a server
- let panning = 0;
- try {
- if ( constants.chartType == 'barplot' ) {
- panning = this.SlideBetween(position.x, 0, plot.bars.length-1, -1, 1);
- } else if ( constants.chartType == 'boxplot' ) {
- panning = this.SlideBetween(position.x, 0, plot.plotData[position.y].length-1, -1, 1);
- } else if ( constants.chartType == 'heatmap' ) {
- panning = this.SlideBetween(position.x, 0, plot.num_cols-1, -1, 1);
- } else if ( constants.chartType == 'scatterplot' ) {
- panning = this.SlideBetween(position.x, 0, plot.x.length-1, -1, 1);
- }
- } catch {
- }
-
- const track = this.audioContext.createMediaElementSource(chimeClone);
- const stereoNode = new StereoPannerNode(this.audioContext, {pan:panning} );
- track.connect(stereoNode).connect(this.audioContext.destination);
- */
- chimeClone.play();
- chimeClone = null;
- }
- }
-
- KillSmooth() {
- if (constants.smoothId) {
- this.smoothGain.gain.cancelScheduledValues(0);
- this.smoothGain.gain.exponentialRampToValueAtTime(
- 0.0001,
- this.audioContext.currentTime + 0.03
- );
-
- clearTimeout(constants.smoothId);
-
- constants.isSmoothAutoplay = false;
- }
- }
-
- SlideBetween(val, a, b, min, max) {
- // helper function that goes between min and max proportional to how val goes between a and b
- let newVal = ((val - a) / (b - a)) * (max - min) + min;
- if (a == 0 && b == 0) {
- newVal = 0;
- }
- return newVal;
- }
-}
-
-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() {
- if (constants.textMode == 'off') {
- constants.textMode = 'terse';
- } else if (constants.textMode == 'terse') {
- constants.textMode = 'verbose';
- } else if (constants.textMode == 'verbose') {
- constants.textMode = 'off';
- }
-
- this.announceText(
- 'Text mode: ' + constants.textMode
- );
- }
-
- toggleBrailleMode(onoff) {
- if (constants.chartType == 'scatterplot' && constants.layer == 1) {
- this.announceText('Braille is not supported in point layer.');
- return;
- }
- if (typeof onoff === 'undefined') {
- onoff = constants.brailleMode == 'on' ? 'off' : 'on';
- }
- if (onoff == 'on') {
- if (constants.chartType == 'boxplot') {
- // braille mode is on before any plot is selected
- if (
- constants.plotOrientation != 'vert' &&
- position.x == -1 &&
- position.y == plot.plotData.length
- ) {
- position.x += 1;
- position.y -= 1;
- } else if (
- constants.plotOrientation == 'vert' &&
- position.x == 0 &&
- position.y == plot.plotData[0].length - 1
- ) {
- // do nothing; don't think there's any problem
- }
- }
-
- constants.brailleMode = 'on';
- constants.brailleInput.classList.remove('hidden');
- constants.brailleInput.focus();
- constants.brailleInput.setSelectionRange(position.x, position.x);
-
- this.SetBraille(plot);
-
- if (constants.chartType == 'heatmap') {
- let pos = position.y * (plot.num_cols + 1) + position.x;
- constants.brailleInput.setSelectionRange(pos, pos);
- }
-
- // braille mode is on before navigation of svg
- // very important to make sure braille works properly
- if (position.x == -1 && position.y == -1) {
- constants.brailleInput.setSelectionRange(0, 0);
- }
- } else {
- constants.brailleMode = 'off';
- constants.brailleInput.classList.add('hidden');
-
- if (constants.review_container) {
- if (!constants.review_container.classList.contains('hidden')) {
- constants.review.focus();
- } else {
- constants.svg.focus();
- }
- } else {
- constants.svg.focus();
- }
- }
-
- this.announceText('Braille ' + constants.brailleMode);
- }
-
- toggleSonificationMode() {
- if (constants.chartType == 'scatterplot' && constants.layer == 1) {
- if (constants.sonifMode == 'off') {
- constants.sonifMode = 'sep';
- this.announceText(resources.GetString('son_sep'));
- } else if (constants.sonifMode == 'sep') {
- constants.sonifMode = 'same';
- this.announceText(resources.GetString('son_same'));
- } else if (constants.sonifMode == 'same') {
- constants.sonifMode = 'off';
- this.announceText(resources.GetString('son_off'));
- }
- } else {
- if (constants.sonifMode == 'off') {
- constants.sonifMode = 'on';
- this.announceText(resources.GetString('son_on'));
- } else {
- constants.sonifMode = 'off';
- this.announceText(resources.GetString('son_off'));
- }
- }
- }
-
- toggleLayerMode() {
- if (constants.layer == 1) {
- constants.layer = 2;
- this.announceText('Layer 2: Smoothed line');
- } else if (constants.layer == 2) {
- constants.layer = 1;
- this.announceText('Layer 1: Point');
- }
- }
-
- announceText(txt) {
- constants.announceContainer.innerHTML = txt;
- }
-
- UpdateBraillePos() {
- if (constants.chartType == 'barplot') {
- constants.brailleInput.setSelectionRange(position.x, position.x);
- } else if (constants.chartType == 'heatmap') {
- let pos = position.y * (plot.num_cols + 1) + position.x;
- constants.brailleInput.setSelectionRange(pos, pos);
- } else if (constants.chartType == 'boxplot') {
- // on boxplot we extend characters a lot and have blanks, so we go to our label
- let sectionPos =
- constants.plotOrientation == 'vert' ? position.y : position.x;
- let targetLabel = this.boxplotGridPlaceholders[sectionPos];
- let haveTargetLabel = false;
- let adjustedPos = 0;
- if (constants.brailleData) {
- for (let i = 0; i < constants.brailleData.length; i++) {
- if (constants.brailleData[i].type != 'blank') {
- if (
- resources.GetString(constants.brailleData[i].label) == targetLabel
- ) {
- haveTargetLabel = true;
- break;
- }
- }
- adjustedPos += constants.brailleData[i].numChars;
- }
- } else {
- throw 'Braille data not set up, cannot move cursor in braille, sorry.';
- }
- // but sometimes we don't have our targetLabel, go to the start
- // future todo: look for nearby label and go to the nearby side of that
- if (!haveTargetLabel) {
- adjustedPos = 0;
- }
-
- constants.brailleInput.setSelectionRange(adjustedPos, adjustedPos);
- } else if (constants.chartType == 'scatterplot') {
- constants.brailleInput.setSelectionRange(positionL1.x, positionL1.x);
- }
- }
-
- displayValues(plot) {
- // we build an html text string to output to both visual users and aria live based on what chart we're on, our position, and the mode
- // note: we do this all as one string rather than changing individual element IDs so that aria-live receives a single update
-
- let output = '';
- let verboseText = '';
- let reviewText = '';
- if (constants.chartType == 'barplot') {
- // {legend x} is {colname x}, {legend y} is {value y}
- verboseText =
- plot.plotLegend.x +
- ' is ' +
- plot.columnLabels[position.x] +
- ', ' +
- plot.plotLegend.y +
- ' is ' +
- plot.plotData[position.x];
- if (constants.textMode == 'off') {
- // do nothing :D
- } else if (constants.textMode == 'terse') {
- // {colname} {value}
- output +=
- '' +
- plot.columnLabels[position.x] +
- ' ' +
- plot.plotData[position.x] +
- '
\n';
- } else if (constants.textMode == 'verbose') {
- output += '' + verboseText + '
\n';
- }
- } else if (constants.chartType == 'heatmap') {
- // col name and value
- if (constants.navigation == 1) {
- verboseText +=
- plot.x_group_label +
- ' ' +
- plot.x_labels[position.x] +
- ', ' +
- plot.y_group_label +
- ' ' +
- plot.y_labels[position.y] +
- ', ' +
- plot.box_label +
- ' is ';
- if (constants.hasRect) {
- verboseText += plot.plotData[2][position.y][position.x];
- }
- } else {
- verboseText +=
- plot.y_group_label +
- ' ' +
- plot.y_labels[position.y] +
- ', ' +
- plot.x_group_label +
- ' ' +
- plot.x_labels[position.x] +
- ', ' +
- plot.box_label +
- ' is ';
- if (constants.hasRect) {
- verboseText += plot.plotData[2][position.y][position.x];
- }
- }
- // terse and verbose alternate between columns and rows
- if (constants.textMode == 'off') {
- // do nothing :D
- } else if (constants.textMode == 'terse') {
- // value only
- if (constants.navigation == 1) {
- // column navigation
- output +=
- '' +
- plot.x_labels[position.x] +
- ', ' +
- plot.plotData[2][position.y][position.x] +
- '
\n';
- } else {
- // row navigation
- output +=
- '' +
- plot.y_labels[position.y] +
- ', ' +
- plot.plotData[2][position.y][position.x] +
- '
\n';
- }
- } else if (constants.textMode == 'verbose') {
- output += '' + verboseText + '
\n';
- }
- } else if (constants.chartType == 'boxplot') {
- // setup
- let val = 0;
- let numPoints = 1;
- let isOutlier = false;
- let plotPos =
- constants.plotOrientation == 'vert' ? position.x : position.y;
- let sectionPos =
- constants.plotOrientation == 'vert' ? position.y : position.x;
- let textTerse = '';
- let textVerbose = '';
-
- if (
- plot.plotData[plotPos][sectionPos].label == 'lower_outlier' ||
- plot.plotData[plotPos][sectionPos].label == 'upper_outlier'
- ) {
- isOutlier = true;
- }
- if (plot.plotData[plotPos][sectionPos].type == 'outlier') {
- val = plot.plotData[plotPos][sectionPos].values.join(', ');
- if (plot.plotData[plotPos][sectionPos].values.length > 0) {
- numPoints = plot.plotData[plotPos][sectionPos].values.length;
- } else {
- numPoints = 0;
- }
- } else if (plot.plotData[plotPos][sectionPos].type == 'blank') {
- val = '';
- if (isOutlier) numPoints = 0;
- } else {
- if (constants.plotOrientation == 'vert') {
- val = plot.plotData[plotPos][sectionPos].y;
- } else {
- val = plot.plotData[plotPos][sectionPos].x;
- }
- }
-
- // set output
-
- // group label for verbose
- if (constants.navigation) {
- if (plot.x_group_label) textVerbose += plot.x_group_label;
- } else if (!constants.navigation) {
- if (plot.y_group_label) textVerbose += plot.y_group_label;
- }
- // and axis label
- if (constants.navigation) {
- if (plot.x_labels[plotPos]) {
- textVerbose += ' is ';
- textTerse += plot.x_labels[plotPos] + ', ';
- textVerbose += plot.x_labels[plotPos] + ', ';
- } else {
- textVerbose += ', ';
- }
- } else if (!constants.navigation) {
- if (plot.y_labels[plotPos]) {
- textVerbose += ' is ';
- textTerse += plot.y_labels[plotPos] + ', ';
- textVerbose += plot.y_labels[plotPos] + ', ';
- } else {
- textVerbose += ', ';
- }
- }
- // outliers
- if (isOutlier) {
- textTerse += numPoints + ' ';
- textVerbose += numPoints + ' ';
- }
- // label
- textVerbose += resources.GetString(
- plot.plotData[plotPos][sectionPos].label
- );
- if (numPoints == 1) textVerbose += ' is ';
- else {
- textVerbose += 's ';
- if (numPoints > 1) textVerbose += ' are ';
- }
- if (
- isOutlier ||
- (constants.navigation && constants.plotOrientation == 'horz') ||
- (!constants.navigation && constants.plotOrientation == 'vert')
- ) {
- textTerse += resources.GetString(
- plot.plotData[plotPos][sectionPos].label
- );
-
- // grammar
- if (numPoints != 1) {
- textTerse += 's';
- }
- textTerse += ' ';
- }
- // val
- if (plot.plotData[plotPos][sectionPos].type == 'blank' && !isOutlier) {
- textTerse += 'empty';
- textVerbose += 'empty';
- } else {
- textTerse += val;
- textVerbose += val;
- }
-
- verboseText = textVerbose; // yeah it's an extra var, who cares
- if (constants.textMode == 'verbose')
- output = '' + textVerbose + '
\n';
- else if (constants.textMode == 'terse')
- output = '' + textTerse + '
\n';
- } else if (constants.chartType == 'scatterplot') {
- if (constants.layer == 1) {
- // point layer
- verboseText +=
- plot.x_group_label +
- ' ' +
- plot.x[position.x] +
- ', ' +
- plot.y_group_label +
- ' [' +
- plot.y[position.x].join(', ') +
- ']';
-
- if (constants.textMode == 'off') {
- // do nothing
- } else if (constants.textMode == 'terse') {
- output +=
- '' +
- plot.x[position.x] +
- ', ' +
- '[' +
- plot.y[position.x].join(', ') +
- ']' +
- '
\n';
- } else if (constants.textMode == 'verbose') {
- // set from verboseText
- }
- } else if (constants.layer == 2) {
- // best fit line layer
- verboseText +=
- plot.x_group_label +
- ' ' +
- plot.curveX[positionL1.x] +
- ', ' +
- plot.y_group_label +
- ' ' +
- plot.curvePoints[positionL1.x]; // verbose mode: x and y values
-
- if (constants.textMode == 'off') {
- // do nothing
- } else if (constants.textMode == 'terse') {
- // terse mode: gradient trend
- // output += '' + plot.gradient[positionL1.x] + '
\n';
-
- // display absolute gradient of the graph
- output += '
' + plot.curvePoints[positionL1.x] + '
\n';
- } else if (constants.textMode == 'verbose') {
- // set from verboseText
- }
- }
- if (constants.textMode == 'verbose')
- output = '
' + verboseText + '
\n';
- }
-
- if (constants.infoDiv) constants.infoDiv.innerHTML = output;
- if (constants.review) {
- if (output.length > 0) {
- constants.review.value = output.replace(/<[^>]*>?/gm, '');
- } else {
- constants.review.value = verboseText;
- }
- }
- }
-
- displayXLabel(plot) {
- let xlabel = '';
- if (constants.chartType == 'barplot') {
- xlabel = plot.plotLegend.x;
- } else if (
- constants.chartType == 'heatmap' ||
- constants.chartType == 'boxplot' ||
- constants.chartType == 'scatterplot'
- ) {
- xlabel = plot.x_group_label;
- }
- if (constants.textMode == 'terse') {
- constants.infoDiv.innerHTML = '' + xlabel + '
';
- } else if (constants.textMode == 'verbose') {
- constants.infoDiv.innerHTML = '
x label is ' + xlabel + '
';
- }
- }
-
- displayYLabel(plot) {
- let ylabel = '';
- if (constants.chartType == 'barplot') {
- ylabel = plot.plotLegend.y;
- } else if (
- constants.chartType == 'heatmap' ||
- constants.chartType == 'boxplot' ||
- constants.chartType == 'scatterplot'
- ) {
- ylabel = plot.y_group_label;
- }
- if (constants.textMode == 'terse') {
- constants.infoDiv.innerHTML = '
' + ylabel + '
';
- } else if (constants.textMode == 'verbose') {
- constants.infoDiv.innerHTML = '
y label is ' + ylabel + '
';
- }
- }
-
- displayTitle(plot) {
- if (constants.textMode == 'terse') {
- if (plot.title != '') {
- constants.infoDiv.innerHTML = '
' + plot.title + '
';
- } else {
- constants.infoDiv.innerHTML = '
Plot does not have a title.
';
- }
- } else if (constants.textMode == 'verbose') {
- if (plot.title != '') {
- constants.infoDiv.innerHTML = '
Title is ' + plot.title + '
';
- } else {
- constants.infoDiv.innerHTML = '
Plot does not have a title.
';
- }
- }
- }
-
- displayFill(plot) {
- if (constants.textMode == 'terse') {
- if (constants.chartType == 'heatmap') {
- constants.infoDiv.innerHTML = '
' + plot.box_label + '
';
- }
- } else if (constants.textMode == 'verbose') {
- if (constants.chartType == 'heatmap') {
- constants.infoDiv.innerHTML =
- '
Fill label is ' + plot.box_label + '
';
- }
- }
- }
-
- SetBraille(plot) {
- let brailleArray = [];
-
- if (constants.chartType == 'heatmap') {
- let range = (constants.maxY - constants.minY) / 3;
- let low = constants.minY + range;
- let medium = low + range;
- let high = medium + range;
- for (let i = 0; i < plot.y_coord.length; i++) {
- for (let j = 0; j < plot.x_coord.length; j++) {
- if (plot.values[i][j] == 0) {
- brailleArray.push('â €');
- } else if (plot.values[i][j] <= low) {
- brailleArray.push('â ¤');
- } else if (plot.values[i][j] <= medium) {
- brailleArray.push('â ’');
- } else {
- brailleArray.push('â ‰');
- }
- }
- brailleArray.push('â ³');
- }
- } else if (constants.chartType == 'barplot') {
- let range = (constants.maxY - constants.minY) / 4;
- let low = constants.minY + range;
- let medium = low + range;
- let medium_high = medium + range;
- for (let i = 0; i < plot.plotData.length; i++) {
- if (plot.plotData[i] <= low) {
- brailleArray.push('⣀');
- } else if (plot.plotData[i] <= medium) {
- brailleArray.push('â ¤');
- } else if (plot.plotData[i] <= medium_high) {
- brailleArray.push('â ’');
- } else {
- brailleArray.push('â ‰');
- }
- }
- } else if (constants.chartType == 'scatterplot') {
- let range = (plot.curveMaxY - plot.curveMinY) / 4;
- let low = plot.curveMinY + range;
- let medium = low + range;
- let medium_high = medium + range;
- let high = medium_high + range;
- for (let i = 0; i < plot.curvePoints.length; i++) {
- if (plot.curvePoints[i] <= low) {
- brailleArray.push('⣀');
- } else if (plot.curvePoints[i] <= medium) {
- brailleArray.push('â ¤');
- } else if (plot.curvePoints[i] <= medium_high) {
- brailleArray.push('â ’');
- } else if (plot.curvePoints[i] <= high) {
- brailleArray.push('â ‰');
- }
- }
- } else if (constants.chartType == 'boxplot' && position.y > -1) {
- // only run if we're on a plot
- // Idea here is to use different braille characters to physically represent the boxplot
- // if sections are longer or shorter we'll add more characters
- // example: outlier, small space, long min, med 25/50/75, short max: ⠂ ⠒⠒⠒⠒⠒⠒⠿⠸⠿⠒
- //
- // So, we get weighted lengths of each section (or gaps between outliers, etc),
- // and then create the appropriate number of characters
- // Full explanation on readme
- //
- // This is messy and long (250 lines). If anyone wants to improve. Be my guest
-
- // First some prep work, we make an array of lengths and types that represent our plot
- let brailleData = [];
- let isBeforeMid = true;
- let plotPos =
- constants.plotOrientation == 'vert' ? position.x : position.y;
- let valCoord = constants.plotOrientation == 'vert' ? 'y' : 'x';
- for (let i = 0; i < plot.plotData[plotPos].length; i++) {
- let point = plot.plotData[plotPos][i];
- // pre clean up, we may want to remove outliers that share the same coordinates. Reasoning: We want this to visually represent the data, and I can't see 2 points on top of each other
- if (point.values && constants.visualBraille) {
- point.values = [...new Set(point.values)];
- }
-
- let nextPoint = null;
- let prevPoint = null;
- if (i < plot.plotData[plotPos].length - 1) {
- nextPoint = plot.plotData[plotPos][i + 1];
- }
- if (i > 0) {
- prevPoint = plot.plotData[plotPos][i - 1];
- }
-
- let charData = {};
-
- if (i == 0) {
- // first point, add space to next actual point
- let firstCoord = 0;
- for (let j = 0; j < plot.plotData[plotPos].length; j++) {
- // find next actual point
- if (valCoord in plot.plotData[plotPos][j]) {
- firstCoord = plot.plotData[plotPos][j][valCoord];
- break;
- }
- }
- charData = {};
- let minVal =
- constants.plotOrientation == 'vert'
- ? constants.minY
- : constants.minX;
- if (firstCoord - minVal > 0) {
- charData.length = firstCoord;
- } else {
- charData.length = 0;
- }
- if (charData.length < 0) charData.length = 0; // dunno why, but this happens sometimes
- charData.type = 'blank';
- charData.label = 'blank';
- brailleData.push(charData);
- }
-
- if (point.type == 'blank') {
- // this is a placeholder point, do nothing
- } else if (point.type == 'outlier') {
- // there might be lots of these or none
-
- // Spacing is messy:
- // isBeforeMid: no pre space, yes after space
- // ! isBeforeMid: yes pre space, no after space
- // either way add spaces in between outlier points
-
- // pre point space
- if (isBeforeMid) {
- // no pre space
- } else {
- // yes after space
- charData = {};
- charData.length = point.values[0] - prevPoint[valCoord];
- charData.type = 'blank';
- charData.label = 'blank';
- brailleData.push(charData);
- }
-
- // now add points with spaces in between
- for (var k = 0; k < point.values.length; k++) {
- if (k == 0) {
- charData = {};
- charData.length = 0;
- charData.type = 'outlier';
- charData.label = point.label;
- brailleData.push(charData);
- } else {
- charData = {};
- charData.length = point.values[k] - point.values[k - 1];
- charData.type = 'blank';
- charData.label = 'blank';
- brailleData.push(charData);
-
- charData = {};
- charData.length = 0;
- charData.type = 'outlier';
- charData.label = point.label;
- brailleData.push(charData);
- }
- }
-
- // after point space
- if (isBeforeMid) {
- // yes pre space
- charData = {};
- charData.length =
- nextPoint[valCoord] - point.values[point.values.length - 1];
- charData.type = 'blank';
- charData.label = 'blank';
- brailleData.push(charData);
- } else {
- // no after space
- }
- } else {
- if (point.label == '50') {
- // exception: another 0 width point here
- charData = {};
- charData.length = 0;
- charData.type = point.type;
- charData.label = point.label;
- brailleData.push(charData);
-
- isBeforeMid = false; // mark this as we pass
- } else {
- // normal points: we calc dist between this point and point closest to middle
- charData = {};
- if (isBeforeMid) {
- charData.length = nextPoint[valCoord] - point[valCoord];
- } else {
- charData.length = point[valCoord] - prevPoint[valCoord];
- }
- charData.type = point.type;
- charData.label = point.label;
- brailleData.push(charData);
- }
- }
- if (i == plot.plotData[plotPos].length - 1) {
- // last point gotta add ending space manually
- charData = {};
- let lastCoord = 0;
- for (let j = 0; j < plot.plotData[plotPos].length; j++) {
- // find last actual point
-
- if (point.type == 'outlier') {
- lastCoord = valCoord == 'y' ? point.yMax : point.xMax;
- } else if (valCoord in plot.plotData[plotPos][j]) {
- lastCoord = plot.plotData[plotPos][j][valCoord];
- }
- }
- charData.length =
- valCoord == 'y'
- ? constants.maxY - lastCoord
- : constants.maxX - lastCoord;
- charData.type = 'blank';
- charData.label = 'blank';
- brailleData.push(charData);
- }
- }
- // cleanup
- for (let i = 0; i < brailleData.length; i++) {
- // A bit of rounding to account for floating point errors
- brailleData[i].length = Math.round(brailleData[i].length); // we currently just use rounding to whole number (pixel), but if other rounding is needed add it here
- }
-
- // We create a set of braille characters based on the lengths
-
- // Method:
- // We normalize the lengths of each characters needed length
- // by the total number of characters we have availble
- // (including offset from characters requiring 1 character).
- // Then apply the appropriate number of characters to each
-
- // A few exceptions:
- // exception: each must have min 1 character (not blanks or length 0)
- // exception: for 25/75 and min/max, if they aren't exactly equal, assign different num characters
- // exception: center is always 456 123
-
- // Step 1, prepopulate each section with a single character, and log for character offset
- let locMin = -1;
- let locMax = -1;
- let loc25 = -1;
- let loc75 = -1;
- let numDefaultChars = 0;
- for (let i = 0; i < brailleData.length; i++) {
- if (
- brailleData[i].type != 'blank' &&
- (brailleData[i].length > 0 || brailleData[i].type == 'outlier')
- ) {
- brailleData[i].numChars = 1;
- numDefaultChars++;
- } else {
- brailleData[i].numChars = 0;
- }
-
- // store 25/75 min/max locations so we can check them later more easily
- if (brailleData[i].label == 'min' && brailleData[i].length > 0)
- locMin = i;
- if (brailleData[i].label == 'max' && brailleData[i].length > 0)
- locMax = i;
- if (brailleData[i].label == '25') loc25 = i;
- if (brailleData[i].label == '75') loc75 = i;
-
- // 50 gets 2 characters by default
- if (brailleData[i].label == '50') {
- brailleData[i].numChars = 2;
- numDefaultChars++;
- }
- }
- // add extras to 25/75 min/max if needed
- let currentPairs = ['25', '75'];
- if (locMin > -1 && locMax > -1) {
- currentPairs.push('min'); // we add these seperately because we don't always have both min and max
- currentPairs.push('max');
- if (brailleData[locMin].length != brailleData[locMax].length) {
- if (brailleData[locMin].length > brailleData[locMax].length) {
- // make sure if they're different, they appear different
- brailleData[locMin].numChars++;
- numDefaultChars++;
- } else {
- brailleData[locMax].numChars++;
- numDefaultChars++;
- }
- }
- }
- if (brailleData[loc25].length != brailleData[loc75].length) {
- if (brailleData[loc25].length > brailleData[loc75].length) {
- brailleData[loc25].numChars++;
- numDefaultChars++;
- } else {
- brailleData[loc75].numChars++;
- numDefaultChars++;
- }
- }
-
- // Step 2: normalize and allocate remaining characters and add to our main braille array
- let charsAvailable = constants.brailleDisplayLength - numDefaultChars;
- let allocateCharacters = this.AllocateCharacters(
- brailleData,
- charsAvailable
- );
- for (let i = 0; i < allocateCharacters.length; i++) {
- if (allocateCharacters[i]) {
- brailleData[i].numChars += allocateCharacters[i];
- }
- }
-
- constants.brailleData = brailleData;
- if (constants.debugLevel > 5) {
- console.log('plotData[i]', plot.plotData[plotPos]);
- console.log('brailleData', brailleData);
- }
-
- // convert to braille characters
- for (let i = 0; i < brailleData.length; i++) {
- for (let j = 0; j < brailleData[i].numChars; j++) {
- let brailleChar = 'â €'; // blank
- if (brailleData[i].label == 'min' || brailleData[i].label == 'max') {
- brailleChar = 'â ’';
- } else if (
- brailleData[i].label == '25' ||
- brailleData[i].label == '75'
- ) {
- brailleChar = 'â ¿';
- } else if (brailleData[i].label == '50') {
- if (j == 0) {
- brailleChar = 'â ¸';
- } else {
- brailleChar = 'â ‡';
- }
- } else if (brailleData[i].type == 'outlier') {
- brailleChar = 'â ‚';
- }
- brailleArray.push(brailleChar);
- }
- }
- }
-
- constants.brailleInput.value = brailleArray.join('');
-
- constants.brailleInput.value = brailleArray.join('');
- if (constants.debugLevel > 5) {
- console.log('braille:', constants.brailleInput.value);
- }
-
- this.UpdateBraillePos();
- }
-
- CharLenImpact(charData) {
- return charData.length / charData.numChars;
- }
-
- /**
- * This function allocates a total number of characters among an array of lengths,
- * proportionally to each length.
- *
- * @param {Array} arr - The array of lengths. Each length should be a positive number.
- * @param {number} totalCharacters - The total number of characters to be allocated.
- *
- * The function first calculates the sum of all lengths in the array. Then, it
- * iterates over the array and calculates an initial allocation for each length,
- * rounded to the nearest integer, based on its proportion of the total length.
- *
- * If the sum of these initial allocations is not equal to the total number of
- * characters due to rounding errors, the function makes adjustments to the allocations.
- *
- * The adjustments are made in a loop that continues until the difference between
- * the total number of characters and the sum of the allocations is zero, or until
- * the loop has run a maximum number of iterations equal to the length of the array.
- *
- * In each iteration of the loop, the function calculates a rounding adjustment for
- * each length, again based on its proportion of the total length, and adds this
- * adjustment to the length's allocation.
- *
- * If there's still a difference after the maximum number of iterations, the function
- * falls back to a simpler method of distributing the difference: it sorts the lengths
- * by their allocations and adds or subtracts 1 from each length in this order until
- * the difference is zero.
- *
- * The function returns an array of the final allocations.
- *
- * @returns {Array} The array of allocations.
- */
- AllocateCharacters(arr, totalCharacters) {
- // init
- let allocation = [];
- let sumLen = 0;
- for (let i = 0; i < arr.length; i++) {
- sumLen += arr[i].length;
- }
- let notAllowed = ['lower_outlier', 'upper_outlier', '50'];
-
- // main allocation
- for (let i = 0; i < arr.length; i++) {
- if (!notAllowed.includes(arr[i].label)) {
- allocation[i] = Math.round((arr[i].length / sumLen) * totalCharacters);
- }
- }
-
- // did it work? check for differences
- let allocatedSum = allocation.reduce((a, b) => a + b, 0);
- let difference = totalCharacters - allocatedSum;
-
- // If there's a rounding error, add/subtract characters proportionally
- let maxIterations = arr.length; // inf loop handler :D
- while (difference !== 0 && maxIterations > 0) {
- // (same method as above)
- for (let i = 0; i < arr.length; i++) {
- if (!notAllowed.includes(arr[i].label)) {
- allocation[i] += Math.round((arr[i].length / sumLen) * difference);
- }
- }
- allocatedSum = allocation.reduce((a, b) => a + b, 0);
- difference = totalCharacters - allocatedSum;
-
- maxIterations--;
- }
-
- // if there's still a rounding error after max iterations, fuck it, just distribute it evenly
- if (difference !== 0) {
- // create an array of indices sorted low to high based on current allocations
- let indices = [];
- for (let i = 0; i < arr.length; i++) {
- indices.push(i);
- }
- indices.sort((a, b) => allocation[a] - allocation[b]);
-
- // if we need to add or remove characters, do so from the beginning
- let plusminus = -1; // add or remove?
- if (difference > 0) {
- plusminus = 1;
- }
- let i = 0;
- let maxIterations = indices.length * 3; // run it for a while just in case
- while (difference > 0 && maxIterations > 0) {
- allocation[indices[i]] += plusminus;
- difference += -plusminus;
-
- i += 1;
- // loop back to start if we end
- if (i >= indices.length) {
- i = 0;
- }
-
- maxIterations += -1;
- }
- }
-
- return allocation;
- }
-}
-
-class BarChart {
- constructor() {
- // bars. The actual bar elements in the SVG. Used to highlight visually
- if ('elements' in maidr) {
- this.bars = maidr.elements;
- constants.hasRect = 1;
- } else {
- this.bars = document.querySelectorAll('g[id^="geom_rect"] > rect');
- constants.hasRect = 0;
- }
-
- // column labels, both legend and tick
- this.columnLabels = [];
- let legendX = '';
- let legendY = '';
- if ('axes' in maidr) {
- // legend labels
- if (maidr.axes.x) {
- if (maidr.axes.x.label) {
- legendX = maidr.axes.x.label;
- }
- }
- if (maidr.axes.y) {
- if (maidr.axes.y.label) {
- legendY = maidr.axes.y.label;
- }
- }
-
- // tick labels
- if (maidr.axes.x) {
- if (maidr.axes.x.format) {
- this.columnLabels = maidr.axes.x.format;
- }
- }
- if (maidr.axes.y) {
- if (maidr.axes.y.format) {
- this.columnLabels = maidr.axes.y.format;
- }
- }
- } else {
- // legend labels
- if (document.querySelector('g[id^="xlab"] tspan')) {
- legendX = document.querySelector('g[id^="xlab"] tspan').innerHTML;
- }
- if (document.querySelector('g[id^="ylab"] tspan')) {
- legendY = document.querySelector('g[id^="ylab"] tspan').innerHTML;
- }
-
- // tick labels
- this.columnLabels = this.ParseInnerHTML(
- document.querySelectorAll(
- 'g:not([id^="xlab"]):not([id^="ylab"]) > g > g > g > text[text-anchor="middle"]'
- )
- );
- }
-
- this.plotLegend = {
- x: legendX,
- y: legendY,
- };
-
- // title, either pulled from data or from the SVG
- this.title = '';
- if ('title' in maidr) {
- this.title = maidr.title;
- } else if (document.querySelector('g[id^="plot.title..titleGrob"] tspan')) {
- this.title = document.querySelector(
- 'g[id^="plot.title..titleGrob"] tspan'
- ).innerHTML;
- this.title = this.title.replace('\n', '').replace(/ +(?= )/g, ''); // there are multiple spaces and newlines, sometimes
- }
-
- if (typeof maidr == 'array') {
- this.plotData = maidr;
- } else if (typeof maidr == 'object') {
- if ('data' in maidr) {
- this.plotData = maidr.data;
- }
- } else {
- // TODO: throw error
- }
-
- // set the max and min values for the plot
- this.SetMaxMin();
-
- this.autoplay = null;
- }
-
- SetMaxMin() {
- for (let i = 0; i < this.plotData.length; i++) {
- if (i == 0) {
- constants.maxY = this.plotData[i];
- constants.minY = this.plotData[i];
- } else {
- if (this.plotData[i] > constants.maxY) {
- constants.maxY = this.plotData[i];
- }
- if (this.plotData[i] < constants.minY) {
- constants.minY = this.plotData[i];
- }
- }
- }
- constants.maxX = this.columnLabels.length;
- }
-
- GetLegendFromManualData() {
- let legend = {};
-
- legend.x = barplotLegend.x;
- legend.y = barplotLegend.y;
-
- return legend;
- }
-
- GetData() {
- // set height for each bar
-
- let plotData = [];
-
- if (this.bars) {
- for (let i = 0; i < this.bars.length; i++) {
- plotData.push(this.bars[i].getAttribute('height'));
- }
- }
-
- return plotData;
- }
-
- GetColumns() {
- // get column names
- // the pattern seems to be a with dy="10", but check this for future output (todo)
-
- let columnLabels = [];
- let els = document.querySelectorAll('tspan[dy="10"]'); // todo, generalize this selector
- for (var i = 0; i < els.length; i++) {
- columnLabels.push(els[i].innerHTML);
- }
-
- return columnLabels;
- }
-
- GetLegend() {
- let legend = {};
- let els = document.querySelectorAll('tspan[dy="12"]'); // todo, generalize this selector
- legend.x = els[1].innerHTML;
- legend.y = els[0].innerHTML;
-
- return legend;
- }
-
- ParseInnerHTML(els) {
- // parse innerHTML of elements
- let parsed = [];
- for (var i = 0; i < els.length; i++) {
- parsed.push(els[i].innerHTML);
- }
- return parsed;
- }
-
- Select() {
- this.DeselectAll();
- if (this.bars) {
- this.bars[position.x].style.fill = constants.colorSelected;
- }
- }
-
- DeselectAll() {
- if (this.bars) {
- for (let i = 0; i < this.bars.length; i++) {
- this.bars[i].style.fill = constants.colorUnselected;
- }
- }
- }
-}
-
-//
-// BoxPlot class.
-// This initializes and contains the JSON data model for this chart
-//
-class BoxPlot {
- constructor() {
- constants.plotId = 0;
-
- constants.plotOrientation = 'horz'; // default
- if (typeof maidr !== 'undefined') {
- constants.plotOrientation = maidr.orientation;
- }
-
- if (
- document.querySelector('g[id^="panel"] > g[id^="geom_boxplot.gTree"]')
- ) {
- constants.plotId = document
- .querySelector('g[id^="panel"] > g[id^="geom_boxplot.gTree"]')
- .getAttribute('id');
- }
-
- if (constants.manualData) {
- // title
- let boxplotTitle = '';
- if (typeof maidr !== 'undefined' && typeof maidr.title !== 'undefined') {
- boxplotTitle = maidr.title;
- } else if (document.querySelector('tspan[dy="9.45"]')) {
- boxplotTitle = document.querySelector('tspan[dy="9.45"]').innerHTML;
- boxplotTitle = boxplotTitle.replace('\n', '').replace(/ +(?= )/g, ''); // there are multiple spaces and newlines, sometimes
- }
- this.title =
- typeof boxplotTitle !== 'undefined' && typeof boxplotTitle != null
- ? boxplotTitle
- : '';
-
- // axis labels
- if (typeof maidr !== 'undefined') {
- this.x_group_label = maidr.x_group_label;
- } else {
- this.x_group_label = document.querySelector(
- 'text:not([transform^="rotate"]) > tspan[dy="7.88"]'
- ).innerHTML;
- }
- if (typeof maidr !== 'undefined') {
- this.y_group_label = maidr.y_group_label;
- } else {
- this.y_group_label = document.querySelector(
- 'text[transform^="rotate"] > tspan[dy="7.88"]'
- ).innerHTML;
- }
-
- // x y tick labels
- let labels = [];
- if (typeof maidr !== 'undefined') {
- this.x_labels = maidr.x_labels;
- this.y_labels = maidr.y_labels;
- } else {
- let elDy = '3.15';
- if (constants.plotOrientation == 'vert') {
- elDy = '6.3';
- }
- let els = document.querySelectorAll('tspan[dy="' + elDy + '"]');
- for (let i = 0; i < els.length; i++) {
- labels.push(els[i].innerHTML.trim());
- }
- if (constants.plotOrientation == 'vert') {
- this.x_labels = labels;
- this.y_labels = [];
- } else {
- this.x_labels = [];
- this.y_labels = labels;
- }
- }
-
- // main data
- if (typeof maidr !== 'undefined') {
- this.plotData = maidr.data;
- } else {
- this.plotData = maidr;
- }
- } else {
- this.x_group_label = document.getElementById(
- 'GRID.text.199.1.1.tspan.1'
- ).innerHTML;
- this.y_group_label = document.getElementById(
- 'GRID.text.202.1.1.tspan.1'
- ).innerHTML;
- if (constants.plotOrientation == 'vert') {
- this.x_labels = this.GetLabels();
- this.y_labels = [];
- } else {
- this.x_labels = [];
- this.y_labels = this.GetLabels();
- }
- this.plotData = this.GetData(); // main json data
- }
-
- if (constants.plotId) {
- this.plotBounds = this.GetPlotBounds(constants.plotId); // bound data
- constants.hasRect = true;
- } else {
- constants.hasRect = false;
- }
-
- this.CleanData();
- }
-
- GetLabels() {
- let labels = [];
- let query = 'tspan[dy="5"]';
- let els = document.querySelectorAll(query);
- for (let i = 0; i < els.length; i++) {
- labels.push(els[i].innerHTML.trim());
- }
- return labels;
- }
-
- CleanData() {
- // we manually input data, so now we need to clean it up and set other vars
-
- if (constants.plotOrientation == 'vert') {
- constants.minY = 0;
- constants.maxY = 0;
- for (let i = 0; i < this.plotData.length; i++) {
- // each plot
- for (let j = 0; j < this.plotData[i].length; j++) {
- // each section in plot
- let point = this.plotData[i][j];
- if (point.hasOwnProperty('y')) {
- if (point.y < constants.minY) {
- constants.yMin = point.y;
- }
- if (point.hasOwnProperty('yMax')) {
- if (point.yMax > constants.maxY) {
- constants.maxY = point.yMax;
- }
- } else {
- if (point.y > constants.maxY) {
- constants.maxY = point.y;
- }
- }
- }
- if (point.hasOwnProperty('x')) {
- if (point.x < constants.minX) {
- constants.minX = point.x;
- }
- if (point.x > constants.maxX) {
- constants.maxX = point.x;
- }
- }
- }
- }
- } else {
- constants.minX = 0;
- constants.maxX = 0;
- for (let i = 0; i < this.plotData.length; i++) {
- // each plot
- for (let j = 0; j < this.plotData[i].length; j++) {
- // each section in plot
- let point = this.plotData[i][j];
- if (point.hasOwnProperty('x')) {
- if (point.x < constants.minX) {
- constants.xMin = point.x;
- }
- if (point.hasOwnProperty('xMax')) {
- if (point.xMax > constants.maxX) {
- constants.maxX = point.xMax;
- }
- } else {
- if (point.x > constants.maxX) {
- constants.maxX = point.x;
- }
- }
- }
- if (point.hasOwnProperty('y')) {
- if (point.y < constants.minY) {
- constants.minY = point.y;
- }
- if (point.y > constants.maxY) {
- constants.maxY = point.y;
- }
- }
- }
- }
- }
- }
-
- GetData() {
- // data in svg is formed as nested elements. Loop through and get all point data
- // goal is to get bounding x values and type (outlier, whisker, range, placeholder)
-
- let plotData = [];
-
- let plots = document.getElementById(constants.plotId).children;
- for (let i = 0; i < plots.length; i++) {
- // each plot
-
- let sections = plots[i].children;
- let points = [];
- for (let j = 0; j < sections.length; j++) {
- // each segment (outlier, whisker, etc)
- // get segments for this section, there are 2 each
- // sometimes they're 0, so ignore those TODO
- let segments = sections[j].children;
- for (let k = 0; k < segments.length; k++) {
- let segment = segments[k];
-
- let segmentType = this.GetBoxplotSegmentType(
- sections[j].getAttribute('id')
- );
- let segmentPoints = this.GetBoxplotSegmentPoints(
- segment,
- segmentType
- );
-
- for (let l = 0; l < segmentPoints.length; l += 2) {
- if (
- segmentType == 'whisker' &&
- l == 0 &&
- constants.plotOrientation == 'vert'
- ) {
- } else {
- let thisPoint = {
- x: Number(segmentPoints[l]),
- y: Number(segmentPoints[l + 1]),
- type: segmentType,
- };
- if (thisPoint.y > constants.maxY) constants.maxY = thisPoint.y;
- points.push(thisPoint);
- }
- }
- }
- }
-
- // post processing
- // Sort this plot
- points.sort(function (a, b) {
- if (constants.plotOrientation == 'vert') {
- return a.y - b.y;
- } else {
- return a.x - b.x;
- }
- });
-
- if (constants.plotOrientation == 'horz') {
- // and remove whisker from range dups
- let noDupPoints = [];
- for (let d = 0; d < points.length; d++) {
- if (d > 0) {
- if (points[d - 1].x == points[d].x) {
- if (points[d - 1].type == 'whisker') {
- noDupPoints.splice(-1, 1);
- noDupPoints.push(points[d]);
- } else {
- }
- } else {
- noDupPoints.push(points[d]);
- }
- } else {
- noDupPoints.push(points[d]);
- }
- }
- points = noDupPoints;
- }
-
- plotData.push(points);
- }
-
- // put plots in order
- plotData.sort(function (a, b) {
- if (constants.plotOrientation == 'vert') {
- return a[0].x - b[0].x;
- } else {
- return a[0].y - b[0].y;
- }
- });
-
- // combine outliers into a single object for easier display
- // info to grab: arr of values=y's or x's, y or x = ymin or xmin, yn xn = ymax xmax. The rest can stay as is
- for (let i = 0; i < plotData.length; i++) {
- let section = plotData[i];
- // loop through points and find outliers
- let outlierGroup = [];
- for (let j = 0; j < section.length + 1; j++) {
- let runProcessOutliers = false; // run if we're past outliers (catching the first set), or if we're at the end (catching the last set)
- if (j == section.length) {
- runProcessOutliers = true;
- } else if (section[j].type != 'outlier') {
- runProcessOutliers = true;
- }
- if (!runProcessOutliers) {
- // add this to the group and continue
- outlierGroup.push(section[j]);
- } else if (outlierGroup.length > 0) {
- // process!! This is the main bit of work done
- let vals = [];
- for (let k = 0; k < outlierGroup.length; k++) {
- // save array of values
- if (constants.plotOrientation == 'vert') {
- vals.push(outlierGroup[k].y);
- } else {
- vals.push(outlierGroup[k].x);
- }
-
- // We're only keeping 1 outlier value, so mark all others to delete after we're done processing
- if (k > 0) {
- plotData[i][j + k - outlierGroup.length].type = 'delete';
- }
- }
-
- // save data
- if (constants.plotOrientation == 'vert') {
- plotData[i][j - outlierGroup.length].y = outlierGroup[0].y;
- plotData[i][j - outlierGroup.length].yMax =
- outlierGroup[outlierGroup.length - 1].y;
- } else {
- plotData[i][j - outlierGroup.length].x = outlierGroup[0].x;
- plotData[i][j - outlierGroup.length].xMax =
- outlierGroup[outlierGroup.length - 1].x;
- }
- plotData[i][j - outlierGroup.length].values = vals;
-
- // reset for next set
- outlierGroup = [];
- }
- }
- }
- // clean up from the above outlier processing
- let cleanData = [];
- for (let i = 0; i < plotData.length; i++) {
- cleanData[i] = [];
- for (let j = 0; j < plotData[i].length; j++) {
- if (plotData[i][j].type != 'delete') {
- cleanData[i][j] = plotData[i][j];
- }
- }
- cleanData[i] = cleanData[i].filter(function () {
- return true;
- });
- }
- plotData = cleanData;
-
- // add labeling for display
- for (let i = 0; i < plotData.length; i++) {
- // each boxplot section
- let rangeCounter = 0;
- for (let j = 0; j < plotData[i].length; j++) {
- let point = plotData[i][j];
- // each point, decide based on position with respect to range
- if (point.type == 'outlier') {
- if (rangeCounter > 0) {
- plotData[i][j].label = resources.GetString('upper_outlier');
- } else {
- plotData[i][j].label = resources.GetString('lower_outlier');
- }
- } else if (point.type == 'whisker') {
- if (rangeCounter > 0) {
- plotData[i][j].label = resources.GetString('max');
- } else {
- plotData[i][j].label = resources.GetString('min');
- }
- } else if (point.type == 'range') {
- if (rangeCounter == 0) {
- plotData[i][j].label = resources.GetString('25');
- } else if (rangeCounter == 1) {
- plotData[i][j].label = resources.GetString('50');
- } else if (rangeCounter == 2) {
- plotData[i][j].label = resources.GetString('75');
- }
- rangeCounter++;
- }
- }
- }
-
- // often a plot doesn't have various sections.
- // we expect outlier - min - 25 - 50 - 75 - max - outlier
- // add blank placeholders where they don't exist for better vertical navigation
- let allWeNeed = this.GetAllSegmentTypes();
- for (let i = 0; i < plotData.length; i++) {
- if (plotData[i].length == 7) {
- // skip, this one has it all. The rare boi
- } else {
- let whatWeGot = []; // we'll get a set of labels that we have so we can find what's missing
- for (let j = 0; j < plotData[i].length; j++) {
- whatWeGot.push(plotData[i][j].label);
- }
-
- // add missing stuff where it should go. We use .label as the user facing var (todo, might be a mistake, maybe use .type?)
- for (let j = 0; j < allWeNeed.length; j++) {
- if (!whatWeGot.includes(allWeNeed[j])) {
- // add a blank where it belongs
- let blank = { type: 'blank', label: allWeNeed[j] };
- plotData[i].splice(j, 0, blank);
- whatWeGot.splice(j, 0, allWeNeed[j]);
- }
- }
- }
- }
-
- // update 50% value as a midpoint of 25 and 75
- for (let i = 0; i < plotData.length; i++) {
- plotData[i][3].y = Math.round((plotData[i][2].y + plotData[i][4].y) / 2);
- }
-
- if (constants.debugLevel > 1) {
- console.log('plotData:', plotData);
- }
-
- return plotData;
- }
-
- GetPlotBounds(plotId) {
- // we fetch the elements in our parent, and similar to GetData we run through and get bounding boxes (or blanks) for everything, and store in an identical structure
-
- let plotBounds = [];
- let allWeNeed = this.GetAllSegmentTypes();
- let re = /(?:\d+(?:\.\d*)?|\.\d+)/g;
-
- // get initial set of elements, a parent element for all outliers, whiskers, and range
- let initialElemSet = [];
- let plots = document.getElementById(constants.plotId).children;
- for (let i = 0; i < plots.length; i++) {
- // each plot
- let plotSet = {};
- let sections = plots[i].children;
- for (let j = 0; j < sections.length; j++) {
- let elemType = this.GetBoxplotSegmentType(
- sections[j].getAttribute('id')
- );
- plotSet[elemType] = sections[j];
- }
- initialElemSet.push(plotSet);
- }
-
- // we build our structure based on the full set we need, and have blanks as placeholders
- // many of these overlap or are missing, so now we go through and make the actual array structure we need
- // like, all outliers are in 1 set, so we have to split those out and then get the bounding boxes
- for (let i = 0; i < initialElemSet.length; i++) {
- let plotBound = [];
-
- // we always have a range, and need those bounds to set others, so we'll do this first
- let rangeBounds = initialElemSet[i].range.getBoundingClientRect();
-
- // we get the midpoint from actual point values in the svg GRID.segments
- let midPoints = initialElemSet[i].range
- .querySelector('polyline[id^="GRID"]')
- .getAttribute('points')
- .match(re);
- let rangePoints = initialElemSet[i].range
- .querySelector('polygon[id^="geom_polygon"]')
- .getAttribute('points')
- .match(re);
- // get midpoint as percentage from bottom to mid to apply to bounding boxes
- // vert: top(rangePoints[1]) | mid(midPoints[1]) | bottom(rangePoints[3])
- // horz: top(rangePoints[0]) | mid(midPoints[0]) | bottom(rangePoints[2])
- let midPercent = 0;
- if (constants.plotOrientation == 'vert') {
- midPercent =
- (midPoints[1] - rangePoints[3]) / (rangePoints[1] - rangePoints[3]);
- } else {
- midPercent =
- (midPoints[0] - rangePoints[2]) / (rangePoints[0] - rangePoints[2]);
- }
- let midSize = 0;
- if (constants.plotOrientation == 'vert') {
- midSize = rangeBounds.height * midPercent;
- } else {
- midSize = rangeBounds.width * midPercent;
- }
-
- // set bounding box values
- // we critically need x / left, y / top, width, height. We can ignore the rest or let it be wrong
-
- // 25%
- plotBound[2] = this.convertBoundingClientRectToObj(rangeBounds);
- plotBound[2].label = allWeNeed[2];
- plotBound[2].type = 'range';
- if (constants.plotOrientation == 'vert') {
- plotBound[2].height = midSize;
- plotBound[2].top = plotBound[2].bottom - midSize;
- plotBound[2].y = plotBound[2].top;
- } else {
- plotBound[2].width = midSize;
- }
- // 50%
- plotBound[3] = this.convertBoundingClientRectToObj(rangeBounds);
- plotBound[3].label = allWeNeed[3];
- plotBound[3].type = 'range';
- if (constants.plotOrientation == 'vert') {
- plotBound[3].height = 0;
- plotBound[3].top = rangeBounds.bottom - midSize;
- plotBound[3].y = plotBound[3].top;
- plotBound[3].bottom = plotBound[3].top;
- } else {
- plotBound[3].width = 0;
- plotBound[3].left = rangeBounds.left + midSize;
- }
- // 75%
- plotBound[4] = this.convertBoundingClientRectToObj(rangeBounds);
- plotBound[4].label = allWeNeed[4];
- plotBound[4].type = 'range';
- if (constants.plotOrientation == 'vert') {
- plotBound[4].height = rangeBounds.height - midSize;
- plotBound[4].bottom = plotBound[3].top;
- } else {
- plotBound[4].width = rangeBounds.width - midSize;
- plotBound[4].left = plotBound[3].left;
- }
-
- // now the tricky ones, outliers and whiskers, if we have them
- if (Object.hasOwn(initialElemSet[i], 'whisker')) {
- // ok great we have a whisker. It could be just above or below or span across the range (in which case we need to split it up). Let's check
- let whiskerBounds = initialElemSet[i].whisker.getBoundingClientRect();
- let hasBelow = false;
- let hasAbove = false;
- if (constants.plotOrientation == 'vert') {
- if (whiskerBounds.bottom > rangeBounds.bottom) hasBelow = true;
- if (whiskerBounds.top < rangeBounds.top) hasAbove = true;
- } else {
- if (whiskerBounds.left < rangeBounds.left) hasBelow = true;
- if (whiskerBounds.right > rangeBounds.right) hasAbove = true;
- }
-
- // lower whisker
- if (hasBelow) {
- plotBound[1] = this.convertBoundingClientRectToObj(whiskerBounds);
- plotBound[1].label = allWeNeed[1];
- plotBound[1].type = 'whisker';
- if (constants.plotOrientation == 'vert') {
- plotBound[1].top = plotBound[2].bottom;
- plotBound[1].y = plotBound[1].top;
- plotBound[1].height = plotBound[1].bottom - plotBound[1].top;
- } else {
- plotBound[1].width = plotBound[2].left - plotBound[1].left;
- }
- } else {
- plotBound[1] = {};
- plotBound[1].label = allWeNeed[1];
- plotBound[1].type = 'blank';
- }
- // upper whisker
- if (hasAbove) {
- plotBound[5] = this.convertBoundingClientRectToObj(whiskerBounds);
- plotBound[5].label = allWeNeed[5];
- plotBound[5].type = 'whisker';
- if (constants.plotOrientation == 'vert') {
- plotBound[5].bottom = plotBound[4].top;
- plotBound[5].height = plotBound[5].bottom - plotBound[5].top;
- } else {
- plotBound[5].left = plotBound[4].right;
- plotBound[5].x = plotBound[4].right;
- plotBound[5].width = plotBound[5].right - plotBound[5].left;
- }
- } else {
- plotBound[5] = {};
- plotBound[5].label = allWeNeed[5];
- plotBound[5].type = 'blank';
- }
- }
- if (Object.hasOwn(initialElemSet[i], 'outlier')) {
- // we have one or more outliers.
- // Where do they appear? above or below the range? both?
- // we want to split them up and put 1 bounding box around each above and below
-
- let outlierElems = initialElemSet[i].outlier.children;
- let outlierUpperBounds = null;
- let outlierLowerBounds = null;
- for (let j = 0; j < outlierElems.length; j++) {
- // add this outlier's bounds, or expand if more than one
- let newOutlierBounds = outlierElems[j].getBoundingClientRect();
-
- if (constants.plotOrientation == 'vert') {
- if (newOutlierBounds.y < rangeBounds.y) {
- // higher, remember y=0 is at the bottom of the page
- if (!outlierUpperBounds) {
- outlierUpperBounds =
- this.convertBoundingClientRectToObj(newOutlierBounds);
- } else {
- if (newOutlierBounds.y < outlierUpperBounds.y)
- outlierUpperBounds.y = newOutlierBounds.y;
- if (newOutlierBounds.top < outlierUpperBounds.top)
- outlierUpperBounds.top = newOutlierBounds.top;
- if (newOutlierBounds.bottom > outlierUpperBounds.bottom)
- outlierUpperBounds.bottom = newOutlierBounds.bottom;
- }
- } else {
- if (!outlierLowerBounds) {
- outlierLowerBounds =
- this.convertBoundingClientRectToObj(newOutlierBounds);
- } else {
- if (newOutlierBounds.y < outlierLowerBounds.y)
- outlierLowerBounds.y = newOutlierBounds.y;
- if (newOutlierBounds.top < outlierLowerBounds.top)
- outlierLowerBounds.top = newOutlierBounds.top;
- if (newOutlierBounds.bottom > outlierLowerBounds.bottom)
- outlierLowerBounds.bottom = newOutlierBounds.bottom;
- }
- }
- } else {
- if (newOutlierBounds.x > rangeBounds.x) {
- // higher, remember x=0 is at the left of the page
- if (!outlierUpperBounds) {
- outlierUpperBounds =
- this.convertBoundingClientRectToObj(newOutlierBounds);
- } else {
- if (newOutlierBounds.x < outlierUpperBounds.x)
- outlierUpperBounds.x = newOutlierBounds.x;
- if (newOutlierBounds.left < outlierUpperBounds.left)
- outlierUpperBounds.left = newOutlierBounds.left;
- if (newOutlierBounds.right > outlierUpperBounds.right)
- outlierUpperBounds.right = newOutlierBounds.right;
- }
- } else {
- if (!outlierLowerBounds) {
- outlierLowerBounds =
- this.convertBoundingClientRectToObj(newOutlierBounds);
- } else {
- if (newOutlierBounds.x < outlierLowerBounds.x)
- outlierLowerBounds.x = newOutlierBounds.x;
- if (newOutlierBounds.left < outlierLowerBounds.left)
- outlierLowerBounds.left = newOutlierBounds.left;
- if (newOutlierBounds.right > outlierLowerBounds.right)
- outlierLowerBounds.right = newOutlierBounds.right;
- }
- }
- }
- }
-
- // now we add plotBound outlier stuff
- if (outlierLowerBounds) {
- outlierLowerBounds.height =
- outlierLowerBounds.bottom - outlierLowerBounds.top;
- outlierLowerBounds.width =
- outlierLowerBounds.right - outlierLowerBounds.left;
-
- plotBound[0] =
- this.convertBoundingClientRectToObj(outlierLowerBounds);
- plotBound[0].label = allWeNeed[0];
- plotBound[0].type = 'outlier';
- } else {
- plotBound[0] = {};
- plotBound[0].label = allWeNeed[0];
- plotBound[0].type = 'blank';
- }
- if (outlierUpperBounds) {
- outlierUpperBounds.height =
- outlierUpperBounds.bottom - outlierUpperBounds.top;
- outlierUpperBounds.width =
- outlierUpperBounds.right - outlierUpperBounds.left;
-
- plotBound[6] =
- this.convertBoundingClientRectToObj(outlierUpperBounds);
- plotBound[6].label = allWeNeed[6];
- plotBound[6].type = 'outlier';
- } else {
- plotBound[6] = {};
- plotBound[6].label = allWeNeed[6];
- plotBound[6].type = 'blank';
- }
- } else {
- // add all blanks
- plotBound[0] = {};
- plotBound[0].label = allWeNeed[0];
- plotBound[0].type = 'blank';
- plotBound[6] = {};
- plotBound[6].label = allWeNeed[6];
- plotBound[6].type = 'blank';
- }
-
- plotBounds.push(plotBound);
- }
-
- if (constants.debugLevel > 5) {
- console.log('plotBounds', plotBounds);
- }
-
- return plotBounds;
- }
-
- GetAllSegmentTypes() {
- let allWeNeed = [
- resources.GetString('lower_outlier'),
- resources.GetString('min'),
- resources.GetString('25'),
- resources.GetString('50'),
- resources.GetString('75'),
- resources.GetString('max'),
- resources.GetString('upper_outlier'),
- ];
-
- return allWeNeed;
- }
-
- GetBoxplotSegmentType(sectionId) {
- // Helper function for main GetData:
- // Fetch type, which comes from section id:
- // geom_polygon = range
- // GRID = whisker
- // points = outlier
-
- let segmentType = 'outlier'; // default? todo: should probably default null, and then throw error instead of return if not set after ifs
- if (sectionId.includes('geom_crossbar')) {
- segmentType = 'range';
- } else if (sectionId.includes('GRID')) {
- segmentType = 'whisker';
- } else if (sectionId.includes('points')) {
- segmentType = 'outlier';
- }
-
- return segmentType;
- }
- GetBoxplotSegmentPoints(segment, segmentType) {
- // Helper function for main GetData:
- // Fetch x and y point data from svg
-
- let re = /(?:\d+(?:\.\d*)?|\.\d+)/g;
- let pointString = '';
- let points = [];
- if (segmentType == 'range') {
- // ranges go a level deeper
- let matches = segment.children[0].getAttribute('points').match(re);
- points.push(matches[0], matches[1]);
- // the middle bar has 2 points but we just need one, check if they're the same
- if (matches[0] != matches[2]) {
- points.push(matches[2], matches[3]);
- }
- } else if (segmentType == 'outlier') {
- // outliers use x attr directly, but have multiple children
- points.push(segment.getAttribute('x'), segment.getAttribute('y'));
- } else {
- // whisker. Get first and third number from points attr
- // but sometimes it's null, giving the same for both, and don't add if that's true
- let matches = segment.getAttribute('points').match(re);
- if (constants.plotOrientation == 'vert') {
- if (matches[1] != matches[3]) {
- points.push(matches[0], matches[1], matches[2], matches[3]);
- }
- } else {
- if (matches[0] != matches[2]) {
- points.push(matches[0], matches[1], matches[2], matches[3]);
- }
- }
- }
-
- return points;
- }
-
- convertBoundingClientRectToObj(rect) {
- return {
- top: rect.top,
- right: rect.right,
- bottom: rect.bottom,
- left: rect.left,
- width: rect.width,
- height: rect.height,
- x: rect.x,
- y: rect.y,
- };
- }
-
- PlayTones(audio) {
- let plotPos = null;
- let sectionPos = null;
- if (constants.outlierInterval) clearInterval(constants.outlierInterval);
- if (constants.plotOrientation == 'vert') {
- plotPos = position.x;
- sectionPos = position.y;
- } else {
- plotPos = position.y;
- sectionPos = position.x;
- }
- if (plot.plotData[plotPos][sectionPos].type == 'blank') {
- audio.PlayNull();
- } else if (plot.plotData[plotPos][sectionPos].type != 'outlier') {
- audio.playTone();
- } else {
- // outlier(s): we play a run of tones
- position.z = 0;
- constants.outlierInterval = setInterval(function () {
- // play this tone
- audio.playTone();
-
- // and then set up for the next one
- position.z += 1;
-
- // and kill if we're done
- if (!Object.hasOwn(plot.plotData[plotPos][sectionPos], 'values')) {
- clearInterval(constants.outlierInterval);
- position.z = -1;
- } else if (
- position.z + 1 >
- plot.plotData[plotPos][sectionPos].values.length
- ) {
- clearInterval(constants.outlierInterval);
- position.z = -1;
- }
- }, constants.autoPlayOutlierRate);
- }
- }
-}
-
-// BoxplotRect class
-// Initializes and updates the visual outline around sections of the chart
-class BoxplotRect {
- // maybe put this stuff in user config?
- rectPadding = 15; // px
- rectStrokeWidth = 4; // px
-
- constructor() {
- this.x1 = 0;
- this.width = 0;
- this.y1 = 0;
- this.height = 0;
- this.svgOffsetLeft = constants.svg.getBoundingClientRect().left;
- this.svgOffsetTop = constants.svg.getBoundingClientRect().top;
- }
-
- UpdateRect() {
- // UpdateRect takes bounding box values from the object and gets bounds of visual outline to be drawn
-
- if (document.getElementById('highlight_rect'))
- document.getElementById('highlight_rect').remove(); // destroy to be recreated
-
- let plotPos = position.x;
- let sectionPos = position.y;
- if (constants.plotOrientation == 'vert') {
- } else {
- plotPos = position.y;
- sectionPos = position.x;
- }
-
- if (
- (constants.plotOrientation == 'vert' && position.y > -1) ||
- (constants.plotOrientation == 'horz' && position.x > -1)
- ) {
- // initial value could be -1, which throws errors, so ignore that
-
- let bounds = plot.plotBounds[plotPos][sectionPos];
-
- if (bounds.type != 'blank') {
- //let svgBounds = constants.svg.getBoundingClientRect();
-
- this.x1 = bounds.left - this.rectPadding - this.svgOffsetLeft;
- this.width = bounds.width + this.rectPadding * 2;
- this.y1 = bounds.top - this.rectPadding - this.svgOffsetTop;
- this.height = bounds.height + this.rectPadding * 2;
-
- if (constants.debugLevel > 5) {
- console.log(
- 'Point',
- plot.plotData[plotPos][sectionPos].label,
- 'bottom:',
- bounds.bottom,
- 'top:',
- bounds.top
- );
- console.log(
- 'x1:',
- this.x1,
- 'y1:',
- this.y1,
- 'width:',
- this.width,
- 'height:',
- this.height
- );
- }
-
- this.CreateRectDisplay();
- }
- }
- }
-
- CreateRectDisplay() {
- // CreateRectDisplay takes bounding points and creates the visual outline
-
- const svgns = 'http://www.w3.org/2000/svg';
- let rect = document.createElementNS(svgns, 'rect');
- rect.setAttribute('id', 'highlight_rect');
- rect.setAttribute('x', this.x1);
- rect.setAttribute('y', this.y1); // y coord is inverse from plot data
- rect.setAttribute('width', this.width);
- rect.setAttribute('height', this.height);
- rect.setAttribute('stroke', constants.colorSelected);
- rect.setAttribute('stroke-width', this.rectStrokeWidth);
- rect.setAttribute('fill', 'none');
- constants.svg.appendChild(rect);
- }
-}
-
-class HeatMap {
- constructor() {
- if ('elements' in maidr) {
- this.plots = maidr.elements;
- constants.hasRect = 1;
- } else {
- this.plots = document.querySelectorAll('g[id^="geom_rect"] > rect');
- constants.hasRect = 0;
- }
-
- this.group_labels = this.getGroupLabels();
- this.x_labels = this.getXLabels();
- this.y_labels = this.getYLabels();
- this.title = this.getTitle();
-
- this.plotData = this.getHeatMapData();
- this.updateConstants();
-
- this.x_coord = this.plotData[0];
- this.y_coord = this.plotData[1];
- this.values = this.plotData[2];
- this.num_rows = this.plotData[3];
- this.num_cols = this.plotData[4];
-
- this.x_group_label = this.group_labels[0].trim();
- this.y_group_label = this.group_labels[1].trim();
- this.box_label = this.group_labels[2].trim();
- }
-
- getHeatMapData() {
- // get the x_coord and y_coord to check if a square exists at the coordinates
- let x_coord_check = [];
- let y_coord_check = [];
-
- let unique_x_coord = [];
- let unique_y_coord = [];
- if (constants.hasRect) {
- for (let i = 0; i < this.plots.length; i++) {
- if (this.plots[i]) {
- x_coord_check.push(parseFloat(this.plots[i].getAttribute('x')));
- y_coord_check.push(parseFloat(this.plots[i].getAttribute('y')));
- }
- }
-
- // sort the squares to access from left to right, up to down
- x_coord_check.sort(function (a, b) {
- return a - b;
- }); // ascending
- y_coord_check
- .sort(function (a, b) {
- return a - b;
- })
- .reverse(); // descending
-
- // get unique elements from x_coord and y_coord
- unique_x_coord = [...new Set(x_coord_check)];
- unique_y_coord = [...new Set(y_coord_check)];
- }
-
- // get num of rows, num of cols, and total numbers of squares
- let num_rows = 0;
- let num_cols = 0;
- let num_squares = 0;
- if ('data' in maidr) {
- num_rows = maidr.data.length;
- num_cols = maidr.data[0].length;
- } else {
- num_rows = unique_y_coord.length;
- num_cols = unique_x_coord.length;
- }
- num_squares = num_rows * num_cols;
-
- let norms = [];
- if ('data' in maidr) {
- norms = [...maidr.data];
- } else {
- norms = Array(num_rows)
- .fill()
- .map(() => Array(num_cols).fill(0));
- let min_norm = 3 * Math.pow(255, 2);
- let max_norm = 0;
-
- for (var i = 0; i < this.plots.length; i++) {
- var x_index = unique_x_coord.indexOf(x_coord_check[i]);
- var y_index = unique_y_coord.indexOf(y_coord_check[i]);
- let norm = this.getRGBNorm(i);
- norms[y_index][x_index] = norm;
-
- if (norm < min_norm) min_norm = norm;
- if (norm > max_norm) max_norm = norm;
- }
- }
-
- let plotData = [unique_x_coord, unique_y_coord, norms, num_rows, num_cols];
-
- return plotData;
- }
-
- updateConstants() {
- constants.minX = 0;
- constants.maxX = this.plotData[4];
- constants.minY = this.plotData[2][0][0]; // initial val
- constants.maxY = this.plotData[2][0][0]; // initial val
- for (let i = 0; i < this.plotData[2].length; i++) {
- for (let j = 0; j < this.plotData[2][i].length; j++) {
- if (this.plotData[2][i][j] < constants.minY)
- constants.minY = this.plotData[2][i][j];
- if (this.plotData[2][i][j] > constants.maxY)
- constants.maxY = this.plotData[2][i][j];
- }
- }
- }
-
- getRGBNorm(i) {
- let rgb_string = this.plots[i].getAttribute('fill');
- let rgb_array = rgb_string.slice(4, -1).split(',');
- // just get the sum of squared value of rgb, similar without sqrt, save computation
- return rgb_array
- .map(function (x) {
- return Math.pow(x, 2);
- })
- .reduce(function (a, b) {
- return a + b;
- });
- }
-
- getGroupLabels() {
- let labels_nodelist;
- let title = '';
- let legendX = '';
- let legendY = '';
-
- if ('title' in maidr) {
- title = maidr.title;
- } else {
- title = document.querySelector(
- 'g[id^="guide.title"] text > tspan'
- ).innerHTML;
- }
-
- if ('axes' in maidr) {
- if ('x' in maidr.axes) {
- if ('label' in maidr.axes.x) {
- legendX = maidr.axes.x.label;
- }
- }
- if ('y' in maidr.axes) {
- if ('label' in maidr.axes.y) {
- legendY = maidr.axes.y.label;
- }
- }
- } else {
- legendX = document.querySelector('g[id^="xlab"] text > tspan').innerHTML;
- legendY = document.querySelector('g[id^="ylab"] text > tspan').innerHTML;
- }
-
- labels_nodelist = [legendX, legendY, title];
-
- return labels_nodelist;
- }
-
- getXLabels() {
- if ('axes' in maidr) {
- if ('x' in maidr.axes) {
- if ('format' in maidr.axes.x) {
- return maidr.axes.x.format;
- }
- }
- } else {
- let x_labels_nodelist;
- x_labels_nodelist = document.querySelectorAll('tspan[dy="10"]');
- let labels = [];
- for (let i = 0; i < x_labels_nodelist.length; i++) {
- labels.push(x_labels_nodelist[i].innerHTML.trim());
- }
-
- return labels;
- }
- }
-
- getYLabels() {
- if ('axes' in maidr) {
- if ('y' in maidr.axes) {
- if ('format' in maidr.axes.y) {
- return maidr.axes.y.format;
- }
- }
- } else {
- let y_labels_nodelist;
- let labels = [];
- y_labels_nodelist = document.querySelectorAll(
- 'tspan[id^="GRID.text.19.1"]'
- );
- for (let i = 0; i < y_labels_nodelist.length; i++) {
- labels.push(y_labels_nodelist[i].innerHTML.trim());
- }
-
- return labels.reverse();
- }
- }
-
- getTitle() {
- if ('title' in maidr) {
- return maidr.title;
- } else {
- let heatmapTitle = document.querySelector(
- 'g[id^="layout::title"] text > tspan'
- ).innerHTML;
- if (
- constants.manualData &&
- typeof heatmapTitle !== 'undefined' &&
- typeof heatmapTitle != null
- ) {
- return heatmapTitle;
- } else {
- return '';
- }
- }
- }
-}
-
-class HeatMapRect {
- constructor() {
- if (constants.hasRect) {
- this.x = plot.x_coord[0];
- this.y = plot.y_coord[0];
- this.rectStrokeWidth = 4; // px
- this.height = Math.abs(plot.y_coord[1] - plot.y_coord[0]);
- }
- }
-
- UpdateRect() {
- this.x = plot.x_coord[position.x];
- this.y = plot.y_coord[position.y];
- }
-
- UpdateRectDisplay() {
- this.UpdateRect();
- if (document.getElementById('highlight_rect'))
- document.getElementById('highlight_rect').remove(); // destroy and recreate
- const svgns = 'http://www.w3.org/2000/svg';
- var rect = document.createElementNS(svgns, 'rect');
- rect.setAttribute('id', 'highlight_rect');
- rect.setAttribute('x', this.x);
- rect.setAttribute(
- 'y',
- constants.svg.getBoundingClientRect().height - this.height - this.y
- ); // y coord is inverse from plot data
- rect.setAttribute('width', this.height);
- rect.setAttribute('height', this.height);
- rect.setAttribute('stroke', constants.colorSelected);
- rect.setAttribute('stroke-width', this.rectStrokeWidth);
- rect.setAttribute('fill', 'none');
- constants.svg.appendChild(rect);
- }
-}
-
-document.addEventListener('DOMContentLoaded', function (e) {
- // we wrap in DOMContentLoaded to make sure everything has loaded before we run anything
-});
-
-class ScatterPlot {
- constructor() {
- // layer = 1
- if ('point_elements' in maidr) {
- this.plotPoints = maidr.point_elements;
- } else {
- this.plotPoints = document.querySelectorAll(
- '#' + constants.plotId.replaceAll('.', '\\.') + ' > use'
- );
- }
- this.svgPointsX = this.GetSvgPointCoords()[0]; // x coordinates of points
- this.svgPointsY = this.GetSvgPointCoords()[1]; // y coordinates of points
-
- this.x = this.GetPointValues()[0]; // actual values of x
- this.y = this.GetPointValues()[1]; // actual values of y
-
- // for sound weight use
- this.points_count = this.GetPointValues()[2]; // number of each points
- this.max_count = this.GetPointValues()[3];
-
- // layer = 2
- if (constants.manualData) {
- this.plotLine = maidr.smooth_elements;
- } else {
- this.plotLine = document.querySelectorAll(
- '#' + 'GRID.polyline.13.1'.replaceAll('.', '\\.') + ' > polyline'
- )[0];
- }
- this.svgLineX = this.GetSvgLineCoords()[0]; // x coordinates of curve
- this.svgLineY = this.GetSvgLineCoords()[1]; // y coordinates of curve
-
- this.curveX = this.GetSmoothCurvePoints()[0]; // actual values of x
- this.curvePoints = this.GetSmoothCurvePoints()[1]; // actual values of y
-
- this.curveMinY = Math.min(...this.curvePoints);
- this.curveMaxY = Math.max(...this.curvePoints);
- this.gradient = this.GetGradient();
-
- this.x_group_label = '';
- this.y_group_label = '';
- this.title = '';
- if (typeof maidr !== 'undefined') {
- if ('axes' in maidr) {
- if ('x' in maidr.axes) {
- this.x_group_label = maidr.axes.x.label;
- }
- if ('y' in maidr.axes) {
- this.y_group_label = maidr.axes.y.label;
- }
- }
- if ('title' in maidr) {
- this.title = maidr.title;
- }
- }
- }
-
- GetSvgPointCoords() {
- let points = new Map();
-
- for (let i = 0; i < this.plotPoints.length; i++) {
- let x = parseFloat(this.plotPoints[i].getAttribute('x')); // .toFixed(1);
- let y = parseFloat(this.plotPoints[i].getAttribute('y'));
- if (!points.has(x)) {
- points.set(x, new Set([y]));
- } else {
- points.get(x).add(y);
- }
- }
-
- points = new Map(
- [...points].sort(function (a, b) {
- return a[0] - b[0];
- })
- );
-
- points.forEach(function (value, key) {
- points[key] = Array.from(value).sort(function (a, b) {
- return a - b;
- });
- });
-
- let X = [...points.keys()];
-
- let Y = [];
- for (let i = 0; i < X.length; i++) {
- Y.push(points[X[i]]);
- }
-
- return [X, Y];
- }
-
- GetPointValues() {
- let points = new Map(); // keep track of x and y values
-
- let xValues = [];
- let yValues = [];
-
- for (let i = 0; i < maidr.data.data_point_layer.length; i++) {
- let x = maidr.data.data_point_layer[i]['x'];
- let y = maidr.data.data_point_layer[i]['y'];
- xValues.push(x);
- yValues.push(y);
- if (!points.has(x)) {
- points.set(x, new Map([[y, 1]]));
- } else {
- if (points.get(x).has(y)) {
- let mapy = points.get(x);
- mapy.set(y, mapy.get(y) + 1);
- } else {
- points.get(x).set(y, 1);
- }
- }
- }
-
- constants.minX = 0;
- constants.maxX = [...new Set(xValues)].length;
-
- constants.minY = Math.min(...yValues);
- constants.maxY = Math.max(...yValues);
-
- points = new Map(
- [...points].sort(function (a, b) {
- return a[0] - b[0];
- })
- );
-
- points.forEach(function (value, key) {
- points[key] = Array.from(value).sort(function (a, b) {
- return a[0] - b[0];
- });
- });
-
- let X = [];
- let Y = [];
- let points_count = [];
- for (const [x_val, y_val] of points) {
- X.push(x_val);
- let y_arr = [];
- let y_count = [];
- for (const [y, count] of y_val) {
- y_arr.push(y);
- y_count.push(count);
- }
- Y.push(y_arr.sort());
- points_count.push(y_count);
- }
- let max_points = Math.max(...points_count.map((a) => Math.max(...a)));
-
- return [X, Y, points_count, max_points];
- }
-
- PlayTones(audio) {
- // kill the previous separate-points play before starting the next play
- if (constants.sepPlayId) {
- constants.KillSepPlay();
- }
- if (constants.layer == 1) {
- // point layer
- // we play a run of tones
- position.z = 0;
- constants.sepPlayId = setInterval(
- function () {
- // play this tone
- audio.playTone();
-
- // and then set up for the next one
- position.z += 1;
-
- // and kill if we're done
- if (position.z + 1 > plot.y[position.x].length) {
- constants.KillSepPlay();
- position.z = -1;
- }
- },
- constants.sonifMode == 'sep' ? constants.autoPlayPointsRate : 0
- ); // play all tones at the same time
- } else if (constants.layer == 2) {
- // best fit line layer
- audio.playTone();
- }
- }
-
- GetSvgLineCoords() {
- // extract all the y coordinates from the point attribute of polyline
- let str = this.plotLine.getAttribute('points');
- let coords = str.split(' ');
-
- let X = [];
- let Y = [];
-
- for (let i = 0; i < coords.length; i++) {
- let coord = coords[i].split(',');
- X.push(parseFloat(coord[0]));
- Y.push(parseFloat(coord[1]));
- }
-
- return [X, Y];
- }
-
- GetSmoothCurvePoints() {
- let x_points = [];
- let y_points = [];
-
- for (let i = 0; i < maidr.data.data_smooth_layer.length; i++) {
- x_points.push(maidr.data.data_smooth_layer[i]['x']);
- y_points.push(maidr.data.data_smooth_layer[i]['y']);
- }
-
- return [x_points, y_points];
- }
-
- GetGradient() {
- let gradients = [];
-
- for (let i = 0; i < this.curvePoints.length - 1; i++) {
- let abs_grad = Math.abs(
- (this.curvePoints[i + 1] - this.curvePoints[i]) /
- (this.curveX[i + 1] - this.curveX[i])
- ).toFixed(3);
- gradients.push(abs_grad);
- }
-
- gradients.push('end');
-
- return gradients;
- }
-}
-
-class Layer0Point {
- constructor() {
- this.x = plot.svgPointsX[0];
- this.y = plot.svgPointsY[0];
- this.strokeWidth = 1.35;
- }
-
- async UpdatePoints() {
- await this.ClearPoints();
- this.x = plot.svgPointsX[position.x];
- this.y = plot.svgPointsY[position.x];
- }
-
- async PrintPoints() {
- await this.ClearPoints();
- await this.UpdatePoints();
- for (let i = 0; i < this.y.length; i++) {
- const svgns = 'http://www.w3.org/2000/svg';
- var point = document.createElementNS(svgns, 'circle');
- point.setAttribute('class', 'highlight_point');
- point.setAttribute('cx', this.x);
- point.setAttribute(
- 'cy',
- constants.svg.getBoundingClientRect().height - this.y[i]
- );
- point.setAttribute('r', 3.95);
- point.setAttribute('stroke', constants.colorSelected);
- point.setAttribute('stroke-width', this.strokeWidth);
- point.setAttribute('fill', constants.colorSelected);
- constants.svg.appendChild(point);
- }
- }
-
- async ClearPoints() {
- if (document.getElementById('highlight_point'))
- document.getElementById('highlight_point').remove();
- let points = document.getElementsByClassName('highlight_point');
- for (let i = 0; i < points.length; i++) {
- document.getElementsByClassName('highlight_point')[i].remove();
- }
- }
-
- UpdatePointDisplay() {
- this.ClearPoints();
- this.UpdatePoints();
- this.PrintPoints();
- }
-}
-
-class Layer1Point {
- constructor() {
- this.x = plot.svgLineX[0];
- this.y = plot.svgLineY[0];
- this.strokeWidth = 1.35;
- }
-
- async UpdatePoints() {
- await this.ClearPoints();
- this.x = plot.svgLineX[positionL1.x];
- this.y = plot.svgLineY[positionL1.x];
- }
-
- async PrintPoints() {
- await this.ClearPoints();
- await this.UpdatePoints();
- const svgns = 'http://www.w3.org/2000/svg';
- var point = document.createElementNS(svgns, 'circle');
- point.setAttribute('id', 'highlight_point');
- point.setAttribute('cx', this.x);
- point.setAttribute(
- 'cy',
- constants.svg.getBoundingClientRect().height - this.y
- );
- point.setAttribute('r', 3.95);
- point.setAttribute('stroke', constants.colorSelected);
- point.setAttribute('stroke-width', this.strokeWidth);
- point.setAttribute('fill', constants.colorSelected);
- constants.svg.appendChild(point);
- }
-
- async ClearPoints() {
- let points = document.getElementsByClassName('highlight_point');
- for (let i = 0; i < points.length; i++) {
- document.getElementsByClassName('highlight_point')[i].remove();
- }
- if (document.getElementById('highlight_point'))
- document.getElementById('highlight_point').remove();
- }
-
- UpdatePointDisplay() {
- this.ClearPoints();
- this.UpdatePoints();
- this.PrintPoints();
- }
-}
-
-// events and init functions
-document.addEventListener('DOMContentLoaded', function (e) {
- // we wrap in DOMContentLoaded to make sure everything has loaded before we run anything
-
- // create global vars
- window.constants = new Constants();
- window.resources = new Resources();
- window.menu = new Menu();
- window.tracker = new Tracker();
-
- // run tracker stuff only on user study page
- if (document.getElementById('download_data_trigger')) {
- document
- .getElementById('download_data_trigger')
- .addEventListener('click', function (e) {
- tracker.DownloadTrackerData();
- });
- }
-
- // run events only on pages with a chart (svg)
- if (document.getElementById(constants.svg_container_id)) {
- constants.PrepChartHelperComponents(); // init html
- window.review = new Review();
- window.display = new Display();
-
- // default page load focus on svg
- // this is mostly for debugging, as first time load users must click or hit a key to focus
- // todo for publish: probably remove outright
- if (constants.debugLevel > 5) {
- setTimeout(function () {
- constants.svg.focus();
- }, 100); // it needs just a tick after DOMContentLoaded
- }
-
- if (constants.svg_container) {
- constants.svg_container.addEventListener('keydown', function (e) {
- // Menu open
- if (e.which == 72) {
- // M(77) for menu, or H(72) for help? I don't like it
- menu.Toggle(true);
- }
- });
- }
-
- // menu close
- let allClose = document.querySelectorAll('#close_menu, #menu .close');
- for (let i = 0; i < allClose.length; i++) {
- allClose[i].addEventListener('click', function (e) {
- menu.Toggle(false);
- });
- }
- document
- .getElementById('save_and_close_menu')
- .addEventListener('click', function (e) {
- menu.SaveData();
- menu.Toggle(false);
- });
- document.getElementById('menu').addEventListener('keydown', function (e) {
- if (e.which == 27) {
- // esc
- menu.Toggle(false);
- svg.focus();
- }
- });
-
- // save user focus so we can return after menu close
- let allFocus = document.querySelectorAll(
- '#' +
- constants.svg_container_id +
- ' > svg, #' +
- constants.braille_input_id
- );
- for (let i = 0; i < allFocus.length; i++) {
- allFocus[i].addEventListener('focus', function (e) {
- constants.nonMenuFocus = allFocus[i];
- });
- }
-
- // Global events for pages with svg
- document.addEventListener('keydown', function (e) {
- // Tracker
- if (constants.isTracking) {
- if (e.which == 121) {
- //tracker.DownloadTrackerData();
- } else {
- if (plot) {
- tracker.LogEvent(e);
- }
- }
- }
-
- // Kill autoplay
- if (constants.isMac ? e.which == 91 || e.which == 93 : e.which == 17) {
- // ctrl (either one)
- constants.KillAutoplay();
- }
-
- // Review mode
- if (e.which == 82 && !e.ctrlKey && !e.shiftKey && !e.altKey) {
- // R, but let Ctrl etc R go through cause I use that to refresh
- e.preventDefault();
- if (constants.review_container.classList.contains('hidden')) {
- review.ToggleReviewMode(true);
- } else {
- review.ToggleReviewMode(false);
- }
- }
- });
- }
-
- // global events for all files
- document.addEventListener('keydown', function (e) {
- // reset tracking with Ctrl + F5 / command + F5, and Ctrl + Shift + R / command + Shift + R
- // future todo: this should probably be a button with a confirmation. This is dangerous
- if (
- (e.which == 116 && (constants.isMac ? e.metaKey : e.ctrlKey)) ||
- (e.which == 82 && e.shiftKey && (constants.isMac ? e.metaKey : e.ctrlKey))
- ) {
- e.preventDefault();
- tracker.Delete();
- location.reload(true);
- }
- });
-});
-
-document.addEventListener('DOMContentLoaded', function (e) {
- // we wrap in DOMContentLoaded to make sure everything has loaded before we run anything
-
- // variable initialization
-
- if (typeof maidr !== 'undefined') {
- if ('type' in maidr) {
- constants.chartType = maidr.type;
- }
- }
-
- if (typeof constants.chartType !== 'undefined') {
- if (constants.chartType == 'barplot') {
- window.position = new Position(-1, -1);
- window.plot = new BarChart();
-
- let audio = new Audio();
-
- // global variables
- let lastPlayed = '';
- let lastx = 0;
- let lastKeyTime = 0;
- let pressedL = false;
-
- // control eventlisteners
- constants.svg_container.addEventListener('keydown', function (e) {
- let updateInfoThisRound = false; // we only update info and play tones on certain keys
- let isAtEnd = false;
-
- if (e.which === 39) {
- // right arrow 39
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- position.x -= 1;
- Autoplay('right', position.x, plot.bars.length);
- } else {
- position.x = plot.bars.length - 1; // go all the way
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (
- e.altKey &&
- e.shiftKey &&
- position.x != plot.bars.length - 1
- ) {
- lastx = position.x;
- Autoplay('reverse-right', plot.bars.length, position.x);
- } else {
- position.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- }
- if (e.which === 37) {
- // left arrow 37
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- position.x += 1;
- Autoplay('left', position.x, -1);
- } else {
- position.x = 0; // go all the way
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.altKey && e.shiftKey && position.x != 0) {
- lastx = position.x;
- Autoplay('reverse-left', -1, position.x);
- } else {
- position.x += -1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- }
-
- // update display / text / audio
- if (updateInfoThisRound && !isAtEnd) {
- UpdateAll();
- }
- if (isAtEnd) {
- audio.playEnd();
- }
- });
-
- constants.brailleInput.addEventListener('keydown', function (e) {
- // We block all input, except if it's B or Tab so we move focus
-
- let updateInfoThisRound = false; // we only update info and play tones on certain keys
- let isAtEnd = false;
-
- if (e.which == 9) {
- // tab
- // do nothing, let the user Tab away
- } else if (e.which == 39) {
- // right arrow
- e.preventDefault();
- if (e.target.selectionStart > e.target.value.length - 2) {
- } else if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- position.x -= 1;
- Autoplay('right', position.x, plot.bars.length);
- } else {
- position.x = plot.bars.length - 1; // go all the way
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (
- e.altKey &&
- e.shiftKey &&
- position.x != plot.bars.length - 1
- ) {
- lastx = position.x;
- Autoplay('reverse-right', plot.bars.length, position.x);
- } else {
- position.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.which == 37) {
- // left arrow
- e.preventDefault();
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- position.x += 1;
- Autoplay('left', position.x, -1);
- } else {
- position.x = 0; // go all the way
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.altKey && e.shiftKey && position.x != 0) {
- lastx = position.x;
- Autoplay('reverse-left', -1, position.x);
- } else {
- position.x += -1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else {
- e.preventDefault();
- }
-
- // auto turn off braille mode if we leave the braille box
- constants.brailleInput.addEventListener('focusout', function (e) {
- display.toggleBrailleMode('off');
- });
-
- // update display / text / audio
- if (updateInfoThisRound && !isAtEnd) {
- UpdateAllBraille();
- }
- if (isAtEnd) {
- audio.playEnd();
- }
- });
-
- // var keys;
- // main BTS controls
- let controlElements = [constants.svg_container, constants.brailleInput];
- for (let i = 0; i < controlElements.length; i++) {
- controlElements[i].addEventListener('keydown', function (e) {
- // B: braille mode
- if (e.which == 66) {
- display.toggleBrailleMode();
- e.preventDefault();
- }
- // keys = (keys || []);
- // keys[e.keyCode] = true;
- // if (keys[84] && !keys[76]) {
- // display.toggleTextMode();
- // }
-
- // T: aria live text output mode
- if (e.which == 84) {
- let timediff = window.performance.now() - lastKeyTime;
- if (!pressedL || timediff > constants.keypressInterval) {
- display.toggleTextMode();
- }
- }
-
- // S: sonification mode
- if (e.which == 83) {
- display.toggleSonificationMode();
- }
-
- if (e.which === 32) {
- // space 32, replay info but no other changes
- UpdateAll();
- }
- });
- }
-
- document.addEventListener('keydown', function (e) {
- // ctrl/cmd: stop autoplay
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- // (ctrl/cmd)+(home/fn+left arrow): first element
- if (e.which == 36) {
- position.x = 0;
- UpdateAllBraille();
- }
-
- // (ctrl/cmd)+(end/fn+right arrow): last element
- else if (e.which == 35) {
- position.x = plot.bars.length - 1;
- UpdateAllBraille();
- }
- }
-
- // for concurrent key press
- // keys = (keys || []);
- // keys[e.keyCode] = true;
- // // lx: x label, ly: y label, lt: title
- // if (keys[76] && keys[88]) { // lx
- // display.displayXLabel(plot);
- // }
-
- // if (keys[76] && keys[89]) { // ly
- // display.displayYLabel(plot);
- // }
-
- // if (keys[76] && keys[84]) { // lt
- // display.displayTitle(plot);
- // }
-
- // must come before prefix L
- if (pressedL) {
- if (e.which == 88) {
- // X: x label
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayXLabel(plot);
- }
- pressedL = false;
- } else if (e.which == 89) {
- // Y: y label
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayYLabel(plot);
- }
- pressedL = false;
- } else if (e.which == 84) {
- // T: title
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayTitle(plot);
- }
- pressedL = false;
- } else if (e.which == 76) {
- lastKeyTime = window.performance.now();
- pressedL = true;
- } else {
- pressedL = false;
- }
- }
-
- // L: prefix for label; must come after the suffix
- if (e.which == 76) {
- lastKeyTime = window.performance.now();
- pressedL = true;
- }
-
- // period: speed up
- if (e.which == 190) {
- constants.SpeedUp();
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- if (lastPlayed == 'reverse-left') {
- Autoplay('right', position.x, lastx);
- } else if (lastPlayed == 'reverse-right') {
- Autoplay('left', position.x, lastx);
- } else {
- Autoplay(lastPlayed, position.x, lastx);
- }
- }
- }
-
- // comma: speed down
- if (e.which == 188) {
- constants.SpeedDown();
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- if (lastPlayed == 'reverse-left') {
- Autoplay('right', position.x, lastx);
- } else if (lastPlayed == 'reverse-right') {
- Autoplay('left', position.x, lastx);
- } else {
- Autoplay(lastPlayed, position.x, lastx);
- }
- }
- }
- });
-
- // document.addEventListener("keyup", function (e) {
- // keys[e.keyCode] = false;
- // stop();
- // }, false);
-
- function lockPosition() {
- // lock to min / max postions
- let isLockNeeded = false;
- if (!constants.hasRect) {
- return isLockNeeded;
- }
-
- if (position.x < 0) {
- position.x = 0;
- isLockNeeded = true;
- }
- if (position.x > plot.bars.length - 1) {
- position.x = plot.bars.length - 1;
- isLockNeeded = true;
- }
-
- return isLockNeeded;
- }
- function UpdateAll() {
- if (constants.showDisplay) {
- display.displayValues(plot);
- }
- if (constants.showRect && constants.hasRect) {
- plot.Select();
- }
- if (constants.sonifMode != 'off') {
- audio.playTone();
- }
- }
- function UpdateAllAutoplay() {
- if (constants.showDisplayInAutoplay) {
- display.displayValues(plot);
- }
- if (constants.showRect && constants.hasRect) {
- plot.Select();
- }
- if (constants.sonifMode != 'off') {
- audio.playTone();
- }
-
- if (constants.brailleMode != 'off') {
- display.UpdateBraillePos(plot);
- }
- }
- function UpdateAllBraille() {
- if (constants.showDisplayInBraille) {
- display.displayValues(plot);
- }
- if (constants.showRect && constants.hasRect) {
- plot.Select();
- }
- if (constants.sonifMode != 'off') {
- audio.playTone();
- }
- display.UpdateBraillePos(plot);
- }
- function Autoplay(dir, start, end) {
- lastPlayed = dir;
- let step = 1; // default right and reverse-left
- if (dir == 'left' || dir == 'reverse-right') {
- step = -1;
- }
-
- // clear old autoplay if exists
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- }
-
- if (dir == 'reverse-right' || dir == 'reverse-left') {
- position.x = start;
- }
-
- constants.autoplayId = setInterval(function () {
- position.x += step;
- if (position.x < 0 || plot.bars.length - 1 < position.x) {
- constants.KillAutoplay();
- lockPosition();
- } else if (position.x == end) {
- constants.KillAutoplay();
- UpdateAllAutoplay();
- } else {
- UpdateAllAutoplay();
- }
- }, constants.autoPlayRate);
- }
- } else if (constants.chartType == 'boxplot') {
- // variable initialization
- constants.plotId = 'geom_boxplot.gTree.78.1';
- window.plot = new BoxPlot();
- constants.chartType = 'boxplot';
- if (constants.plotOrientation == 'vert') {
- window.position = new Position(0, plot.plotData[0].length - 1);
- } else {
- window.position = new Position(-1, plot.plotData.length);
- }
- let rect = new BoxplotRect();
- let audio = new Audio();
- let lastPlayed = '';
- let lastY = 0;
- let lastx = 0;
- let lastKeyTime = 0;
- let pressedL = false;
-
- // control eventlisteners
- constants.svg_container.addEventListener('keydown', function (e) {
- let updateInfoThisRound = false; // we only update info and play tones on certain keys
- let isAtEnd = false;
-
- // right arrow
- if (e.which === 39) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- if (constants.plotOrientation == 'vert') {
- Autoplay('right', position.x, plot.plotData.length - 1);
- } else {
- Autoplay('right', position.x, plot.plotData[position.y].length);
- }
- } else {
- isAtEnd = lockPosition();
- if (constants.plotOrientation == 'vert') {
- position.x = plot.plotData.length - 1;
- } else {
- position.x = plot.plotData[position.y].length - 1;
- }
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (constants.plotOrientation == 'vert') {
- if (
- e.altKey &&
- e.shiftKey &&
- plot.plotData.length - 1 != position.x
- ) {
- lastY = position.y;
- Autoplay('reverse-right', plot.plotData.length - 1, position.x);
- } else {
- if (
- position.x == -1 &&
- position.y == plot.plotData[position.x].length
- ) {
- position.y -= 1;
- }
- position.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else {
- if (
- e.altKey &&
- e.shiftKey &&
- plot.plotData[position.y].length - 1 != position.x
- ) {
- lastx = position.x;
- Autoplay(
- 'reverse-right',
- plot.plotData[position.y].length - 1,
- position.x
- );
- } else {
- if (position.x == -1 && position.y == plot.plotData.length) {
- position.y -= 1;
- }
- position.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- }
- constants.navigation = 1;
- }
- // left arrow
- if (e.which === 37) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- Autoplay('left', position.x, -1);
- } else {
- position.x = 0;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.altKey && e.shiftKey && position.x > 0) {
- if (constants.plotOrientation == 'vert') {
- lastY = position.y;
- } else {
- lastx = position.x;
- }
- Autoplay('reverse-left', 0, position.x);
- } else {
- position.x += -1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- constants.navigation = 1;
- }
- // up arrow
- if (e.which === 38) {
- let oldY = position.y;
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- if (constants.plotOrientation == 'vert') {
- Autoplay('up', position.y, plot.plotData[position.x].length);
- } else {
- Autoplay('up', position.y, plot.plotData.length);
- }
- } else {
- if (constants.plotOrientation == 'vert') {
- position.y = plot.plotData[position.x].length - 1;
- } else {
- position.y = plot.plotData.length - 1;
- }
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (constants.plotOrientation == 'vert') {
- if (
- e.altKey &&
- e.shiftKey &&
- position.y != plot.plotData[position.x].length - 1
- ) {
- lastY = position.y;
- Autoplay(
- 'reverse-up',
- plot.plotData[position.x].length - 1,
- position.y
- );
- } else {
- position.y += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else {
- if (
- e.altKey &&
- e.shiftKey &&
- position.y != plot.plotData.length - 1
- ) {
- lastx = position.x;
- Autoplay('reverse-up', plot.plotData.length - 1, position.y);
- } else {
- position.y += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- }
- constants.navigation = 0;
- }
- // down arrow
- if (e.which === 40) {
- let oldY = position.y;
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- Autoplay('down', position.y, -1);
- } else {
- position.y = 0;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.altKey && e.shiftKey && position.y != 0) {
- if (constants.plotOrientation == 'vert') {
- lastY = position.y;
- } else {
- lastx = position.x;
- }
- Autoplay('reverse-down', 0, position.y);
- } else {
- if (constants.plotOrientation == 'vert') {
- if (
- position.x == -1 &&
- position.y == plot.plotData[position.x].length
- ) {
- position.x += 1;
- }
- } else {
- if (position.x == -1 && position.y == plot.plotData.length) {
- position.x += 1;
- }
- }
- position.y += -1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- //position.x = GetRelativeBoxPosition(oldY, position.y);
- constants.navigation = 0;
- }
-
- // update display / text / audio
- if (updateInfoThisRound && !isAtEnd) {
- UpdateAll();
- }
- if (isAtEnd) {
- audio.playEnd();
- }
- });
-
- constants.brailleInput.addEventListener('keydown', function (e) {
- // We block all input, except if it's B or Tab so we move focus
-
- let updateInfoThisRound = false; // we only update info and play tones on certain keys
- let setBrailleThisRound = false;
- let isAtEnd = false;
-
- if (e.which == 9) {
- // tab
- // do nothing, let the user Tab away
- } else if (e.which == 39) {
- // right arrow
- e.preventDefault();
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- if (constants.plotOrientation == 'vert') {
- Autoplay('right', position.x, plot.plotData.length - 1);
- } else {
- Autoplay('right', position.x, plot.plotData[position.y].length);
- }
- } else {
- if (constants.plotOrientation == 'vert') {
- position.x = plot.plotData.length - 1;
- } else {
- position.x = plot.plotData[position.y].length - 1;
- }
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (constants.plotOrientation == 'vert') {
- if (
- e.altKey &&
- e.shiftKey &&
- plot.plotData.length - 1 != position.x
- ) {
- lastY = position.y;
- Autoplay('reverse-right', plot.plotData.length - 1, position.x);
- } else {
- if (
- position.x == -1 &&
- position.y == plot.plotData[position.x].length
- ) {
- position.y -= 1;
- }
- position.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else {
- if (
- e.altKey &&
- e.shiftKey &&
- plot.plotData[position.y].length - 1 != position.x
- ) {
- lastx = position.x;
- Autoplay(
- 'reverse-right',
- plot.plotData[position.y].length - 1,
- position.x
- );
- } else {
- if (position.x == -1 && position.y == plot.plotData.length) {
- position.y -= 1;
- }
- position.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- }
- setBrailleThisRound = true;
- constants.navigation = 1;
- } else if (e.which == 37) {
- // left arrow
- e.preventDefault();
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- Autoplay('left', position.x, -1);
- } else {
- position.x = 0;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.altKey && e.shiftKey && position.x > 0) {
- if (constants.plotOrientation == 'vert') {
- lastY = position.y;
- } else {
- lastx = position.x;
- }
- Autoplay('reverse-left', 0, position.x);
- } else {
- position.x += -1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- setBrailleThisRound = true;
- constants.navigation = 1;
- } else if (e.which === 38) {
- // up arrow
- let oldY = position.y;
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- if (constants.plotOrientation == 'vert') {
- if (position.x < 0) position.x = 0;
- Autoplay('up', position.y, plot.plotData[position.x].length);
- } else {
- Autoplay('up', position.y, plot.plotData.length);
- }
- } else if (constants.plotOrientation == 'vert') {
- position.y = plot.plotData[position.x].length - 1;
- updateInfoThisRound = true;
- } else {
- position.y = plot.plotData.length - 1;
- updateInfoThisRound = true;
- }
- } else if (constants.plotOrientation == 'vert') {
- if (
- e.altKey &&
- e.shiftKey &&
- position.y != plot.plotData[position.x].length - 1
- ) {
- lasY = position.y;
- Autoplay(
- 'reverse-up',
- plot.plotData[position.x].length - 1,
- position.y
- );
- } else {
- position.y += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else {
- if (
- e.altKey &&
- e.shiftKey &&
- position.y != plot.plotData.length - 1
- ) {
- lastx = position.x;
- Autoplay('reverse-up', plot.plotData.length - 1, position.y);
- } else {
- position.y += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- }
- if (constants.plotOrientation == 'vert') {
- } else {
- setBrailleThisRound = true;
- }
- constants.navigation = 0;
- } else if (e.which === 40) {
- // down arrow
- let oldY = position.y;
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- Autoplay('down', position.y, -1);
- } else {
- position.y = 0;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.altKey && e.shiftKey && position.y != 0) {
- if (constants.plotOrientation == 'vert') {
- lastY = position.y;
- } else {
- lastx = position.x;
- }
- Autoplay('reverse-down', 0, position.y);
- } else {
- if (constants.plotOrientation == 'vert') {
- if (
- position.x == -1 &&
- position.y == plot.plotData[position.x].length
- ) {
- position.x += 1;
- }
- } else {
- if (position.x == -1 && position.y == plot.plotData.length) {
- position.x += 1;
- }
- }
- position.y += -1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- constants.navigation = 0;
- if (constants.plotOrientation == 'vert') {
- } else {
- setBrailleThisRound = true;
- }
- constants.navigation = 0;
- } else {
- e.preventDefault();
- // todo: allow some controls through like page refresh
- }
-
- // update audio. todo: add a setting for this later
- if (updateInfoThisRound && !isAtEnd) {
- if (setBrailleThisRound) display.SetBraille(plot);
- setTimeout(UpdateAllBraille, 50); // we delay this by just a moment as otherwise the cursor position doesn't get set
- }
- if (isAtEnd) {
- audio.playEnd();
- }
-
- // auto turn off braille mode if we leave the braille box
- constants.brailleInput.addEventListener('focusout', function (e) {
- display.toggleBrailleMode('off');
- });
- });
-
- // var keys;
- // main BTS controls
- let controlElements = [constants.svg_container, constants.brailleInput];
- for (let i = 0; i < controlElements.length; i++) {
- controlElements[i].addEventListener('keydown', function (e) {
- // B: braille mode
- if (e.which == 66) {
- display.toggleBrailleMode();
- e.preventDefault();
- }
- // T: aria live text output mode
- if (e.which == 84) {
- let timediff = window.performance.now() - lastKeyTime;
- if (!pressedL || timediff > constants.keypressInterval) {
- display.toggleTextMode();
- }
- }
-
- // keys = (keys || []);
- // keys[e.keyCode] = true;
- // if (keys[84] && !keys[76]) {
- // display.toggleTextMode();
- // }
-
- // S: sonification mode
- if (e.which == 83) {
- display.toggleSonificationMode();
- }
-
- if (e.which === 32) {
- // space 32, replay info but no other changes
- UpdateAll();
- }
- });
- }
-
- document.addEventListener('keydown', function (e) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- // (ctrl/cmd)+(home/fn+left arrow): top left element
- if (e.which == 36) {
- position.x = 0;
- position.y = plot.plotData.length - 1;
- UpdateAllBraille();
- }
-
- // (ctrl/cmd)+(end/fn+right arrow): right bottom element
- else if (e.which == 35) {
- position.x = plot.plotData[0].length - 1;
- position.y = 0;
- UpdateAllBraille();
- }
- }
-
- // keys = (keys || []);
- // keys[e.keyCode] = true;
- // // lx: x label, ly: y label, lt: title, lf: fill
- // if (keys[76] && keys[88]) { // lx
- // display.displayXLabel(plot);
- // }
-
- // if (keys[76] && keys[89]) { // ly
- // display.displayYLabel(plot);
- // }
-
- // if (keys[76] && keys[84]) { // lt
- // display.displayTitle(plot);
- // }
-
- // must come before the prefix L
- if (pressedL) {
- if (e.which == 88) {
- // X: x label
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayXLabel(plot);
- }
- pressedL = false;
- } else if (e.which == 89) {
- // Y: y label
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayYLabel(plot);
- }
- pressedL = false;
- } else if (e.which == 84) {
- // T: title
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayTitle(plot);
- }
- pressedL = false;
- } else if (e.which == 76) {
- lastKeyTime = window.performance.now();
- pressedL = true;
- } else {
- pressedL = false;
- }
- }
-
- // L: prefix for label; must come after suffix
- if (e.which == 76) {
- lastKeyTime = window.performance.now();
- pressedL = true;
- }
-
- // period: speed up
- if (e.which == 190) {
- constants.SpeedUp();
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- if (lastPlayed == 'reverse-left') {
- if (constants.plotOrientation == 'vert') {
- Autoplay('right', position.y, lastY);
- } else {
- Autoplay('right', position.x, lastx);
- }
- } else if (lastPlayed == 'reverse-right') {
- if (constants.plotOrientation == 'vert') {
- Autoplay('left', position.y, lastY);
- } else {
- Autoplay('left', position.x, lastx);
- }
- } else if (lastPlayed == 'reverse-up') {
- if (constants.plotOrientation == 'vert') {
- Autoplay('down', position.y, lastY);
- } else {
- Autoplay('down', position.x, lastx);
- }
- } else if (lastPlayed == 'reverse-down') {
- if (constants.plotOrientation == 'vert') {
- Autoplay('up', position.y, lastY);
- } else {
- Autoplay('up', position.x, lastx);
- }
- } else {
- if (constants.plotOrientation == 'vert') {
- Autoplay(lastPlayed, position.y, lastY);
- } else {
- Autoplay(lastPlayed, position.x, lastx);
- }
- }
- }
- }
-
- // comma: speed down
- if (e.which == 188) {
- constants.SpeedDown();
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- if (lastPlayed == 'reverse-left') {
- if (constants.plotOrientation == 'vert') {
- Autoplay('right', position.y, lastY);
- } else {
- Autoplay('right', position.x, lastx);
- }
- } else if (lastPlayed == 'reverse-right') {
- if (constants.plotOrientation == 'vert') {
- Autoplay('left', position.y, lastY);
- } else {
- Autoplay('left', position.x, lastx);
- }
- } else if (lastPlayed == 'reverse-up') {
- if (constants.plotOrientation == 'vert') {
- Autoplay('down', position.y, lastY);
- } else {
- Autoplay('down', position.x, lastx);
- }
- } else if (lastPlayed == 'reverse-down') {
- if (constants.plotOrientation == 'vert') {
- Autoplay('up', position.y, lastY);
- } else {
- Autoplay('up', position.x, lastx);
- }
- } else {
- if (constants.plotOrientation == 'vert') {
- Autoplay(lastPlayed, position.y, lastY);
- } else {
- Autoplay(lastPlayed, position.x, lastx);
- }
- }
- }
- }
- });
-
- // document.addEventListener("keyup", function (e) {
- // keys[e.keyCode] = false;
- // stop();
- // }, false);
-
- function UpdateAll() {
- if (constants.showDisplay) {
- display.displayValues(plot);
- }
- if (constants.showRect && constants.hasRect) {
- rect.UpdateRect();
- }
- if (constants.sonifMode != 'off') {
- plot.PlayTones(audio);
- }
- }
- function UpdateAllAutoplay() {
- if (constants.showDisplayInAutoplay) {
- display.displayValues(plot);
- }
- if (constants.showRect && constants.hasRect) {
- rect.UpdateRect();
- }
- if (constants.sonifMode != 'off') {
- plot.PlayTones(audio);
- }
- if (constants.brailleMode != 'off') {
- display.UpdateBraillePos(plot);
- }
- }
- function UpdateAllBraille() {
- if (constants.showDisplayInBraille) {
- display.displayValues(plot);
- }
- if (constants.showRect && constants.hasRect) {
- rect.UpdateRect();
- }
- if (constants.sonifMode != 'off') {
- plot.PlayTones(audio);
- }
- display.UpdateBraillePos(plot);
- }
- function lockPosition() {
- // lock to min / max postions
- let isLockNeeded = false;
- if (constants.plotOrientation == 'vert') {
- if (position.y < 0) {
- position.y = 0;
- isLockNeeded = true;
- }
- if (position.x < 0) {
- position.x = 0;
- isLockNeeded = true;
- }
- if (position.x > plot.plotData.length - 1) {
- position.x = plot.plotData.length - 1;
- isLockNeeded = true;
- }
- if (position.y > plot.plotData[position.x].length - 1) {
- position.y = plot.plotData[position.x].length - 1;
- isLockNeeded = true;
- }
- } else {
- if (position.x < 0) {
- position.x = 0;
- isLockNeeded = true;
- }
- if (position.y < 0) {
- position.y = 0;
- isLockNeeded = true;
- }
- if (position.y > plot.plotData.length - 1) {
- position.y = plot.plotData.length - 1;
- isLockNeeded = true;
- }
- if (position.x > plot.plotData[position.y].length - 1) {
- position.x = plot.plotData[position.y].length - 1;
- isLockNeeded = true;
- }
- }
-
- return isLockNeeded;
- }
-
- // deprecated. We now use grid system and x values are always available
- function GetRelativeBoxPosition(yOld, yNew) {
- // Used when we move up / down to another plot
- // We want to go to the relative position in the new plot
- // ie, if we were on the 50%, return the position.x of the new 50%
-
- // init
- let xNew = 0;
- // lock yNew
- if (yNew < 1) {
- ynew = 0;
- } else if (yNew > plot.plotData.length - 1) {
- yNew = plot.plotData.length - 1;
- }
-
- if (yOld < 0) {
- // not on any chart yet, just start at 0
- } else {
- let oldLabel = '';
- if ('label' in plot.plotData[yOld][position.x]) {
- oldLabel = plot.plotData[yOld][position.x].label;
- }
- // does it exist on the new plot? we'll just get that val
- for (let i = 0; i < plot.plotData[yNew].length; i++) {
- if (plot.plotData[yNew][i].label == oldLabel) {
- xNew = i;
- }
- }
- }
-
- return xNew;
- }
-
- function Autoplay(dir, start, end) {
- lastPlayed = dir;
- let step = 1; // default right / up / reverse-left / reverse-down
- if (
- dir == 'left' ||
- dir == 'down' ||
- dir == 'reverse-right' ||
- dir == 'reverse-up'
- ) {
- step = -1;
- }
-
- // clear old autoplay if exists
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- }
-
- if (dir == 'reverse-left' || dir == 'reverse-right') {
- position.x = start;
- } else if (dir == 'reverse-up' || dir == 'reverse-down') {
- position.y = start;
- }
-
- if (constants.debugLevel > 0) {
- console.log('starting autoplay', dir);
- }
-
- UpdateAllAutoplay(); // play current tone before we move
- constants.autoplayId = setInterval(function () {
- let doneNext = false;
- if (dir == 'left' || dir == 'right' || dir == 'up' || dir == 'down') {
- if (
- (position.x < 1 && dir == 'left') ||
- (constants.plotOrientation == 'vert' &&
- dir == 'up' &&
- position.y > plot.plotData[position.x].length - 2) ||
- (constants.plotOrientation == 'horz' &&
- dir == 'up' &&
- position.y > plot.plotData.length - 2) ||
- (constants.plotOrientation == 'horz' &&
- dir == 'right' &&
- position.x > plot.plotData[position.y].length - 2) ||
- (constants.plotOrientation == 'vert' &&
- dir == 'right' &&
- position.x > plot.plotData.length - 2) ||
- (constants.plotOrientation == 'horz' &&
- dir == 'down' &&
- position.y < 1) ||
- (constants.plotOrientation == 'vert' &&
- dir == 'down' &&
- position.y < 1)
- ) {
- doneNext = true;
- }
- } else {
- if (
- (dir == 'reverse-left' && position.x >= end) ||
- (dir == 'reverse-right' && position.x <= end) ||
- (dir == 'reverse-up' && position.y <= end) ||
- (dir == 'reverse-down' && position.y >= end)
- ) {
- doneNext = true;
- }
- }
-
- if (doneNext) {
- constants.KillAutoplay();
- } else {
- if (
- dir == 'left' ||
- dir == 'right' ||
- dir == 'reverse-left' ||
- dir == 'reverse-right'
- ) {
- position.x += step;
- } else {
- position.y += step;
- }
- UpdateAllAutoplay();
- }
- if (constants.debugLevel > 5) {
- console.log('autoplay pos', position);
- }
- }, constants.autoPlayRate);
- }
- } else if (constants.chartType == 'heatmap') {
- // variable initialization
- constants.plotId = 'geom_rect.rect.2.1';
- window.position = new Position(-1, -1);
- window.plot = new HeatMap();
- constants.chartType = 'heatmap';
- let rect = new HeatMapRect();
- let audio = new Audio();
- let lastPlayed = '';
- let lastx = 0;
- let lastKeyTime = 0;
- let pressedL = false;
-
- // control eventlisteners
- constants.svg_container.addEventListener('keydown', function (e) {
- let updateInfoThisRound = false;
- let isAtEnd = false;
-
- // right arrow 39
- if (e.which === 39) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- position.x -= 1;
- Autoplay('right', position.x, plot.num_cols);
- } else {
- position.x = plot.num_cols - 1;
- updateInfoThisRound = true;
- }
- } else if (
- e.altKey &&
- e.shiftKey &&
- position.x != plot.num_cols - 1
- ) {
- lastx = position.x;
- Autoplay('reverse-right', plot.num_cols, position.x);
- } else {
- if (position.x == -1 && position.y == -1) {
- position.y += 1;
- }
- position.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- constants.navigation = 1;
- }
-
- // left arrow 37
- if (e.which === 37) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- position.x += 1;
- Autoplay('left', position.x, -1);
- } else {
- position.x = 0;
- updateInfoThisRound = true;
- }
- } else if (e.altKey && e.shiftKey && position.x != 0) {
- lastx = position.x;
- Autoplay('reverse-left', -1, position.x);
- } else {
- position.x -= 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- constants.navigation = 1;
- }
-
- // up arrow 38
- if (e.which === 38) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.y;
- position.y += 1;
- Autoplay('up', position.y, -1);
- } else {
- position.y = 0;
- updateInfoThisRound = true;
- }
- } else if (e.altKey && e.shiftKey && position.y != 0) {
- lastx = position.x;
- Autoplay('reverse-up', -1, position.y);
- } else {
- position.y -= 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- constants.navigation = 0;
- }
-
- // down arrow 40
- if (e.which === 40) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.y;
- position.y -= 1;
- Autoplay('down', position.y, plot.num_rows);
- } else {
- position.y = plot.num_rows - 1;
- updateInfoThisRound = true;
- }
- } else if (
- e.altKey &&
- e.shiftKey &&
- position.y != plot.num_rows - 1
- ) {
- lastx = position.x;
- Autoplay('reverse-down', plot.num_rows, position.y);
- } else {
- if (position.x == -1 && position.y == -1) {
- position.x += 1;
- }
- position.y += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- constants.navigation = 0;
- }
-
- // update text, display, and audio
- if (updateInfoThisRound && !isAtEnd) {
- UpdateAll();
- }
- if (isAtEnd) {
- audio.playEnd();
- }
- });
-
- constants.brailleInput.addEventListener('keydown', function (e) {
- let updateInfoThisRound = false;
- let isAtEnd = false;
-
- if (e.which == 9) {
- // let user tab
- } else if (e.which == 39) {
- // right arrow
- if (
- e.target.selectionStart > e.target.value.length - 3 ||
- e.target.value.substring(
- e.target.selectionStart + 1,
- e.target.selectionStart + 2
- ) == 'â ³'
- ) {
- // already at the end, do nothing
- e.preventDefault();
- } else {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (position.x == -1 && position.y == -1) {
- position.x += 1;
- position.y += 1;
- }
- if (e.shiftKey) {
- position.x -= 1;
- Autoplay('right', position.x, plot.num_cols);
- } else {
- position.x = plot.num_cols - 1;
- updateInfoThisRound = true;
- }
- } else if (
- e.altKey &&
- e.shiftKey &&
- position.x != plot.num_cols - 1
- ) {
- lastx = position.x;
- Autoplay('reverse-right', plot.num_cols, position.x);
- } else {
- if (position.x == -1 && position.y == -1) {
- position.y += 1;
- }
- position.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
-
- // we need pos to be y*(num_cols+1), (and num_cols+1 because there's a spacer character)
- let pos = position.y * (plot.num_cols + 1) + position.x;
- e.target.setSelectionRange(pos, pos);
- e.preventDefault();
-
- constants.navigation = 1;
- }
- } else if (e.which == 37) {
- // left
- if (
- e.target.selectionStart == 0 ||
- e.target.value.substring(
- e.target.selectionStart - 1,
- e.target.selectionStart
- ) == 'â ³'
- ) {
- e.preventDefault();
- } else {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- position.x += 1;
- Autoplay('left', position.x, -1);
- } else {
- position.x = 0;
- updateInfoThisRound = true;
- }
- } else if (e.altKey && e.shiftKey && position.x != 0) {
- lastx = position.x;
- Autoplay('reverse-left', -1, position.x);
- } else {
- position.x += -1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
-
- let pos = position.y * (plot.num_cols + 1) + position.x;
- e.target.setSelectionRange(pos, pos);
- e.preventDefault();
-
- constants.navigation = 1;
- }
- } else if (e.which == 40) {
- // down
- if (position.y + 1 == plot.num_rows) {
- e.preventDefault();
- } else {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (position.x == -1 && position.y == -1) {
- position.x += 1;
- position.y += 1;
- }
- if (e.shiftKey) {
- position.y -= 1;
- Autoplay('down', position.y, plot.num_rows);
- } else {
- position.y = plot.num_rows - 1;
- updateInfoThisRound = true;
- }
- } else if (
- e.altKey &&
- e.shiftKey &&
- position.y != plot.num_rows - 1
- ) {
- lastx = position.x;
- Autoplay('reverse-down', plot.num_rows, position.y);
- } else {
- if (position.x == -1 && position.y == -1) {
- position.x += 1;
- }
- position.y += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
-
- let pos = position.y * (plot.num_cols + 1) + position.x;
- e.target.setSelectionRange(pos, pos);
- e.preventDefault();
-
- constants.navigation = 0;
- }
- } else if (e.which == 38) {
- // up
- if (e.target.selectionStart - plot.num_cols - 1 < 0) {
- e.preventDefault();
- } else {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.y;
- position.y += 1;
- Autoplay('up', position.y, -1);
- } else {
- position.y = 0;
- updateInfoThisRound = true;
- }
- } else if (e.altKey && e.shiftKey && position.y != 0) {
- lastx = position.x;
- Autoplay('reverse-up', -1, position.y);
- } else {
- position.y += -1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
-
- let pos = position.y * (plot.num_cols + 1) + position.x;
- e.target.setSelectionRange(pos, pos);
- e.preventDefault();
-
- constants.navigation = 0;
- }
- } else {
- e.preventDefault();
- }
-
- // auto turn off braille mode if we leave the braille box
- constants.brailleInput.addEventListener('focusout', function (e) {
- display.toggleBrailleMode('off');
- });
-
- if (updateInfoThisRound && !isAtEnd) {
- UpdateAllBraille();
- }
- if (isAtEnd) {
- audio.playEnd();
- }
- });
-
- // var keys;
- // main BTS controls
- let controlElements = [constants.svg_container, constants.brailleInput];
- for (let i = 0; i < controlElements.length; i++) {
- controlElements[i].addEventListener('keydown', function (e) {
- // B: braille mode
- if (e.which == 66) {
- display.toggleBrailleMode();
- e.preventDefault();
- }
- // keys = (keys || []);
- // keys[e.keyCode] = true;
- // if (keys[84] && !keys[76]) {
- // display.toggleTextMode();
- // }
-
- // T: aria live text output mode
- if (e.which == 84) {
- let timediff = window.performance.now() - lastKeyTime;
- if (!pressedL || timediff > constants.keypressInterval) {
- display.toggleTextMode();
- }
- }
-
- // S: sonification mode
- if (e.which == 83) {
- display.toggleSonificationMode();
- }
-
- // space: replay info but no other changes
- if (e.which === 32) {
- UpdateAll();
- }
- });
- }
-
- document.addEventListener('keydown', function (e) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- // (ctrl/cmd)+(home/fn+left arrow): first element
- if (e.which == 36) {
- position.x = 0;
- position.y = 0;
- UpdateAllBraille();
- }
-
- // (ctrl/cmd)+(end/fn+right arrow): last element
- else if (e.which == 35) {
- position.x = plot.num_cols - 1;
- position.y = plot.num_rows - 1;
- UpdateAllBraille();
- }
- }
-
- // keys = (keys || []);
- // keys[e.keyCode] = true;
- // // lx: x label, ly: y label, lt: title, lf: fill
- // if (keys[76] && keys[88]) { // lx
- // display.displayXLabel(plot);
- // }
-
- // if (keys[76] && keys[89]) { // ly
- // display.displayYLabel(plot);
- // }
-
- // if (keys[76] && keys[84]) { // lt
- // display.displayTitle(plot);
- // }
-
- // if (keys[76] && keys[70]) { // lf
- // display.displayFill(plot);
- // }
-
- // must come before the prefix L
- if (pressedL) {
- if (e.which == 88) {
- // X: x label
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayXLabel(plot);
- }
- pressedL = false;
- } else if (e.which == 89) {
- // Y: y label
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayYLabel(plot);
- }
- pressedL = false;
- } else if (e.which == 84) {
- // T: title
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayTitle(plot);
- }
- pressedL = false;
- } else if (e.which == 70) {
- // F: fill label
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayFill(plot);
- }
- pressedL = false;
- } else if (e.which == 76) {
- lastKeyTime = window.performance.now();
- pressedL = true;
- } else {
- pressedL = false;
- }
- }
-
- // L: prefix for label; must come after suffix
- if (e.which == 76) {
- lastKeyTime = window.performance.now();
- pressedL = true;
- }
-
- // period: speed up
- if (e.which == 190) {
- constants.SpeedUp();
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- if (lastPlayed == 'reverse-left') {
- Autoplay('right', position.x, lastx);
- } else if (lastPlayed == 'reverse-right') {
- Autoplay('left', position.x, lastx);
- } else if (lastPlayed == 'reverse-up') {
- Autoplay('down', position.x, lastx);
- } else if (lastPlayed == 'reverse-down') {
- Autoplay('up', position.x, lastx);
- } else {
- Autoplay(lastPlayed, position.x, lastx);
- }
- }
- }
-
- // comma: speed down
- if (e.which == 188) {
- constants.SpeedDown();
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- if (lastPlayed == 'reverse-left') {
- Autoplay('right', position.x, lastx);
- } else if (lastPlayed == 'reverse-right') {
- Autoplay('left', position.x, lastx);
- } else if (lastPlayed == 'reverse-up') {
- Autoplay('down', position.x, lastx);
- } else if (lastPlayed == 'reverse-down') {
- Autoplay('up', position.x, lastx);
- } else {
- Autoplay(lastPlayed, position.x, lastx);
- }
- }
- }
- });
-
- // document.addEventListener("keyup", function (e) {
- // keys[e.keyCode] = false;
- // stop();
- // }, false);
-
- function sleep(time) {
- return new Promise((resolve) => setTimeout(resolve, time));
- }
-
- // helper functions
- function lockPosition() {
- // lock to min / max postions
- let isLockNeeded = false;
-
- if (position.x < 0) {
- position.x = 0;
- isLockNeeded = true;
- }
- if (position.x > plot.num_cols - 1) {
- position.x = plot.num_cols - 1;
- isLockNeeded = true;
- }
- if (position.y < 0) {
- position.y = 0;
- isLockNeeded = true;
- }
- if (position.y > plot.num_rows - 1) {
- position.y = plot.num_rows - 1;
- isLockNeeded = true;
- }
-
- return isLockNeeded;
- }
-
- function UpdateAll() {
- if (constants.showDisplay) {
- display.displayValues(plot);
- }
- if (constants.showRect && constants.hasRect) {
- rect.UpdateRectDisplay();
- }
- if (constants.sonifMode != 'off') {
- audio.playTone();
- }
- }
- function UpdateAllAutoplay() {
- if (constants.showDisplayInAutoplay) {
- display.displayValues(plot);
- }
- if (constants.showRect && constants.hasRect) {
- rect.UpdateRectDisplay();
- }
- if (constants.sonifMode != 'off') {
- audio.playTone();
- }
- if (constants.brailleMode != 'off') {
- display.UpdateBraillePos(plot);
- }
- }
- function UpdateAllBraille() {
- if (constants.showDisplayInBraille) {
- display.displayValues(plot);
- }
- if (constants.showRect && constants.hasRect) {
- rect.UpdateRectDisplay();
- }
- if (constants.sonifMode != 'off') {
- audio.playTone();
- }
- display.UpdateBraillePos(plot);
- }
-
- function Autoplay(dir, start, end) {
- lastPlayed = dir;
- let step = 1; // default right, down, reverse-left, and reverse-up
- if (
- dir == 'left' ||
- dir == 'up' ||
- dir == 'reverse-right' ||
- dir == 'reverse-down'
- ) {
- step = -1;
- }
-
- // clear old autoplay if exists
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- }
-
- if (dir == 'reverse-left' || dir == 'reverse-right') {
- position.x = start;
- } else if (dir == 'reverse-up' || dir == 'reverse-down') {
- position.y = start;
- }
-
- constants.autoplayId = setInterval(function () {
- if (
- dir == 'left' ||
- dir == 'right' ||
- dir == 'reverse-left' ||
- dir == 'reverse-right'
- ) {
- position.x += step;
- if (position.x < 0 || plot.num_cols - 1 < position.x) {
- constants.KillAutoplay();
- lockPosition();
- } else if (position.x == end) {
- constants.KillAutoplay();
- UpdateAllAutoplay();
- } else {
- UpdateAllAutoplay();
- }
- } else {
- // up or down
- position.y += step;
- if (position.y < 0 || plot.num_rows - 1 < position.y) {
- constants.KillAutoplay();
- lockPosition();
- } else if (position.y == end) {
- constants.KillAutoplay();
- UpdateAllAutoplay();
- } else {
- UpdateAllAutoplay();
- }
- }
- }, constants.autoPlayRate);
- }
- } else if (
- constants.chartType == 'scatterplot' ||
- constants.chartType.includes('scatterplot')
- ) {
- // variable initialization
- constants.plotId = 'geom_point.points.12.1';
- window.position = new Position(-1, -1);
- window.plot = new ScatterPlot();
- constants.chartType = 'scatterplot';
- let audio = new Audio();
- let layer0Point = new Layer0Point();
- let layer1Point = new Layer1Point();
-
- let lastPlayed = ''; // for autoplay use
- let lastx = 0; // for layer 1 autoplay use
- let lastx1 = 0; // for layer 2 autoplay use
- let lastKeyTime = 0;
- let pressedL = false;
-
- window.positionL1 = new Position(lastx1, lastx1);
-
- // control eventlisteners
- constants.svg_container.addEventListener('keydown', function (e) {
- let updateInfoThisRound = false;
- let isAtEnd = false;
-
- // left and right arrows are enabled only at point layer
- if (constants.layer == 1) {
- // right arrow 39
- if (e.which === 39) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- position.x -= 1;
- Autoplay('outward_right', position.x, plot.x.length);
- } else {
- position.x = plot.x.length - 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (
- e.altKey &&
- e.shiftKey &&
- position.x != plot.x.length - 1
- ) {
- lastx = position.x;
- Autoplay('inward_right', plot.x.length, position.x);
- } else {
- position.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- }
-
- // left arrow 37
- if (e.which === 37) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- position.x += 1;
- Autoplay('outward_left', position.x, -1);
- } else {
- position.x = 0;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.altKey && e.shiftKey && position.x != 0) {
- lastx = position.x;
- Autoplay('inward_left', -1, position.x);
- } else {
- position.x -= 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- }
- } else if (constants.layer == 2) {
- positionL1.x = lastx1;
-
- if (e.which == 39 && e.shiftKey) {
- if (
- (constants.isMac ? e.metaKey : e.ctrlKey) &&
- constants.sonifMode != 'off'
- ) {
- PlayLine('outward_right');
- } else if (e.altKey && constants.sonifMode != 'off') {
- PlayLine('inward_right');
- }
- }
-
- if (e.which == 37 && e.shiftKey) {
- if (
- (constants.isMac ? e.metaKey : e.ctrlKey) &&
- constants.sonifMode != 'off'
- ) {
- PlayLine('outward_left');
- } else if (e.altKey && constants.sonifMode != 'off') {
- PlayLine('inward_left');
- }
- }
- }
-
- // update text, display, and audio
- if (updateInfoThisRound && constants.layer == 1 && !isAtEnd) {
- UpdateAll();
- }
- if (isAtEnd) {
- audio.playEnd();
- }
- });
-
- constants.brailleInput.addEventListener('keydown', function (e) {
- let updateInfoThisRound = false;
- let isAtEnd = false;
-
- // @TODO
- // only line layer can access to braille display
- if (e.which == 9) {
- // constants.brailleInput.setSelectionRange(positionL1.x, positionL1.x);
- } else if (constants.layer == 2) {
- lockPosition();
- if (e.which == 9) {
- } else if (e.which == 39) {
- // right arrow
- e.preventDefault();
- constants.brailleInput.setSelectionRange(
- positionL1.x,
- positionL1.x
- );
- if (e.target.selectionStart > e.target.value.length - 2) {
- e.preventDefault();
- } else if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- positionL1.x -= 1;
- Autoplay(
- 'outward_right',
- positionL1.x,
- plot.curvePoints.length
- );
- } else {
- positionL1.x = plot.curvePoints.length - 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (
- e.altKey &&
- e.shiftKey &&
- positionL1.x != plot.curvePoints.length - 1
- ) {
- lastx1 = positionL1.x;
- Autoplay('inward_right', plot.curvePoints.length, positionL1.x);
- } else {
- positionL1.x += 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.which == 37) {
- // left
- e.preventDefault();
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- if (e.shiftKey) {
- // lastx = position.x;
- positionL1.x += 1;
- Autoplay('outward_left', positionL1.x, -1);
- } else {
- positionL1.x = 0; // go all the way
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else if (e.altKey && e.shiftKey && positionL1.x != 0) {
- Autoplay('inward_left', -1, positionL1.x);
- } else {
- positionL1.x -= 1;
- updateInfoThisRound = true;
- isAtEnd = lockPosition();
- }
- } else {
- e.preventDefault();
- }
- } else {
- e.preventDefault();
- }
-
- // auto turn off braille mode if we leave the braille box
- constants.brailleInput.addEventListener('focusout', function (e) {
- display.toggleBrailleMode('off');
- });
-
- lastx1 = positionL1.x;
-
- if (updateInfoThisRound && !isAtEnd) {
- UpdateAllBraille();
- }
- if (isAtEnd) {
- audio.playEnd();
- }
- });
-
- // var keys;
- // main BTS controls
- let controlElements = [constants.svg_container, constants.brailleInput];
- for (let i = 0; i < controlElements.length; i++) {
- controlElements[i].addEventListener('keydown', function (e) {
- // B: braille mode
- if (e.which == 66) {
- display.toggleBrailleMode();
- e.preventDefault();
- }
- // T: aria live text output mode
- if (e.which == 84) {
- let timediff = window.performance.now() - lastKeyTime;
- if (!pressedL || timediff > constants.keypressInterval) {
- display.toggleTextMode();
- }
- }
-
- // keys = (keys || []);
- // keys[e.keyCode] = true;
- // if (keys[84] && !keys[76]) {
- // display.toggleTextMode();
- // }
-
- // S: sonification mode
- if (e.which == 83) {
- display.toggleSonificationMode();
- }
-
- // page down /(fn+down arrow): point layer(1)
- if (
- e.which == 34 &&
- constants.layer == 2 &&
- constants.brailleMode == 'off'
- ) {
- lastx1 = positionL1.x;
- display.toggleLayerMode();
- }
-
- // page up / (fn+up arrow): line layer(2)
- if (
- e.which == 33 &&
- constants.layer == 1 &&
- constants.brailleMode == 'off'
- ) {
- display.toggleLayerMode();
- }
-
- // space: replay info but no other changes
- if (e.which === 32) {
- UpdateAll();
- }
- });
- }
-
- document.addEventListener('keydown', function (e) {
- if (constants.isMac ? e.metaKey : e.ctrlKey) {
- // (ctrl/cmd)+(home/fn+left arrow): first element
- if (e.which == 36) {
- if (constants.layer == 1) {
- position.x = 0;
- UpdateAll();
- // move cursor for braille
- constants.brailleInput.setSelectionRange(0, 0);
- } else if (constants.layer == 2) {
- positionL1.x = 0;
- UpdateAllBraille();
- }
- }
-
- // (ctrl/cmd)+(end/fn+right arrow): last element
- else if (e.which == 35) {
- if (constants.layer == 1) {
- position.x = plot.y.length - 1;
- UpdateAll();
- // move cursor for braille
- constants.brailleInput.setSelectionRange(
- plot.curvePoints.length - 1,
- plot.curvePoints.length - 1
- );
- } else if (constants.layer == 2) {
- positionL1.x = plot.curvePoints.length - 1;
- UpdateAllBraille();
- }
- }
-
- // if you're only hitting control
- if (!e.shiftKey) {
- audio.KillSmooth();
- }
- }
-
- // keys = (keys || []);
- // keys[e.keyCode] = true;
- // // lx: x label, ly: y label, lt: title, lf: fill
- // if (keys[76] && keys[88]) { // lx
- // display.displayXLabel(plot);
- // }
-
- // if (keys[76] && keys[89]) { // ly
- // display.displayYLabel(plot);
- // }
-
- // if (keys[76] && keys[84]) { // lt
- // display.displayTitle(plot);
- // }
-
- if (pressedL) {
- if (e.which == 88) {
- // X: x label
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayXLabel(plot);
- }
- pressedL = false;
- } else if (e.which == 89) {
- // Y: y label
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayYLabel(plot);
- }
- pressedL = false;
- } else if (e.which == 84) {
- // T: title
- let timediff = window.performance.now() - lastKeyTime;
- if (pressedL && timediff <= constants.keypressInterval) {
- display.displayTitle(plot);
- }
- pressedL = false;
- } else if (e.which == 76) {
- lastKeyTime = window.performance.now();
- pressedL = true;
- } else {
- pressedL = false;
- }
- }
-
- // L: prefix for label
- if (e.which == 76) {
- lastKeyTime = window.performance.now();
- pressedL = true;
- }
-
- // period: speed up
- if (e.which == 190) {
- constants.SpeedUp();
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- audio.KillSmooth();
- if (lastPlayed == 'inward_left') {
- if (constants.layer == 1) {
- Autoplay('outward_right', position.x, lastx);
- } else if (constants.layer == 2) {
- Autoplay('outward_right', positionL1.x, lastx1);
- }
- } else if (lastPlayed == 'inward_right') {
- if (constants.layer == 1) {
- Autoplay('outward_left', position.x, lastx);
- } else if (constants.layer == 2) {
- Autoplay('outward_left', positionL1.x, lastx1);
- }
- } else {
- if (constants.layer == 1) {
- Autoplay(lastPlayed, position.x, lastx);
- } else if (constants.layer == 2) {
- Autoplay(lastPlayed, positionL1.x, lastx1);
- }
- }
- }
- }
-
- // comma: speed down
- if (e.which == 188) {
- constants.SpeedDown();
- if (constants.autoplayId != null) {
- constants.KillAutoplay();
- audio.KillSmooth();
- if (lastPlayed == 'inward_left') {
- if (constants.layer == 1) {
- Autoplay('outward_right', position.x, lastx);
- } else if (constants.layer == 2) {
- Autoplay('outward_right', positionL1.x, lastx1);
- }
- } else if (lastPlayed == 'inward_right') {
- if (constants.layer == 1) {
- Autoplay('outward_left', position.x, lastx);
- } else if (constants.layer == 2) {
- Autoplay('outward_left', positionL1.x, lastx1);
- }
- } else {
- if (constants.layer == 1) {
- Autoplay(lastPlayed, position.x, lastx);
- } else if (constants.layer == 2) {
- Autoplay(lastPlayed, positionL1.x, lastx1);
- }
- }
- }
- }
- });
-
- // document.addEventListener("keyup", function (e) {
- // keys[e.keyCode] = false;
- // stop();
- // }, false);
-
- // helper functions
- function lockPosition() {
- // lock to min / max positions
- let isLockNeeded = false;
- if (constants.layer == 1) {
- if (position.x < 0) {
- position.x = 0;
- isLockNeeded = true;
- }
- if (position.x > plot.x.length - 1) {
- position.x = plot.x.length - 1;
- isLockNeeded = true;
- }
- } else if (constants.layer == 2) {
- if (positionL1.x < 0) {
- positionL1.x = 0;
- isLockNeeded = true;
- }
- if (positionL1.x > plot.curvePoints.length - 1) {
- positionL1.x = plot.curvePoints.length - 1;
- isLockNeeded = true;
- }
- }
-
- return isLockNeeded;
- }
-
- function UpdateAll() {
- if (constants.showDisplay) {
- display.displayValues(plot);
- }
- if (constants.showRect) {
- layer0Point.UpdatePointDisplay();
- }
- if (constants.sonifMode != 'off') {
- plot.PlayTones(audio);
- }
- }
-
- function UpdateAllAutoplay() {
- if (constants.showDisplayInAutoplay) {
- display.displayValues(plot);
- }
- if (constants.showRect) {
- if (constants.layer == 1) {
- layer0Point.UpdatePointDisplay();
- } else {
- layer1Point.UpdatePointDisplay();
- }
- }
- if (constants.sonifMode != 'off') {
- plot.PlayTones(audio);
- }
- if (constants.brailleMode != 'off') {
- display.UpdateBraillePos(plot);
- }
- }
- function UpdateAllBraille() {
- if (constants.showDisplayInBraille) {
- display.displayValues(plot);
- }
- if (constants.showRect) {
- layer1Point.UpdatePointDisplay();
- }
- if (constants.sonifMode != 'off') {
- plot.PlayTones(audio);
- }
- display.UpdateBraillePos(plot);
- }
-
- function Autoplay(dir, start, end) {
- lastPlayed = dir;
- let step = 1; // default right and reverse left
- if (dir == 'outward_left' || dir == 'inward_right') {
- step = -1;
- }
-
- // clear old autoplay if exists
- if (constants.autoplayId) {
- constants.KillAutoplay();
- }
- if (constants.isSmoothAutoplay) {
- audio.KillSmooth();
- }
-
- if (dir == 'inward_left' || dir == 'inward_right') {
- position.x = start;
- position.L1x = start;
- }
-
- if (constants.layer == 1) {
- constants.autoplayId = setInterval(function () {
- position.x += step;
- // autoplay for two layers: point layer & line layer in braille
- // plot.numPoints is not available anymore
- if (position.x < 0 || position.x > plot.y.length - 1) {
- constants.KillAutoplay();
- lockPosition();
- } else if (position.x == end) {
- constants.KillAutoplay();
- UpdateAllAutoplay();
- } else {
- UpdateAllAutoplay();
- }
- }, constants.autoPlayRate);
- } else if (constants.layer == 2) {
- constants.autoplayId = setInterval(function () {
- positionL1.x += step;
- // autoplay for two layers: point layer & line layer in braille
- // plot.numPoints is not available anymore
- if (
- positionL1.x < 0 ||
- positionL1.x > plot.curvePoints.length - 1
- ) {
- constants.KillAutoplay();
- lockPosition();
- } else if (positionL1.x == end) {
- constants.KillAutoplay();
- UpdateAllAutoplay();
- } else {
- UpdateAllAutoplay();
- }
- }, constants.autoPlayRate);
- }
- }
-
- function PlayLine(dir) {
- lastPlayed = dir;
-
- let freqArr = [];
- let panningArr = [];
- let panPoint = audio.SlideBetween(
- positionL1.x,
- 0,
- plot.curvePoints.length - 1,
- -1,
- 1
- );
- let x = positionL1.x < 0 ? 0 : positionL1.x;
- let duration = 0;
- if (dir == 'outward_right') {
- for (let i = x; i < plot.curvePoints.length; i++) {
- freqArr.push(
- audio.SlideBetween(
- plot.curvePoints[i],
- plot.curveMinY,
- plot.curveMaxY,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- )
- );
- }
- panningArr = [panPoint, 1];
- duration =
- (Math.abs(plot.curvePoints.length - x) / plot.curvePoints.length) *
- 3;
- } else if (dir == 'outward_left') {
- for (let i = x; i >= 0; i--) {
- freqArr.push(
- audio.SlideBetween(
- plot.curvePoints[i],
- plot.curveMinY,
- plot.curveMaxY,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- )
- );
- }
- panningArr = [panPoint, -1];
- duration = (Math.abs(x) / plot.curvePoints.length) * 3;
- } else if (dir == 'inward_right') {
- for (let i = plot.curvePoints.length - 1; i >= x; i--) {
- freqArr.push(
- audio.SlideBetween(
- plot.curvePoints[i],
- plot.curveMinY,
- plot.curveMaxY,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- )
- );
- }
- panningArr = [1, panPoint];
- duration =
- (Math.abs(plot.curvePoints.length - x) / plot.curvePoints.length) *
- 3;
- } else if (dir == 'inward_left') {
- for (let i = 0; i <= x; i++) {
- freqArr.push(
- audio.SlideBetween(
- plot.curvePoints[i],
- plot.curveMinY,
- plot.curveMaxY,
- constants.MIN_FREQUENCY,
- constants.MAX_FREQUENCY
- )
- );
- }
- panningArr = [-1, panPoint];
- duration = (Math.abs(x) / plot.curvePoints.length) * 3;
- }
-
- if (constants.isSmoothAutoplay) {
- audio.KillSmooth();
- }
-
- // audio.playSmooth(freqArr, 2, panningArr, constants.vol, 'sine');
- audio.playSmooth(freqArr, duration, panningArr, constants.vol, 'sine');
- }
- }
- }
-
- // initialize braille mode on page load
- if (constants.brailleMode == 'on') {
- display.toggleBrailleMode('on');
- }
-});
diff --git a/maidr/example/js/maidr.min.js b/maidr/example/js/maidr.min.js
deleted file mode 100644
index 7c4144e..0000000
--- a/maidr/example/js/maidr.min.js
+++ /dev/null
@@ -1 +0,0 @@
-class Constants{svg_container_id="svg-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;constructor(){this.svg_container=document.getElementById(this.svg_container_id),this.svg=document.querySelector("#"+this.svg_container_id+" > svg"),this.brailleContainer=document.getElementById(this.braille_container_id),this.brailleInput=document.getElementById(this.braille_input_id),this.infoDiv=document.getElementById(this.info_id),this.announceContainer=document.getElementById(this.announcement_container_id),this.nonMenuFocus=this.svg,this.endChime=document.getElementById(this.end_chime_id)}textMode="verbose";brailleMode="on";sonifMode="on";reviewMode="off";layer=2;minX=0;maxX=0;minY=0;maxY=0;plotId="";chartType="";navigation=1;MAX_FREQUENCY=1e3;MIN_FREQUENCY=200;NULL_FREQUENCY=100;MAX_SPEED=2e3;MIN_SPEED=50;INTERVAL=50;vol=.5;MAX_VOL=30;autoPlayRate=250;colorSelected="#03C809";brailleDisplayLength=40;showRect=1;hasRect=1;duration=.3;outlierDuration=.06;autoPlayOutlierRate=50;autoPlayPointsRate=30;colorUnselected="#595959";isTracking=1;visualBraille=!1;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;debugLevel=3;canPlayEndChime=!1;manualData=!0;PrepChartHelperComponents(){document.getElementById(this.info_id)||document.getElementById(this.svg_container_id)&&document.getElementById(this.svg_container_id).insertAdjacentHTML("afterend",' \n\n'),document.getElementById(this.announcement_container_id)||document.getElementById(this.info_id)&&document.getElementById(this.info_id).insertAdjacentHTML("afterend",'\n
\n'),document.getElementById(this.braille_container_id)||document.getElementById(this.container_id)&&document.getElementById(this.container_id).insertAdjacentHTML("afterbegin",'\n \n
\n'),document.getElementById(this.svg_container_id)&&(document.querySelector("#"+this.svg_container_id+" > svg").setAttribute("role","application"),document.querySelector("#"+this.svg_container_id+" > svg").setAttribute("tabindex","0")),document.getElementById(this.end_chime_id)||document.getElementById(this.info_id)&&document.getElementById(this.info_id).insertAdjacentHTML("afterend",'')}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)}}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%",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"}}};GetString(t){return this.strings[this.language][this.knowledgeLevel][t]}}class Menu{constructor(){this.CreateMenu(),this.LoadDataFromLocalStorage()}menuHtml=`\n \n
\n `;CreateMenu(){document.querySelector("body").insertAdjacentHTML("beforeend",this.menuHtml)}Toggle(t){void 0===t&&(t=!!document.getElementById("menu").classList.contains("hidden")),t?(this.PopulateData(),document.getElementById("menu").classList.remove("hidden"),document.getElementById("modal_backdrop").classList.remove("hidden"),document.querySelector("#menu .close").focus()):(document.getElementById("menu").classList.add("hidden"),document.getElementById("modal_backdrop").classList.add("hidden"),constants.nonMenuFocus.focus())}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}SaveData(){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}SaveDataToLocalStorage(){let t={};t.vol=constants.vol,t.autoPlayRate=constants.autoPlayRate,t.brailleDisplayLength=constants.brailleDisplayLength,t.colorSelected=constants.colorSelected,t.MIN_FREQUENCY=constants.MIN_FREQUENCY,t.MAX_FREQUENCY=constants.MAX_FREQUENCY,t.keypressInterval=constants.keypressInterval,localStorage.setItem("settings_data",JSON.stringify(t))}LoadDataFromLocalStorage(){let t=JSON.parse(localStorage.getItem("settings_data"));t&&(constants.vol=t.vol,constants.autoPlayRate=t.autoPlayRate,constants.brailleDisplayLength=t.brailleDisplayLength,constants.colorSelected=t.colorSelected,constants.MIN_FREQUENCY=t.MIN_FREQUENCY,constants.MAX_FREQUENCY=t.MAX_FREQUENCY,constants.keypressInterval=t.keypressInterval)}}class Position{constructor(t,e,n=-1){this.x=t,this.y=e,this.z=n}}class Helper{static containsObject(t,e){for(let n=0;n0&&console.log("tracking data cleared"),this.DataSetup()}LogEvent(t){let e={};if(e.timestamp=Object.assign(t.timeStamp),e.time=Date().toString(),e.key=Object.assign(t.key),e.which=Object.assign(t.which),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.layer)||(e.layer=Object.assign(constants.layer)),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="",o="",s="",i="",a="",l="";if("barplot"==constants.chartType)this.isUndefinedOrNull(plot.columnLabels[position.x])||(n=plot.columnLabels[position.x]),this.isUndefinedOrNull(plot.plotLegend.x)||(s=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("heatmap"==constants.chartType)this.isUndefinedOrNull(plot.x_labels[position.x])||(n=plot.x_labels[position.x].trim()),this.isUndefinedOrNull(plot.y_labels[position.y])||(o=plot.y_labels[position.y].trim()),this.isUndefinedOrNull(plot.x_group_label)||(s=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("boxplot"==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)||(s=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)||(o=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])||(o=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"scatterplot"==constants.chartType&&(this.isUndefinedOrNull(plot.x_group_label)||(s=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])||(o=plot.y[position.x]),a=[n,o]);e.x_tickmark=Object.assign(n),e.y_tickmark=Object.assign(o),e.x_label=Object.assign(s),e.y_label=Object.assign(i),e.value=Object.assign(a),e.fill_value=Object.assign(l);let r=this.GetTrackerData();r.events.push(e),this.SaveTrackerData(r)}isUndefinedOrNull(t){try{return null==t}catch{return!0}}}class Review{constructor(){document.getElementById(constants.review_id)||document.getElementById(constants.info_id)&&document.getElementById(constants.info_id).insertAdjacentHTML("beforebegin",'
'),constants&&(constants.review_container=document.querySelector("#"+constants.review_id_container),constants.review=document.querySelector("#"+constants.review_id))}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 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(){let t=constants.duration,e=constants.vol,n=0,o=0,s=0,i=0;if("barplot"==constants.chartType)o=plot.plotData[position.x],n=position.x,s=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),i=this.SlideBetween(n,constants.minX,constants.maxX,-1,1);else if("boxplot"==constants.chartType){let t="vert"==constants.plotOrientation?position.x:position.y,e="vert"==constants.plotOrientation?position.y:position.x;o=position.z>-1&&Object.hasOwn(plot.plotData[t][e],"values")?plot.plotData[t][e].values[position.z]:"vert"==constants.plotOrientation?plot.plotData[t][e].y:plot.plotData[t][e].x,"blank"!=plot.plotData[t][e].type?"vert"==constants.plotOrientation?(s=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),i=this.SlideBetween(o,constants.minY,constants.maxY,-1,1)):(s=this.SlideBetween(o,constants.minX,constants.maxX,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),i=this.SlideBetween(o,constants.minX,constants.maxX,-1,1)):(s=constants.MIN_FREQUENCY,i=0)}else"heatmap"==constants.chartType?(o=plot.values[position.y][position.x],n=position.x,s=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),i=this.SlideBetween(n,constants.minX,constants.maxX,-1,1)):"scatterplot"==constants.chartType&&(1==constants.layer?(o=plot.y[position.x][position.z],e=1==plot.max_count?constants.vol:this.SlideBetween(plot.points_count[position.x][position.z],1,plot.max_count,constants.vol,constants.MAX_VOL),n=position.x,s=this.SlideBetween(o,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),i=this.SlideBetween(n,constants.minX,constants.maxX,-1,1)):2==constants.layer&&(o=plot.curvePoints[positionL1.x],n=positionL1.x,s=this.SlideBetween(o,plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),i=this.SlideBetween(n,constants.minX,constants.maxX,-1,1)));if(constants.debugLevel>5&&(console.log("will play tone at freq",s),"boxplot"==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)),"boxplot"==constants.chartType){let e="vert"==constants.plotOrientation?position.x:position.y,n="vert"==constants.plotOrientation?position.y:position.x,o=plot.plotData[e][n].type;"outlier"==o&&(t=constants.outlierDuration)}if(this.playOscillator(s,t,i,e,"sine"),"boxplot"==constants.chartType){let e="vert"==constants.plotOrientation?position.x:position.y,n="vert"==constants.plotOrientation?position.y:position.x;if("range"==plot.plotData[e][n].type){let e=s/2;this.playOscillator(e,t,i,constants.vol/4,"triangle")}}else"heatmap"==constants.chartType&&0==o&&this.PlayNull()}playOscillator(t,e,n,o=1,s="sine"){const i=this.audioContext.currentTime,a=this.audioContext.createOscillator();a.type=s,a.frequency.value=parseFloat(t),a.start();const l=this.audioContext.createGain();l.gain.setValueCurveAtTime([.5*o,1*o,.5*o,.5*o,.5*o,.1*o,1e-4*o],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}),p=this.audioContext.createStereoPanner();p.pan.value=n,a.connect(l),l.connect(p),p.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],o=1,s="sine"){let i=new Array(3*t.length).fill(.5*o);i.push(1e-4*o);const a=this.audioContext.currentTime,l=this.audioContext.createOscillator();l.type=s,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}),p=this.audioContext.createStereoPanner();p.pan.setValueCurveAtTime(n,a,e),l.connect(this.smoothGain),this.smoothGain.connect(p),p.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(){console.log("playing null");let t=constants.NULL_FREQUENCY,e=constants.duration,n=constants.vol,o="triangle";this.playOscillator(t,e,0,n,o),setTimeout((function(s){s.playOscillator(23*t/24,e,0,n,o)}),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,o,s){let i=(t-e)/(n-e)*(s-o)+o;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('Text mode: '+constants.textMode)}toggleBrailleMode(t){if("scatterplot"!=constants.chartType||1!=constants.layer){if(void 0===t&&(t="on"==constants.brailleMode?"off":"on"),"on"==t){if("boxplot"==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",constants.brailleInput.classList.remove("hidden"),constants.brailleInput.focus(),constants.brailleInput.setSelectionRange(position.x,position.x),this.SetBraille(plot),"heatmap"==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",constants.brailleInput.classList.add("hidden"),constants.review_container?constants.review_container.classList.contains("hidden")?constants.svg.focus():constants.review.focus():constants.svg.focus();this.announceText("Braille "+constants.brailleMode)}else this.announceText("Braille is not supported in point layer.")}toggleSonificationMode(){"scatterplot"==constants.chartType&&1==constants.layer?"off"==constants.sonifMode?(constants.sonifMode="sep",this.announceText(resources.GetString("son_sep"))):"sep"==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")))}toggleLayerMode(){1==constants.layer?(constants.layer=2,this.announceText("Layer 2: Smoothed line")):2==constants.layer&&(constants.layer=1,this.announceText("Layer 1: Point"))}announceText(t){constants.announceContainer.innerHTML=t}UpdateBraillePos(){if("barplot"==constants.chartType)constants.brailleInput.setSelectionRange(position.x,position.x);else if("heatmap"==constants.chartType){let t=position.y*(plot.num_cols+1)+position.x;constants.brailleInput.setSelectionRange(t,t)}else if("boxplot"==constants.chartType){let t="vert"==constants.plotOrientation?position.y:position.x,e=this.boxplotGridPlaceholders[t],n=!1,o=0;if(!constants.brailleData)throw"Braille data not set up, cannot move cursor in braille, sorry.";for(let t=0;t"+t.columnLabels[position.x]+" "+t.plotData[position.x]+"
\n":"verbose"==constants.textMode&&(e+=""+n+"
\n"));else if("heatmap"==constants.chartType)1==constants.navigation?(n+=t.x_group_label+" "+t.x_labels[position.x]+", "+t.y_group_label+" "+t.y_labels[position.y]+", "+t.box_label+" is ",constants.hasRect&&(n+=t.plotData[2][position.y][position.x])):(n+=t.y_group_label+" "+t.y_labels[position.y]+", "+t.x_group_label+" "+t.x_labels[position.x]+", "+t.box_label+" is ",constants.hasRect&&(n+=t.plotData[2][position.y][position.x])),"off"==constants.textMode||("terse"==constants.textMode?1==constants.navigation?e+=""+t.x_labels[position.x]+", "+t.plotData[2][position.y][position.x]+"
\n":e+=""+t.y_labels[position.y]+", "+t.plotData[2][position.y][position.x]+"
\n":"verbose"==constants.textMode&&(e+=""+n+"
\n"));else if("boxplot"==constants.chartType){let o=0,s=1,i=!1,a="vert"==constants.plotOrientation?position.x:position.y,l="vert"==constants.plotOrientation?position.y:position.x,r="",p="";"lower_outlier"!=t.plotData[a][l].label&&"upper_outlier"!=t.plotData[a][l].label||(i=!0),"outlier"==t.plotData[a][l].type?(o=t.plotData[a][l].values.join(", "),s=t.plotData[a][l].values.length>0?t.plotData[a][l].values.length:0):"blank"==t.plotData[a][l].type?(o="",i&&(s=0)):o="vert"==constants.plotOrientation?t.plotData[a][l].y:t.plotData[a][l].x,constants.navigation?t.x_group_label&&(p+=t.x_group_label):constants.navigation||t.y_group_label&&(p+=t.y_group_label),constants.navigation?t.x_labels[a]?(p+=" is ",r+=t.x_labels[a]+", ",p+=t.x_labels[a]+", "):p+=", ":constants.navigation||(t.y_labels[a]?(p+=" is ",r+=t.y_labels[a]+", ",p+=t.y_labels[a]+", "):p+=", "),i&&(r+=s+" ",p+=s+" "),p+=resources.GetString(t.plotData[a][l].label),1==s?p+=" is ":(p+="s ",s>1&&(p+=" are ")),(i||constants.navigation&&"horz"==constants.plotOrientation||!constants.navigation&&"vert"==constants.plotOrientation)&&(r+=resources.GetString(t.plotData[a][l].label),1!=s&&(r+="s"),r+=" "),"blank"!=t.plotData[a][l].type||i?(r+=o,p+=o):(r+="empty",p+="empty"),n=p,"verbose"==constants.textMode?e=""+p+"
\n":"terse"==constants.textMode&&(e=""+r+"
\n")}else"scatterplot"==constants.chartType&&(1==constants.layer?(n+=t.x_group_label+" "+t.x[position.x]+", "+t.y_group_label+" ["+t.y[position.x].join(", ")+"]","off"==constants.textMode||("terse"==constants.textMode?e+=""+t.x[position.x]+", ["+t.y[position.x].join(", ")+"]
\n":constants.textMode)):2==constants.layer&&(n+=t.x_group_label+" "+t.curveX[positionL1.x]+", "+t.y_group_label+" "+t.curvePoints[positionL1.x],"off"==constants.textMode||("terse"==constants.textMode?e+=""+t.curvePoints[positionL1.x]+"
\n":constants.textMode)),"verbose"==constants.textMode&&(e="
"+n+"
\n"));constants.infoDiv&&(constants.infoDiv.innerHTML=e),constants.review&&(e.length>0?constants.review.value=e.replace(/<[^>]*>?/gm,""):constants.review.value=n)}displayXLabel(t){let e="";"barplot"==constants.chartType?e=t.plotLegend.x:"heatmap"!=constants.chartType&&"boxplot"!=constants.chartType&&"scatterplot"!=constants.chartType||(e=t.x_group_label),"terse"==constants.textMode?constants.infoDiv.innerHTML=""+e+"
":"verbose"==constants.textMode&&(constants.infoDiv.innerHTML="
x label is "+e+"
")}displayYLabel(t){let e="";"barplot"==constants.chartType?e=t.plotLegend.y:"heatmap"!=constants.chartType&&"boxplot"!=constants.chartType&&"scatterplot"!=constants.chartType||(e=t.y_group_label),"terse"==constants.textMode?constants.infoDiv.innerHTML="
"+e+"
":"verbose"==constants.textMode&&(constants.infoDiv.innerHTML="
y label is "+e+"
")}displayTitle(t){"terse"==constants.textMode?""!=t.title?constants.infoDiv.innerHTML="
"+t.title+"
":constants.infoDiv.innerHTML="
Plot does not have a title.
":"verbose"==constants.textMode&&(""!=t.title?constants.infoDiv.innerHTML="
Title is "+t.title+"
":constants.infoDiv.innerHTML="
Plot does not have a title.
")}displayFill(t){"terse"==constants.textMode?"heatmap"==constants.chartType&&(constants.infoDiv.innerHTML="
"+t.box_label+"
"):"verbose"==constants.textMode&&"heatmap"==constants.chartType&&(constants.infoDiv.innerHTML="
Fill label is "+t.box_label+"
")}SetBraille(t){let e=[];if("heatmap"==constants.chartType){let n=(constants.maxY-constants.minY)/3,o=constants.minY+n,s=o+n;for(let n=0;n-1){let o=[],s=!0,i="vert"==constants.plotOrientation?position.x:position.y,a="vert"==constants.plotOrientation?"y":"x";for(let e=0;e0&&(p=t.plotData[i][e-1]);let c={};if(0==e){let e=0;for(let n=0;n0?e:0,c.length<0&&(c.length=0),c.type="blank",c.label="blank",o.push(c)}if("blank"==l.type);else if("outlier"==l.type){s||(c={},c.length=l.values[0]-p[a],c.type="blank",c.label="blank",o.push(c));for(var n=0;n0||"outlier"==o[t].type)?(o[t].numChars=1,h++):o[t].numChars=0,"min"==o[t].label&&o[t].length>0&&(l=t),"max"==o[t].label&&o[t].length>0&&(r=t),"25"==o[t].label&&(p=t),"75"==o[t].label&&(c=t),"50"==o[t].label&&(o[t].numChars=2,h++);let d=["25","75"];l>-1&&r>-1&&(d.push("min"),d.push("max"),o[l].length!=o[r].length&&(o[l].length>o[r].length?(o[l].numChars++,h++):(o[r].numChars++,h++))),o[p].length!=o[c].length&&(o[p].length>o[c].length?(o[p].numChars++,h++):(o[c].numChars++,h++));let u=constants.brailleDisplayLength-h,y=this.AllocateCharacters(o,u);for(let t=0;t5&&(console.log("plotData[i]",t.plotData[i]),console.log("brailleData",o));for(let t=0;t5&&console.log("braille:",constants.brailleInput.value),this.UpdateBraillePos()}CharLenImpact(t){return t.length/t.numChars}AllocateCharacters(t,e){let n=[],o=0;for(let e=0;et+e),0),a=e-i,l=t.length;for(;0!==a&&l>0;){for(let e=0;et+e),0),a=e-i,l--}if(0!==a){let e=[];for(let n=0;nn[t]-n[e]));let o=-1;a>0&&(o=1);let s=0,i=3*e.length;for(;a>0&&i>0;)n[e[s]]+=o,a+=-o,s+=1,s>=e.length&&(s=0),i+=-1}return n}}class BarChart{constructor(){"elements"in maidr?(this.bars=maidr.elements,constants.hasRect=1):(this.bars=document.querySelectorAll('g[id^="geom_rect"] > rect'),constants.hasRect=0),this.columnLabels=[];let t="",e="";"axes"in maidr?(maidr.axes.x&&maidr.axes.x.label&&(t=maidr.axes.x.label),maidr.axes.y&&maidr.axes.y.label&&(e=maidr.axes.y.label),maidr.axes.x&&maidr.axes.x.format&&(this.columnLabels=maidr.axes.x.format),maidr.axes.y&&maidr.axes.y.format&&(this.columnLabels=maidr.axes.y.format)):(document.querySelector('g[id^="xlab"] tspan')&&(t=document.querySelector('g[id^="xlab"] tspan').innerHTML),document.querySelector('g[id^="ylab"] tspan')&&(e=document.querySelector('g[id^="ylab"] tspan').innerHTML),this.columnLabels=this.ParseInnerHTML(document.querySelectorAll('g:not([id^="xlab"]):not([id^="ylab"]) > g > g > g > text[text-anchor="middle"]'))),this.plotLegend={x:t,y:e},this.title="","title"in maidr?this.title=maidr.title:document.querySelector('g[id^="plot.title..titleGrob"] tspan')&&(this.title=document.querySelector('g[id^="plot.title..titleGrob"] tspan').innerHTML,this.title=this.title.replace("\n","").replace(/ +(?= )/g,"")),"array"==typeof maidr?this.plotData=maidr:"object"==typeof maidr&&"data"in maidr&&(this.plotData=maidr.data),this.SetMaxMin(),this.autoplay=null}SetMaxMin(){for(let t=0;tconstants.maxY&&(constants.maxY=this.plotData[t]),this.plotData[t] g[id^="geom_boxplot.gTree"]')&&(constants.plotId=document.querySelector('g[id^="panel"] > g[id^="geom_boxplot.gTree"]').getAttribute("id")),constants.manualData){let t="";"undefined"!=typeof maidr&&void 0!==maidr.title?t=maidr.title:document.querySelector('tspan[dy="9.45"]')&&(t=document.querySelector('tspan[dy="9.45"]').innerHTML,t=t.replace("\n","").replace(/ +(?= )/g,"")),this.title=void 0!==t&&null!=typeof t?t:"","undefined"!=typeof maidr?this.x_group_label=maidr.x_group_label:this.x_group_label=document.querySelector('text:not([transform^="rotate"]) > tspan[dy="7.88"]').innerHTML,"undefined"!=typeof maidr?this.y_group_label=maidr.y_group_label:this.y_group_label=document.querySelector('text[transform^="rotate"] > tspan[dy="7.88"]').innerHTML;let e=[];if("undefined"!=typeof maidr)this.x_labels=maidr.x_labels,this.y_labels=maidr.y_labels;else{let t="3.15";"vert"==constants.plotOrientation&&(t="6.3");let n=document.querySelectorAll('tspan[dy="'+t+'"]');for(let t=0;tconstants.maxY&&(constants.maxY=n.yMax):n.y>constants.maxY&&(constants.maxY=n.y)),n.hasOwnProperty("x")&&(n.xconstants.maxX&&(constants.maxX=n.x))}}else{constants.minX=0,constants.maxX=0;for(let t=0;tconstants.maxX&&(constants.maxX=n.xMax):n.x>constants.maxX&&(constants.maxX=n.x)),n.hasOwnProperty("y")&&(n.yconstants.maxY&&(constants.maxY=n.y))}}}GetData(){let t=[],e=document.getElementById(constants.plotId).children;for(let n=0;nconstants.maxY&&(constants.maxY=e.y),s.push(e)}}}if(s.sort((function(t,e){return"vert"==constants.plotOrientation?t.y-e.y:t.x-e.x})),"horz"==constants.plotOrientation){let t=[];for(let e=0;e0&&s[e-1].x==s[e].x?"whisker"==s[e-1].type&&(t.splice(-1,1),t.push(s[e])):t.push(s[e]);s=t}t.push(s)}t.sort((function(t,e){return"vert"==constants.plotOrientation?t[0].x-e[0].x:t[0].y-e[0].y}));for(let e=0;e0){let n=[];for(let i=0;i0&&(t[e][s+i-o.length].type="delete");"vert"==constants.plotOrientation?(t[e][s-o.length].y=o[0].y,t[e][s-o.length].yMax=o[o.length-1].y):(t[e][s-o.length].x=o[0].x,t[e][s-o.length].xMax=o[o.length-1].x),t[e][s-o.length].values=n,o=[]}}else o.push(n[s])}}let n=[];for(let e=0;e0?resources.GetString("upper_outlier"):resources.GetString("lower_outlier"):"whisker"==s.type?t[e][o].label=n>0?resources.GetString("max"):resources.GetString("min"):"range"==s.type&&(0==n?t[e][o].label=resources.GetString("25"):1==n?t[e][o].label=resources.GetString("50"):2==n&&(t[e][o].label=resources.GetString("75")),n++)}}let o=this.GetAllSegmentTypes();for(let e=0;e1&&console.log("plotData:",t),t}GetPlotBounds(t){let e=[],n=this.GetAllSegmentTypes(),o=/(?:\d+(?:\.\d*)?|\.\d+)/g,s=[],i=document.getElementById(constants.plotId).children;for(let t=0;ta.bottom&&(o=!0),e.topa.right&&(l=!0)),o?(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(s[t],"outlier")){let e=s[t].outlier.children,o=null,l=null;for(let t=0;to.bottom&&(o.bottom=n.bottom)):o=this.convertBoundingClientRectToObj(n):l?(n.yl.bottom&&(l.bottom=n.bottom)):l=this.convertBoundingClientRectToObj(n):n.x>a.x?o?(n.xo.right&&(o.right=n.right)):o=this.convertBoundingClientRectToObj(n):l?(n.xl.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"),o?(o.height=o.bottom-o.top,o.width=o.right-o.left,i[6]=this.convertBoundingClientRectToObj(o),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(){return[resources.GetString("lower_outlier"),resources.GetString("min"),resources.GetString("25"),resources.GetString("50"),resources.GetString("75"),resources.GetString("max"),resources.GetString("upper_outlier")]}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,o=[];if("range"==e){let e=t.children[0].getAttribute("points").match(n);o.push(e[0],e[1]),e[0]!=e[2]&&o.push(e[2],e[3])}else if("outlier"==e)o.push(t.getAttribute("x"),t.getAttribute("y"));else{let e=t.getAttribute("points").match(n);"vert"==constants.plotOrientation?e[1]!=e[3]&&o.push(e[0],e[1],e[2],e[3]):e[0]!=e[2]&&o.push(e[0],e[1],e[2],e[3])}return o}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(t){let e=null,n=null;constants.outlierInterval&&clearInterval(constants.outlierInterval),"vert"==constants.plotOrientation?(e=position.x,n=position.y):(e=position.y,n=position.x),"blank"==plot.plotData[e][n].type?t.PlayNull():"outlier"!=plot.plotData[e][n].type?t.playTone():(position.z=0,constants.outlierInterval=setInterval((function(){t.playTone(),position.z+=1,Object.hasOwn(plot.plotData[e][n],"values")?position.z+1>plot.plotData[e][n].values.length&&(clearInterval(constants.outlierInterval),position.z=-1):(clearInterval(constants.outlierInterval),position.z=-1)}),constants.autoPlayOutlierRate))}}class BoxplotRect{rectPadding=15;rectStrokeWidth=4;constructor(){this.x1=0,this.width=0,this.y1=0,this.height=0,this.svgOffsetLeft=constants.svg.getBoundingClientRect().left,this.svgOffsetTop=constants.svg.getBoundingClientRect().top}UpdateRect(){document.getElementById("highlight_rect")&&document.getElementById("highlight_rect").remove();let t=position.x,e=position.y;if("vert"==constants.plotOrientation||(t=position.y,e=position.x),"vert"==constants.plotOrientation&&position.y>-1||"horz"==constants.plotOrientation&&position.x>-1){let n=plot.plotBounds[t][e];"blank"!=n.type&&(this.x1=n.left-this.rectPadding-this.svgOffsetLeft,this.width=n.width+2*this.rectPadding,this.y1=n.top-this.rectPadding-this.svgOffsetTop,this.height=n.height+2*this.rectPadding,constants.debugLevel>5&&(console.log("Point",plot.plotData[t][e].label,"bottom:",n.bottom,"top:",n.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.svg.appendChild(t)}}class HeatMap{constructor(){"elements"in maidr?(this.plots=maidr.elements,constants.hasRect=1):(this.plots=document.querySelectorAll('g[id^="geom_rect"] > rect'),constants.hasRect=0),this.group_labels=this.getGroupLabels(),this.x_labels=this.getXLabels(),this.y_labels=this.getYLabels(),this.title=this.getTitle(),this.plotData=this.getHeatMapData(),this.updateConstants(),this.x_coord=this.plotData[0],this.y_coord=this.plotData[1],this.values=this.plotData[2],this.num_rows=this.plotData[3],this.num_cols=this.plotData[4],this.x_group_label=this.group_labels[0].trim(),this.y_group_label=this.group_labels[1].trim(),this.box_label=this.group_labels[2].trim()}getHeatMapData(){let t=[],e=[],n=[],o=[];if(constants.hasRect){for(let n=0;nArray(i).fill(0)));let a=3*Math.pow(255,2),h=0;for(var r=0;rh&&(h=s)}}return[n,o,l,s,i]}updateConstants(){constants.minX=0,constants.maxX=this.plotData[4],constants.minY=this.plotData[2][0][0],constants.maxY=this.plotData[2][0][0];for(let t=0;tconstants.maxY&&(constants.maxY=this.plotData[2][t][e])}getRGBNorm(t){return this.plots[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="",o="";return e="title"in maidr?maidr.title:document.querySelector('g[id^="guide.title"] text > tspan').innerHTML,"axes"in maidr?("x"in maidr.axes&&"label"in maidr.axes.x&&(n=maidr.axes.x.label),"y"in maidr.axes&&"label"in maidr.axes.y&&(o=maidr.axes.y.label)):(n=document.querySelector('g[id^="xlab"] text > tspan').innerHTML,o=document.querySelector('g[id^="ylab"] text > tspan').innerHTML),t=[n,o,e],t}getXLabels(){if(!("axes"in maidr)){let t;t=document.querySelectorAll('tspan[dy="10"]');let e=[];for(let n=0;n tspan').innerHTML;return constants.manualData&&void 0!==t&&null!=typeof t?t:""}}}class HeatMapRect{constructor(){constants.hasRect&&(this.x=plot.x_coord[0],this.y=plot.y_coord[0],this.rectStrokeWidth=4,this.height=Math.abs(plot.y_coord[1]-plot.y_coord[0]))}UpdateRect(){this.x=plot.x_coord[position.x],this.y=plot.y_coord[position.y]}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",constants.svg.getBoundingClientRect().height-this.height-this.y),t.setAttribute("width",this.height),t.setAttribute("height",this.height),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.rectStrokeWidth),t.setAttribute("fill","none"),constants.svg.appendChild(t)}}document.addEventListener("DOMContentLoaded",(function(t){}));class ScatterPlot{constructor(){"point_elements"in maidr?this.plotPoints=maidr.point_elements:this.plotPoints=document.querySelectorAll("#"+constants.plotId.replaceAll(".","\\.")+" > use"),this.svgPointsX=this.GetSvgPointCoords()[0],this.svgPointsY=this.GetSvgPointCoords()[1],this.x=this.GetPointValues()[0],this.y=this.GetPointValues()[1],this.points_count=this.GetPointValues()[2],this.max_count=this.GetPointValues()[3],constants.manualData?this.plotLine=maidr.smooth_elements:this.plotLine=document.querySelectorAll("#"+"GRID.polyline.13.1".replaceAll(".","\\.")+" > polyline")[0],this.svgLineX=this.GetSvgLineCoords()[0],this.svgLineY=this.GetSvgLineCoords()[1],this.curveX=this.GetSmoothCurvePoints()[0],this.curvePoints=this.GetSmoothCurvePoints()[1],this.curveMinY=Math.min(...this.curvePoints),this.curveMaxY=Math.max(...this.curvePoints),this.gradient=this.GetGradient(),this.x_group_label="",this.y_group_label="",this.title="","undefined"!=typeof maidr&&("axes"in maidr&&("x"in maidr.axes&&(this.x_group_label=maidr.axes.x.label),"y"in maidr.axes&&(this.y_group_label=maidr.axes.y.label)),"title"in maidr&&(this.title=maidr.title))}GetSvgPointCoords(){let t=new Map;for(let e=0;eMath.max(...t))));return[o,s,i,a]}PlayTones(t){constants.sepPlayId&&constants.KillSepPlay(),1==constants.layer?(position.z=0,constants.sepPlayId=setInterval((function(){t.playTone(),position.z+=1,position.z+1>plot.y[position.x].length&&(constants.KillSepPlay(),position.z=-1)}),"sep"==constants.sonifMode?constants.autoPlayPointsRate:0)):2==constants.layer&&t.playTone()}GetSvgLineCoords(){let t=this.plotLine.getAttribute("points").split(" "),e=[],n=[];for(let o=0;o5&&setTimeout((function(){constants.svg.focus()}),100),constants.svg_container&&constants.svg_container.addEventListener("keydown",(function(t){72==t.which&&menu.Toggle(!0)}));let t=document.querySelectorAll("#close_menu, #menu .close");for(let e=0;e svg, #"+constants.braille_input_id);for(let t=0;tt.target.value.length-2||((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,i("right",position.x,plot.bars.length)):(position.x=plot.bars.length-1,n=!0,o=e()):t.altKey&&t.shiftKey&&position.x!=plot.bars.length-1?(p=position.x,i("reverse-right",plot.bars.length,position.x)):(position.x+=1,n=!0,o=e()))):37==t.which?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,i("left",position.x,-1)):(position.x=0,n=!0,o=e()):t.altKey&&t.shiftKey&&0!=position.x?(p=position.x,i("reverse-left",-1,position.x)):(position.x+=-1,n=!0,o=e())):t.preventDefault()),constants.brailleInput.addEventListener("focusout",(function(t){display.toggleBrailleMode("off")})),n&&!o&&s(),o&&l.playEnd()}));let d=[constants.svg_container,constants.brailleInput];for(let u=0;uconstants.keypressInterval)&&display.toggleTextMode()}83==t.which&&display.toggleSonificationMode(),32===t.which&&n()}));function e(){let t=!1;return constants.hasRect?(position.x<0&&(position.x=0,t=!0),position.x>plot.bars.length-1&&(position.x=plot.bars.length-1,t=!0),t):t}function n(){constants.showDisplay&&display.displayValues(plot),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&l.playTone()}function o(){constants.showDisplayInAutoplay&&display.displayValues(plot),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&l.playTone(),"off"!=constants.brailleMode&&display.UpdateBraillePos(plot)}function s(){constants.showDisplayInBraille&&display.displayValues(plot),constants.showRect&&constants.hasRect&&plot.Select(),"off"!=constants.sonifMode&&l.playTone(),display.UpdateBraillePos(plot)}function i(t,n,s){r=t;let i=1;"left"!=t&&"reverse-right"!=t||(i=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=n),constants.autoplayId=setInterval((function(){position.x+=i,position.x<0||plot.bars.length-10?("vert"==constants.plotOrientation?f=position.y:x=position.x,i("reverse-left",0,position.x)):(position.x+=-1,o=!0,s=e()),constants.navigation=1),38===t.which){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?i("up",position.y,plot.plotData[position.x].length):i("up",position.y,plot.plotData.length):("vert"==constants.plotOrientation?position.y=plot.plotData[position.x].length-1:position.y=plot.plotData.length-1,o=!0,s=e()):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&position.y!=plot.plotData[position.x].length-1?(f=position.y,i("reverse-up",plot.plotData[position.x].length-1,position.y)):(position.y+=1,o=!0,s=e()):t.altKey&&t.shiftKey&&position.y!=plot.plotData.length-1?(x=position.x,i("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,o=!0,s=e()),constants.navigation=0}if(40===t.which){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?i("down",position.y,-1):(position.y=0,o=!0,s=e()):t.altKey&&t.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?f=position.y:x=position.x,i("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.plotData[position.x].length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,o=!0,s=e()),constants.navigation=0}o&&!s&&n(),s&&g.playEnd()})),constants.brailleInput.addEventListener("keydown",(function(t){let n=!1,o=!1,a=!1;if(9==t.which);else if(39==t.which)t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?i("right",position.x,plot.plotData.length-1):i("right",position.x,plot.plotData[position.y].length):("vert"==constants.plotOrientation?position.x=plot.plotData.length-1:position.x=plot.plotData[position.y].length-1,n=!0,a=e()):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&plot.plotData.length-1!=position.x?(f=position.y,i("reverse-right",plot.plotData.length-1,position.x)):(-1==position.x&&position.y==plot.plotData[position.x].length&&(position.y-=1),position.x+=1,n=!0,a=e()):t.altKey&&t.shiftKey&&plot.plotData[position.y].length-1!=position.x?(x=position.x,i("reverse-right",plot.plotData[position.y].length-1,position.x)):(-1==position.x&&position.y==plot.plotData.length&&(position.y-=1),position.x+=1,n=!0,a=e()),o=!0,constants.navigation=1;else if(37==t.which)t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?i("left",position.x,-1):(position.x=0,n=!0,a=e()):t.altKey&&t.shiftKey&&position.x>0?("vert"==constants.plotOrientation?f=position.y:x=position.x,i("reverse-left",0,position.x)):(position.x+=-1,n=!0,a=e()),o=!0,constants.navigation=1;else if(38===t.which){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?"vert"==constants.plotOrientation?(position.x<0&&(position.x=0),i("up",position.y,plot.plotData[position.x].length)):i("up",position.y,plot.plotData.length):"vert"==constants.plotOrientation?(position.y=plot.plotData[position.x].length-1,n=!0):(position.y=plot.plotData.length-1,n=!0):"vert"==constants.plotOrientation?t.altKey&&t.shiftKey&&position.y!=plot.plotData[position.x].length-1?(lasY=position.y,i("reverse-up",plot.plotData[position.x].length-1,position.y)):(position.y+=1,n=!0,a=e()):t.altKey&&t.shiftKey&&position.y!=plot.plotData.length-1?(x=position.x,i("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,n=!0,a=e()),"vert"==constants.plotOrientation||(o=!0),constants.navigation=0}else if(40===t.which){position.y;(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?i("down",position.y,-1):(position.y=0,n=!0,a=e()):t.altKey&&t.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?f=position.y:x=position.x,i("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.plotData[position.x].length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,n=!0,a=e()),constants.navigation=0,"vert"==constants.plotOrientation||(o=!0),constants.navigation=0}else t.preventDefault();n&&!a&&(o&&display.SetBraille(plot),setTimeout(s,50)),a&&g.playEnd(),constants.brailleInput.addEventListener("focusout",(function(t){display.toggleBrailleMode("off")}))}));let w=[constants.svg_container,constants.brailleInput];for(let _=0;_constants.keypressInterval)&&display.toggleTextMode()}83==t.which&&display.toggleSonificationMode(),32===t.which&&n()}));function n(){constants.showDisplay&&display.displayValues(plot),constants.showRect&&constants.hasRect&&y.UpdateRect(),"off"!=constants.sonifMode&&plot.PlayTones(g)}function o(){constants.showDisplayInAutoplay&&display.displayValues(plot),constants.showRect&&constants.hasRect&&y.UpdateRect(),"off"!=constants.sonifMode&&plot.PlayTones(g),"off"!=constants.brailleMode&&display.UpdateBraillePos(plot)}function s(){constants.showDisplayInBraille&&display.displayValues(plot),constants.showRect&&constants.hasRect&&y.UpdateRect(),"off"!=constants.sonifMode&&plot.PlayTones(g),display.UpdateBraillePos(plot)}function e(){let t=!1;return"vert"==constants.plotOrientation?(position.y<0&&(position.y=0,t=!0),position.x<0&&(position.x=0,t=!0),position.x>plot.plotData.length-1&&(position.x=plot.plotData.length-1,t=!0),position.y>plot.plotData[position.x].length-1&&(position.y=plot.plotData[position.x].length-1,t=!0)):(position.x<0&&(position.x=0,t=!0),position.y<0&&(position.y=0,t=!0),position.y>plot.plotData.length-1&&(position.y=plot.plotData.length-1,t=!0),position.x>plot.plotData[position.y].length-1&&(position.x=plot.plotData[position.y].length-1,t=!0)),t}function i(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),o(),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.plotData[position.x].length-2||"horz"==constants.plotOrientation&&"up"==t&&position.y>plot.plotData.length-2||"horz"==constants.plotOrientation&&"right"==t&&position.x>plot.plotData[position.y].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,o()),constants.debugLevel>5&&console.log("autoplay pos",position)}),constants.autoPlayRate)}document.addEventListener("keydown",(function(t){if((constants.isMac?t.metaKey:t.ctrlKey)&&(36==t.which?(position.x=0,position.y=plot.plotData.length-1,s()):35==t.which&&(position.x=plot.plotData[0].length-1,position.y=0,s())),b)if(88==t.which){let t=window.performance.now()-v;b&&t<=constants.keypressInterval&&display.displayXLabel(plot),b=!1}else if(89==t.which){let t=window.performance.now()-v;b&&t<=constants.keypressInterval&&display.displayYLabel(plot),b=!1}else if(84==t.which){let t=window.performance.now()-v;b&&t<=constants.keypressInterval&&display.displayTitle(plot),b=!1}else 76==t.which?(v=window.performance.now(),b=!0):b=!1;76==t.which&&(v=window.performance.now(),b=!0),190==t.which&&(constants.SpeedUp(),null!=constants.autoplayId&&(constants.KillAutoplay(),"reverse-left"==m?"vert"==constants.plotOrientation?i("right",position.y,f):i("right",position.x,x):"reverse-right"==m?"vert"==constants.plotOrientation?i("left",position.y,f):i("left",position.x,x):"reverse-up"==m?"vert"==constants.plotOrientation?i("down",position.y,f):i("down",position.x,x):"reverse-down"==m?"vert"==constants.plotOrientation?i("up",position.y,f):i("up",position.x,x):"vert"==constants.plotOrientation?i(m,position.y,f):i(m,position.x,x))),188==t.which&&(constants.SpeedDown(),null!=constants.autoplayId&&(constants.KillAutoplay(),"reverse-left"==m?"vert"==constants.plotOrientation?i("right",position.y,f):i("right",position.x,x):"reverse-right"==m?"vert"==constants.plotOrientation?i("left",position.y,f):i("left",position.x,x):"reverse-up"==m?"vert"==constants.plotOrientation?i("down",position.y,f):i("down",position.x,x):"reverse-down"==m?"vert"==constants.plotOrientation?i("up",position.y,f):i("up",position.x,x):"vert"==constants.plotOrientation?i(m,position.y,f):i(m,position.x,x)))}))}else if("heatmap"==constants.chartType){constants.plotId="geom_rect.rect.2.1",window.position=new Position(-1,-1),window.plot=new HeatMap,constants.chartType="heatmap";let M=new HeatMapRect,D=new Audio,S="",L=0,O=0,E=!1;constants.svg_container.addEventListener("keydown",(function(t){let o=!1,s=!1;39===t.which&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,i("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,o=!0):t.altKey&&t.shiftKey&&position.x!=plot.num_cols-1?(L=position.x,i("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,o=!0,s=e()),constants.navigation=1),37===t.which&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,i("left",position.x,-1)):(position.x=0,o=!0):t.altKey&&t.shiftKey&&0!=position.x?(L=position.x,i("reverse-left",-1,position.x)):(position.x-=1,o=!0,s=e()),constants.navigation=1),38===t.which&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.y+=1,i("up",position.y,-1)):(position.y=0,o=!0):t.altKey&&t.shiftKey&&0!=position.y?(L=position.x,i("reverse-up",-1,position.y)):(position.y-=1,o=!0,s=e()),constants.navigation=0),40===t.which&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.y-=1,i("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,o=!0):t.altKey&&t.shiftKey&&position.y!=plot.num_rows-1?(L=position.x,i("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,o=!0,s=e()),constants.navigation=0),o&&!s&&n(),s&&D.playEnd()})),constants.brailleInput.addEventListener("keydown",(function(t){let n=!1,o=!1;if(9==t.which);else if(39==t.which)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,i("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,n=!0)):t.altKey&&t.shiftKey&&position.x!=plot.num_cols-1?(L=position.x,i("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,n=!0,o=e());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=1}else if(37==t.which)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,i("left",position.x,-1)):(position.x=0,n=!0):t.altKey&&t.shiftKey&&0!=position.x?(L=position.x,i("reverse-left",-1,position.x)):(position.x+=-1,n=!0,o=e());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=1}else if(40==t.which)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,i("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,n=!0)):t.altKey&&t.shiftKey&&position.y!=plot.num_rows-1?(L=position.x,i("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,n=!0,o=e());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=0}else if(38==t.which)if(t.target.selectionStart-plot.num_cols-1<0)t.preventDefault();else{(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.y+=1,i("up",position.y,-1)):(position.y=0,n=!0):t.altKey&&t.shiftKey&&0!=position.y?(L=position.x,i("reverse-up",-1,position.y)):(position.y+=-1,n=!0,o=e());let s=position.y*(plot.num_cols+1)+position.x;t.target.setSelectionRange(s,s),t.preventDefault(),constants.navigation=0}else t.preventDefault();constants.brailleInput.addEventListener("focusout",(function(t){display.toggleBrailleMode("off")})),n&&!o&&s(),o&&D.playEnd()}));let I=[constants.svg_container,constants.brailleInput];for(let T=0;Tconstants.keypressInterval)&&display.toggleTextMode()}83==t.which&&display.toggleSonificationMode(),32===t.which&&n()}));function e(){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 n(){constants.showDisplay&&display.displayValues(plot),constants.showRect&&constants.hasRect&&M.UpdateRectDisplay(),"off"!=constants.sonifMode&&D.playTone()}function o(){constants.showDisplayInAutoplay&&display.displayValues(plot),constants.showRect&&constants.hasRect&&M.UpdateRectDisplay(),"off"!=constants.sonifMode&&D.playTone(),"off"!=constants.brailleMode&&display.UpdateBraillePos(plot)}function s(){constants.showDisplayInBraille&&display.displayValues(plot),constants.showRect&&constants.hasRect&&M.UpdateRectDisplay(),"off"!=constants.sonifMode&&D.playTone(),display.UpdateBraillePos(plot)}function i(t,n,s){S=t;let i=1;"left"!=t&&"up"!=t&&"reverse-right"!=t&&"reverse-down"!=t||(i=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=n:"reverse-up"!=t&&"reverse-down"!=t||(position.y=n),constants.autoplayId=setInterval((function(){"left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?(position.x+=i,position.x<0||plot.num_cols-1t.target.value.length-2?t.preventDefault():(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(positionL1.x-=1,i("outward_right",positionL1.x,plot.curvePoints.length)):(positionL1.x=plot.curvePoints.length-1,n=!0,o=e()):t.altKey&&t.shiftKey&&positionL1.x!=plot.curvePoints.length-1?(B=positionL1.x,i("inward_right",plot.curvePoints.length,positionL1.x)):(positionL1.x+=1,n=!0,o=e())):37==t.which?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(positionL1.x+=1,i("outward_left",positionL1.x,-1)):(positionL1.x=0,n=!0,o=e()):t.altKey&&t.shiftKey&&0!=positionL1.x?i("inward_left",-1,positionL1.x):(positionL1.x-=1,n=!0,o=e())):t.preventDefault())):t.preventDefault()),constants.brailleInput.addEventListener("focusout",(function(t){display.toggleBrailleMode("off")})),B=positionL1.x,n&&!o&&s(),o&&P.playEnd()}));let U=[constants.svg_container,constants.brailleInput];for(let Y=0;Yconstants.keypressInterval)&&display.toggleTextMode()}83==t.which&&display.toggleSonificationMode(),34==t.which&&2==constants.layer&&"off"==constants.brailleMode&&(B=positionL1.x,display.toggleLayerMode()),33==t.which&&1==constants.layer&&"off"==constants.brailleMode&&display.toggleLayerMode(),32===t.which&&n()}));function e(){let t=!1;return 1==constants.layer?(position.x<0&&(position.x=0,t=!0),position.x>plot.x.length-1&&(position.x=plot.x.length-1,t=!0)):2==constants.layer&&(positionL1.x<0&&(positionL1.x=0,t=!0),positionL1.x>plot.curvePoints.length-1&&(positionL1.x=plot.curvePoints.length-1,t=!0)),t}function n(){constants.showDisplay&&display.displayValues(plot),constants.showRect&&K.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(P)}function o(){constants.showDisplayInAutoplay&&display.displayValues(plot),constants.showRect&&(1==constants.layer?K.UpdatePointDisplay():R.UpdatePointDisplay()),"off"!=constants.sonifMode&&plot.PlayTones(P),"off"!=constants.brailleMode&&display.UpdateBraillePos(plot)}function s(){constants.showDisplayInBraille&&display.displayValues(plot),constants.showRect&&R.UpdatePointDisplay(),"off"!=constants.sonifMode&&plot.PlayTones(P),display.UpdateBraillePos(plot)}function i(t,n,s){A=t;let i=1;"outward_left"!=t&&"inward_right"!=t||(i=-1),constants.autoplayId&&constants.KillAutoplay(),constants.isSmoothAutoplay&&P.KillSmooth(),"inward_left"!=t&&"inward_right"!=t||(position.x=n,position.L1x=n),1==constants.layer?constants.autoplayId=setInterval((function(){position.x+=i,position.x<0||position.x>plot.y.length-1?(constants.KillAutoplay(),e()):position.x==s?(constants.KillAutoplay(),o()):o()}),constants.autoPlayRate):2==constants.layer&&(constants.autoplayId=setInterval((function(){positionL1.x+=i,positionL1.x<0||positionL1.x>plot.curvePoints.length-1?(constants.KillAutoplay(),e()):positionL1.x==s?(constants.KillAutoplay(),o()):o()}),constants.autoPlayRate))}function a(t){A=t;let e=[],n=[],o=P.SlideBetween(positionL1.x,0,plot.curvePoints.length-1,-1,1),s=positionL1.x<0?0:positionL1.x,i=0;if("outward_right"==t){for(let t=s;t=0;t--)e.push(P.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[o,-1],i=Math.abs(s)/plot.curvePoints.length*3}else if("inward_right"==t){for(let t=plot.curvePoints.length-1;t>=s;t--)e.push(P.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[1,o],i=Math.abs(plot.curvePoints.length-s)/plot.curvePoints.length*3}else if("inward_left"==t){for(let t=0;t<=s;t++)e.push(P.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[-1,o],i=Math.abs(s)/plot.curvePoints.length*3}constants.isSmoothAutoplay&&P.KillSmooth(),P.playSmooth(e,i,n,constants.vol,"sine")}document.addEventListener("keydown",(function(t){if((constants.isMac?t.metaKey:t.ctrlKey)&&(36==t.which?1==constants.layer?(position.x=0,n(),constants.brailleInput.setSelectionRange(0,0)):2==constants.layer&&(positionL1.x=0,s()):35==t.which&&(1==constants.layer?(position.x=plot.y.length-1,n(),constants.brailleInput.setSelectionRange(plot.curvePoints.length-1,plot.curvePoints.length-1)):2==constants.layer&&(positionL1.x=plot.curvePoints.length-1,s())),t.shiftKey||P.KillSmooth()),k)if(88==t.which){let t=window.performance.now()-N;k&&t<=constants.keypressInterval&&display.displayXLabel(plot),k=!1}else if(89==t.which){let t=window.performance.now()-N;k&&t<=constants.keypressInterval&&display.displayYLabel(plot),k=!1}else if(84==t.which){let t=window.performance.now()-N;k&&t<=constants.keypressInterval&&display.displayTitle(plot),k=!1}else 76==t.which?(N=window.performance.now(),k=!0):k=!1;76==t.which&&(N=window.performance.now(),k=!0),190==t.which&&(constants.SpeedUp(),null!=constants.autoplayId&&(constants.KillAutoplay(),P.KillSmooth(),"inward_left"==A?1==constants.layer?i("outward_right",position.x,C):2==constants.layer&&i("outward_right",positionL1.x,B):"inward_right"==A?1==constants.layer?i("outward_left",position.x,C):2==constants.layer&&i("outward_left",positionL1.x,B):1==constants.layer?i(A,position.x,C):2==constants.layer&&i(A,positionL1.x,B))),188==t.which&&(constants.SpeedDown(),null!=constants.autoplayId&&(constants.KillAutoplay(),P.KillSmooth(),"inward_left"==A?1==constants.layer?i("outward_right",position.x,C):2==constants.layer&&i("outward_right",positionL1.x,B):"inward_right"==A?1==constants.layer?i("outward_left",position.x,C):2==constants.layer&&i("outward_left",positionL1.x,B):1==constants.layer?i(A,position.x,C):2==constants.layer&&i(A,positionL1.x,B)))}))}"on"==constants.brailleMode&&display.toggleBrailleMode("on")}));
\ No newline at end of file
diff --git a/maidr/example/js/styles.min.css b/maidr/example/js/styles.min.css
deleted file mode 100644
index bc42262..0000000
--- a/maidr/example/js/styles.min.css
+++ /dev/null
@@ -1,207 +0,0 @@
-*,
-::after,
-::before {
- box-sizing: border-box;
-}
-.sr-only {
- clip: rect(1px, 1px, 1px, 1px);
- clip-path: inset(50%);
- height: 1px;
- width: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
-}
-.sr-only-focusable {
- position: static;
- width: auto;
- height: auto;
- overflow: visible;
- clip: auto;
- white-space: normal;
- -webkit-clip-path: none;
- clip-path: none;
-}
-#skip a {
- position: absolute;
- left: -10000px;
- top: auto;
- width: 1px;
- height: 1px;
- overflow: hidden;
-}
-#skip a:focus {
- position: static;
- width: auto;
- height: auto;
-}
-.hidden {
- display: none;
- opacity: 0;
-}
-.braille-input {
- font-size: 200%;
- border: none;
- resize: none;
- padding: 5px;
-}
-.modal {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 1072;
- overflow-x: hidden;
- overflow-y: auto;
- opacity: 1;
- transition: opacity 0.15s linear;
-}
-.modal-dialog {
- position: relative;
- width: auto;
- margin: 0.5rem;
-}
-@media (min-width: 900px) {
- .modal-dialog {
- max-width: 800px;
- margin: 1.75rem auto;
- }
-}
-@media (min-width: 576px) {
- .modal-dialog {
- max-width: 500px;
- margin: 1.75rem auto;
- }
-}
-.close:not(:disabled):not(.disabled) {
- cursor: pointer;
-}
-.modal-header .close {
- padding: 1rem;
- margin: -1rem -1rem -1rem auto;
- font-size: 2rem;
-}
-button.close {
- padding: 0;
- background-color: transparent;
- border: 0;
- -webkit-appearance: none;
-}
-.close {
- float: right;
- font-size: 1.5rem;
- font-weight: 700;
- line-height: 1;
- color: #000;
- text-shadow: 0 1px 0 #fff;
- opacity: 0.5;
-}
-button,
-select {
- text-transform: none;
-}
-.modal-title {
- margin-bottom: 0;
- line-height: 1.5;
-}
-h5.modal-title {
- font-size: 1.25rem;
- border-bottom: 1px solid #dee2e6;
-}
-h4.modal-title {
- font-size: 1.5rem;
-}
-.modal-content {
- position: relative;
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- width: 100%;
- pointer-events: auto;
- background-color: #fff;
- background-clip: padding-box;
- border: 1px solid rgba(0, 0, 0, 0.2);
- border-radius: 0.3rem;
- outline: 0;
-}
-.modal-header {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-align: start;
- -ms-flex-align: start;
- align-items: flex-start;
- -webkit-box-pack: justify;
- -ms-flex-pack: justify;
- justify-content: space-between;
- padding: 1rem;
- border-bottom: 1px solid #e9ecef;
- border-top-left-radius: 0.3rem;
- border-top-right-radius: 0.3rem;
-}
-.modal-body {
- position: relative;
- -webkit-box-flex: 1;
- -ms-flex: 1 1 auto;
- flex: 1 1 auto;
- padding: 1rem;
-}
-.modal-footer {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: end;
- -ms-flex-pack: end;
- justify-content: flex-end;
- padding: 1rem;
- border-top: 1px solid #e9ecef;
-}
-.modal button {
- display: inline-block;
- text-align: center;
- vertical-align: middle;
- font-size: 1rem;
- line-height: 1.5;
- padding: 0.375rem 0.75rem;
- margin: 0.125rem;
- font-weight: 700;
-}
-.modal-backdrop {
- z-index: 1071;
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- background-color: #000;
- opacity: 0.5;
-}
-table {
- width: 100%;
- max-width: 100%;
- margin-bottom: 1rem;
- background-color: transparent;
- border-collapse: collapse;
-}
-table thead th {
- vertical-align: bottom;
- border-bottom: 2px solid #dee2e6;
-}
-table td,
-table th {
- padding: 0.75rem;
- vertical-align: top;
-}
-label {
- margin: 0 1.5rem;
- vertical-align: middle;
-}
diff --git a/maidr/example/tutorial1_bar_plot.html b/maidr/example/tutorial1_bar_plot.html
deleted file mode 100644
index 11a659b..0000000
--- a/maidr/example/tutorial1_bar_plot.html
+++ /dev/null
@@ -1,1164 +0,0 @@
-
-
-
- Tutorial 1: Bar Chart
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 0
-
-
-
-
-
-
-
-
- 5000
-
-
-
-
-
-
-
-
- 10000
-
-
-
-
-
-
-
-
- 15000
-
-
-
-
-
-
-
-
- 20000
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fair
-
-
-
-
-
-
-
-
- Good
-
-
-
-
-
-
-
-
- Very Good
-
-
-
-
-
-
-
-
- Premium
-
-
-
-
-
-
-
-
- Ideal
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cut
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Count
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The Number of Diamonds by Cut.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/maidr/example/tutorial2_heatmap.html b/maidr/example/tutorial2_heatmap.html
deleted file mode 100644
index 3c8ad5e..0000000
--- a/maidr/example/tutorial2_heatmap.html
+++ /dev/null
@@ -1,1289 +0,0 @@
-
-
-
- Tutorial 2: Heatmap
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Adelie
-
-
-
-
-
-
-
-
- Chinstrap
-
-
-
-
-
-
-
-
- Gentoo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Biscoe
-
-
-
-
-
-
-
-
- Dream
-
-
-
-
-
-
-
-
- Torgersen
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Island
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Species
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 60
-
-
-
-
-
-
-
-
- 80
-
-
-
-
-
-
-
-
- 100
-
-
-
-
-
-
-
-
- 120
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Count
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Penguin Species by Island
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/maidr/example/tutorial3_boxplot_horizontal.html b/maidr/example/tutorial3_boxplot_horizontal.html
deleted file mode 100644
index e3aba1f..0000000
--- a/maidr/example/tutorial3_boxplot_horizontal.html
+++ /dev/null
@@ -1,1912 +0,0 @@
-
-
-
- Tutorial 3: Box Plot
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2seater
-
-
-
-
-
-
-
-
- compact
-
-
-
-
-
-
-
-
- midsize
-
-
-
-
-
-
-
-
- minivan
-
-
-
-
-
-
-
-
- pickup
-
-
-
-
-
-
-
-
- subcompact
-
-
-
-
-
-
-
-
- suv
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 20
-
-
-
-
-
-
-
-
- 30
-
-
-
-
-
-
-
-
- 40
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Highway Mileage
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Car Class
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Highway Mileage by Car Class.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/maidr/example/tutorial4_scatterplot.html b/maidr/example/tutorial4_scatterplot.html
deleted file mode 100644
index 4e78567..0000000
--- a/maidr/example/tutorial4_scatterplot.html
+++ /dev/null
@@ -1,5894 +0,0 @@
-
-
-
- Tutorial 4: Scatter Plot
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 20
-
-
-
-
-
-
-
-
- 30
-
-
-
-
-
-
-
-
- 40
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
-
- 3
-
-
-
-
-
-
-
-
- 4
-
-
-
-
-
-
-
-
- 5
-
-
-
-
-
-
-
-
- 6
-
-
-
-
-
-
-
-
- 7
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Engine Displacement
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Highway Mileage
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Highway Mileage by Engine Displacement.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/maidr/layer_data.py b/maidr/layer_data.py
deleted file mode 100644
index a8116f3..0000000
--- a/maidr/layer_data.py
+++ /dev/null
@@ -1,786 +0,0 @@
-import numpy as np
-
-
-class LayerData:
- def __init__(self, data):
- self.plot_data = data
-
- def dataplotCount(self, name):
- if not self.plot_data.has_data():
- return "Plot is Empty!"
-
- data_y = []
- data_x = []
-
- x_vars = self.plot_data.get_xticklabels()
- for x in x_vars:
- data_x.append(x.get_text())
-
- y_vars = self.plot_data.patches
- for y in y_vars:
- data_y.append(y.get_height())
-
- _data = [data_x, data_y]
- # self.createHtmlTemplate(name, _data, "path", 2)
- self.createMaidrTemplate(name, _data, "path", 2, len(data_y))
-
- return _data
-
- def dataplotBar(self, name):
- _data = self.dataplotCount(name)
- self.createMaidrTemplate(name, _data, "path", 2, len(_data[1]))
-
- return _data
-
- def dataplotScatter(self, name):
- if not self.plot_data.has_data():
- return "Plot is Empty!"
-
- data_y = []
- data_x = []
- data_sc = self.plot_data.collections[0].get_offsets()
- for points in data_sc:
- data_y.append(points.data[1])
- data_x.append(points.data[0])
-
- _data = [data_x, data_y]
-
- # added for maidr
- data = []
- for i in range(len(data_x)):
- data.append({"x": data_x[i], "y": data_y[i]})
-
- self.createMaidrTemplateScatter(name, data, "use", 0, len(data_y))
-
- return _data
-
- def dataplotLine(self, name):
- if not self.plot_data.has_data():
- return "Plot is Empty!"
-
- data_y = []
- data_x = []
- for data in self.plot_data.lines:
- y = data.get_ydata()
- data_y.append(y)
-
- x = data.get_xdata()
- data_x.append(x)
-
- x = np.array(data_x[0]).tolist()
- y = np.array(data_y[0]).tolist()
- _data = [x, y]
- print(_data)
- self.createHtmlTemplateLine(name, _data, "path", 14)
-
- return _data
-
- def dataplotHeat(self, name):
- if not self.plot_data.has_data():
- return "Plot is Empty!"
-
- x_ticks = self.plot_data.get_xticklabels()
-
- y_ticks = self.plot_data.get_yticklabels()
-
- x_labels = []
- for x in x_ticks:
- x_labels.append(x.get_text())
-
- y_labels = []
- for y in y_ticks:
- y_labels.append(y.get_text())
-
- print("axes", x_labels, y_labels)
-
- datapoints = self.plot_data.collections[0].get_array()
-
- # x_ax_data = {}
- # for i in range(len(x_labels)):
- # year = []
- # for j in range(len(y_labels)):
- # index = j * len(x_labels) + i
- # data_value = datapoints[index]
- # year.append(data_value)
- # x_ax_data.update({y_labels[i]: year})
-
- x_ax_data = []
- for i in range(len(x_labels)):
- year = []
- for j in range(len(y_labels)):
- index = j * len(x_labels) + i
- data_value = datapoints[index]
- year.append(data_value)
- x_ax_data.append(year)
-
- _data = []
- data_x = x_labels
- slices = y_labels
- data_y = x_ax_data
-
- _data = [data_x, slices, data_y]
- self.createMaidrTemplateHeat(
- name, _data, "path", 2, (len(data_x) * len(slices))
- )
-
- return
-
- def dataplotBox(self, name):
- if not self.plot_data.has_data():
- return "Plot is Empty!"
-
- print("Hi", self.plot_data.artists, len(self.plot_data.artists))
- print("Hi", self.plot_data.lines, len(self.plot_data.lines))
-
- for i in self.plot_data.lines:
- print(i)
-
- # _data = [data_x, data_y]
- # # print(_data)
- # self.createHtmlTemplateHeatMap(name, _data, "path", 2)
-
- return
-
- def createMaidrTemplate(self, name, _data, element, slice_count, index):
- with open("generated_svg/" + name + "plot.svg", "r") as text_file:
- svg_ = text_file.read()
-
- # id_attr = 'id="MyChart"'
- # svg_ = svg_.replace("
-
-
-
-
-
- Document
-
-
-
-
-
-
-
-
-
- """
-
- html_template = html_template.format(
- svg=svg_,
- data_x=_data[0],
- name=name,
- data_y=_data[1],
- element=element,
- slice_count=slice_count,
- index=index,
- )
-
- with open("chart_maidr.html", "w") as f:
- f.write(html_template)
-
- def createMaidrTemplateScatter(self, name, _data, element, slice_count, index):
- with open("generated_svg/" + name + "plot.svg", "r") as text_file:
- svg_ = text_file.read()
-
- # id_attr = 'id="MyChart"'
- # svg_ = svg_.replace("
-
-
-
-
-
- Document
-
-
-
-
-
-
-
-
-
- """
-
- html_template = html_template.format(
- svg=svg_,
- data=_data,
- name=name,
- # data_y=_data[1],
- element=element,
- slice_count=slice_count,
- index=index,
- )
-
- with open("chart_maidr.html", "w") as f:
- f.write(html_template)
-
- def createMaidrTemplateHeat(self, name, _data, element, slice_count, index):
- with open("generated_svg/" + name + "plot.svg", "r") as text_file:
- svg_ = text_file.read()
-
- # id_attr = 'id="MyChart"'
- # svg_ = svg_.replace("
-
-
-
-
-
- Document
-
-
-
-
-
-
-
-
-
- """
-
- html_template = html_template.format(
- svg=svg_,
- data_x=_data[0],
- slices=_data[1],
- name=name,
- data_y=_data[2],
- element=element,
- slice_count=slice_count,
- index=index,
- )
-
- #
- #
- #
- #
- #
- #
- # Document
-
- #
- #
- #
- #
- # {svg}
- #
- #
-
- #
- #
- #
-
- with open("chart_maidr.html", "w") as f:
- f.write(html_template)
-
- def createHtmlTemplate(self, name, _data, element, slice_count):
- with open("generated_svg/" + name + "plot.svg", "r") as text_file:
- svg_ = text_file.read()
-
- id_attr = 'id="MyChart"'
- svg_ = svg_.replace("
-
-
-
-
-
- Document
-
-
-
-
-
- {svg}
-
-
-
-
-
-
- """
-
- html_template = html_template.format(
- svg=svg_,
- data_x=_data[0],
- name=name,
- data_y=_data[1],
- element=element,
- slice_count=slice_count,
- )
-
- with open("chart.html", "w") as f:
- f.write(html_template)
-
- def createHtmlTemplate(self, name, _data, element, slice_count):
- with open("generated_svg/" + name + "plot.svg", "r") as text_file:
- svg_ = text_file.read()
-
- id_attr = 'id="MyChart"'
- svg_ = svg_.replace("
-
-
-
-
-
- Document
-
-
-
-
-
- {svg}
-
-
-
-
-
-
- """
-
- html_template = html_template.format(
- svg=svg_,
- data_x=_data[0],
- name=name,
- data_y=_data[1],
- element=element,
- slice_count=slice_count,
- )
-
- with open("chart.html", "w") as f:
- f.write(html_template)
-
- def createHtmlTemplateHeatMap(self, name, _data, element, slice_count):
- with open("generated_svg/" + name + "plot.svg", "r") as text_file:
- svg_ = text_file.read()
-
- id_attr = 'id="MyChart"'
- svg_ = svg_.replace("
-
-
-
-
-
- Document
-
-
-
-
-
- {svg}
-
-
-
-
-
-
- """
-
- # data: Object.fromEntries(
- # {data_y}.map((label, index) => [label, {data_y}[index]])
- # ),
- # options: {{
- # onFocusCallback: ({{index, slice}}) => {{
- # const data_ = {data_y}
- # Array.from(document.querySelectorAll("#MyChart {element}")).slice({slice_count}) .forEach((elem) => {{
- # elem.style.fill = "rgb(89, 89, 89)";
- # }})
- # document.querySelectorAll("#MyChart {element}")[index+{slice_count}].style.fill = "cyan";
- # }}
- # }}
-
- # onFocusCallback: ({{index}}) => {{
- # const data_ = {data_y}
- # Array.from(document.querySelectorAll("#MyChart {element}")).slice({slice_count}) .forEach((elem) => {{
- # elem.style.fill = "rgb(89, 89, 89)";
- # }})
- # const point = data_[Object.keys(data_)[index]];
- # point.map((val, ind)=>{{
- # console.log(ind, index)
- # document.querySelectorAll("#MyChart {element}")[(index*ind)+{slice_count}].style.fill = "cyan";
- # }})
- # }}
-
- # Object.keys({data_y})[index].map((value, i) => {{
- # document.querySelectorAll("#MyChart {element}")[index+{slice_count}][i].style.fill = "cyan";
- # }})
-
- html_template = html_template.format(
- svg=svg_,
- data_x=_data[0],
- slices=_data[1],
- name=name,
- data_y=_data[2],
- element=element,
- slice_count=slice_count,
- )
-
- with open("chart.html", "w") as f:
- f.write(html_template)
-
- def createHtmlTemplateLine(self, name, _data, element, slice_count):
- with open("generated_svg/" + name + "plot.svg", "r") as text_file:
- svg_ = text_file.read()
-
- id_attr = 'id="MyChart"'
- svg_ = svg_.replace("
-
-
-
-
-
- Document
-
-
-
-
-
- {svg}
-
-
-
-
-
-
- """
-
- html_template = html_template.format(
- svg=svg_,
- data_x=_data[0],
- name=name,
- data_y=_data[1],
- element=element,
- slice_count=slice_count,
- )
-
- with open("chart.html", "w") as f:
- f.write(html_template)
-
- # def createHtmlTemplateLine2(self, name, _data, element, slice_count):
- # with open("generated_svg/" + name + "plot.svg", "r") as text_file:
- # svg_ = text_file.read()
-
- # id_attr = 'id="MyChart"'
- # svg_ = svg_.replace("
- #
- #
- #
- #
- #
- # Document
-
- #
- #
- #
- #
- # {svg}
- #
- #
-
- #
- #
- #
- # """
-
- # html_template = html_template.format(
- # svg=svg_,
- # data_x=_data[0],
- # name=name,
- # data_y=_data[1],
- # element=element,
- # slice_count=slice_count,
- # )
-
- # with open("chart.html", "w") as f:
- # f.write(html_template)
diff --git a/maidr/maidr.py b/maidr/maidr.py
index dc4e0b6..7c6352f 100644
--- a/maidr/maidr.py
+++ b/maidr/maidr.py
@@ -1,258 +1,17 @@
-import datetime
-import io
-import os
-import tempfile
-import webbrowser
+from __future__ import annotations
-import matplotlib.pyplot as plt
-import numpy as np
-import seaborn as sns
-from lxml import etree
+from matplotlib.container import BarContainer
-# Temp original sns.countplot function to override
-sns_countplot = sns.countplot
+from .core.maidr import Maidr
+from .core.enum.plot_type import PlotType
+from .utils.figure_manager import FigureManager
-def countplot(*args, **kwargs):
- browse = kwargs.pop("browse", True)
- file = kwargs.pop("file", None)
+def bar(plot: BarContainer) -> Maidr:
+ fig = FigureManager.get_figure(plot)
+ plot_type = [PlotType.BAR for _ in fig.axes] if fig and fig.axes else []
+ return FigureManager.create_maidr(fig, plot, plot_type)
- plot_data = sns_countplot(*args, **kwargs)
- data_x = [x.get_text() for x in plot_data.get_xticklabels()]
- data_y = [y.get_height() for y in plot_data.patches]
- _data = [data_x, data_y]
-
- # Get x and y label
- x_label = plot_data.get_xlabel()
- y_label = plot_data.get_ylabel()
-
- create_html_template(
- name="bar",
- _data=_data,
- x_label=x_label,
- y_label=y_label,
- element="path",
- slice_count=2,
- browse=browse,
- file=file,
- )
- return plot_data
-
-
-sns.countplot = countplot
-
-# Barplot
-
-# Temp original sns.barplot function to override
-sns_barplot = sns.barplot
-
-
-def barplot(*args, **kwargs):
- browse = kwargs.pop("browse", True)
- file = kwargs.pop("file", None)
-
- plot_data = sns_barplot(*args, **kwargs)
-
- # The y values can be extracted as follows:
- data_y = [patch.get_height() for patch in plot_data.patches]
-
- # The x labels can be extracted using get_xticklabels()
- data_x = [label.get_text() for label in plot_data.get_xticklabels()]
-
- _data = [data_x, data_y]
-
- # Get x and y label
- x_label = plot_data.get_xlabel()
- y_label = plot_data.get_ylabel()
-
- create_html_template(
- name="bar",
- _data=_data,
- x_label=x_label,
- y_label=y_label,
- element="path",
- slice_count=2,
- browse=browse,
- file=file,
- )
- return plot_data
-
-
-sns.barplot = barplot
-
-# Scatterplot
-sns_scatterplot = sns.scatterplot
-
-
-def scatterplot(*args, **kwargs):
- browse = kwargs.pop("browse", True)
- file = kwargs.pop("file", None)
- plot_data = sns_scatterplot(*args, **kwargs)
- data_sc = plot_data.collections[0].get_offsets()
- data_x = [points.data[0] for points in data_sc]
- data_y = [points.data[1] for points in data_sc]
- _data = [data_x, data_y]
-
- # Get x and y label
- x_label = plot_data.get_xlabel()
- y_label = plot_data.get_ylabel()
-
- create_html_template(
- name="scatter",
- _data=_data,
- x_label=x_label,
- y_label=y_label,
- element="use",
- slice_count=0,
- browse=browse,
- file=file,
- )
- return plot_data
-
-
-sns.scatterplot = scatterplot
-
-# lineplot
-sns_lineplot = sns.lineplot
-
-
-def lineplot(*args, **kwargs):
- browse = kwargs.pop("browse", True)
- file = kwargs.pop("file", None)
- plot_data = sns_lineplot(*args, **kwargs)
-
- data_y = [data.get_ydata() for data in plot_data.lines]
- data_x = [data.get_xdata() for data in plot_data.lines]
- x = np.array(data_x[0]).tolist()
- y = np.array(data_y[0]).tolist()
- _data = [x, y]
-
- # Get x and y label
- x_label = plot_data.get_xlabel()
- y_label = plot_data.get_ylabel()
-
- create_html_template(
- name="line",
- _data=_data,
- x_label=x_label,
- y_label=y_label,
- element="path",
- slice_count=14,
- browse=browse,
- file=file,
- )
- return plot_data
-
-
-sns.lineplot = lineplot
-
-
-def create_html_template(
- name, _data, x_label, y_label, element, slice_count, browse, file
-):
- # Create an io.BytesIO object and save the seaborn plot as SVG to it
- svg_file = io.BytesIO()
- plt.savefig(svg_file, format="svg", bbox_inches="tight")
- plt.close()
- # Seek to the beginning of the file and read it into a variable
- svg_file.seek(0)
- svg_data = svg_file.read().decode("utf-8")
-
- # Parse the SVG data
- svg_tree = etree.fromstring(svg_data.encode("utf-8"))
-
- # Find and remove all tags
- for xml_tag in svg_tree.xpath("//xml"):
- xml_tag.getparent().remove(xml_tag)
-
- # Find the opening tag and add an id attribute
- # Current date and time
- now = datetime.datetime.now()
-
- # Create an id
- id = name + now.strftime("%Y%m%d%H%M%S")
-
- svg_tree.set("id", id)
-
- # Serialize the modified SVG back into a string
- svg_ = etree.tostring(svg_tree, pretty_print=True, method="xml").decode("utf-8")
-
- html_template = """
-
-
-
-
-
-
- Document
-
-
-
-
-
- {svg}
-
-
-
-
-
-
- """
-
- html_template = html_template.format(
- svg=svg_,
- data_x=_data[0],
- name=name,
- id=id,
- data_y=_data[1],
- x_label=x_label,
- y_label=y_label,
- element=element,
- slice_count=slice_count,
- )
-
- if file is None:
- # Save the HTML string to a file in the temp directory
- temp_dir = tempfile.gettempdir()
- html_file_path = os.path.join(temp_dir, "my_plot.html")
- else:
- html_file_path = file
-
- with open(html_file_path, "w") as f:
- f.write(html_template)
-
- # Open in the default web browser
- if browse:
- webbrowser.open("file://" + os.path.realpath(html_file_path))
- else:
- print(f"HTML file saved at: {html_file_path}")
+def close() -> None:
+ pass
diff --git a/maidr/main.py b/maidr/main.py
deleted file mode 100644
index 4a5857a..0000000
--- a/maidr/main.py
+++ /dev/null
@@ -1,137 +0,0 @@
-import matplotlib.pyplot as plt
-import pandas as pd
-import pydataset
-import seaborn as sns
-from layer_data import LayerData
-
-
-def countPlot(plot_type, is_json):
- df_cp = sns.load_dataset("titanic")
- plot_data_cp = sns.countplot(x=df_cp["class"])
- ext_data_count = LayerData(plot_data_cp)
-
- plt.savefig("generated_svg/" + plot_type + "plot.svg", format="svg")
- data = ext_data_count.dataplotCount(plot_type)
-
- _data = None
- if is_json:
- _data = toJson(plot_type, data[0], data[1])
- else:
- _data = toDf(data[0], data[1])
- print(_data)
-
- plot_data_cp.clear()
-
-
-def barPlot(plot_type, is_json):
- df_bp = sns.load_dataset("penguins")
- plot_data_bp = sns.barplot(data=df_bp, x="island", y="body_mass_g")
- ext_data_bar = LayerData(plot_data_bp)
-
- plt.savefig("generated_svg/" + plot_type + "plot.svg", format="svg")
- data = ext_data_bar.dataplotBar(plot_type)
-
- _data = None
- if is_json:
- _data = toJson(plot_type, data[0], data[1])
- else:
- _data = toDf(data[0], data[1])
- print(_data)
-
- plot_data_bp.clear()
-
-
-def scatterPlot(plot_type, is_json):
- df_sc = sns.load_dataset("tips")
- plot_data_sc = sns.scatterplot(data=df_sc, x="total_bill", y="tip")
- ext_data_scatter = LayerData(plot_data_sc)
-
- plt.savefig("generated_svg/" + plot_type + "plot.svg", format="svg")
- data = ext_data_scatter.dataplotScatter(plot_type)
- _data = None
- if is_json:
- _data = toJson(plot_type, data[0], data[1])
- else:
- _data = toDf(data[0], data[1])
- print(_data)
-
-
-def linePlot(plot_type, is_json):
- df = pydataset.data("economics")
- plot_data_lp = sns.lineplot(df, x="date", y="pop")
-
- # df_lp = sns.load_dataset("flights")
- # may_flights = df_lp.query("month == 'May'")
- # plot_data_lp = sns.lineplot(data=may_flights, x="year", y="passengers")
- ext_data_line = LayerData(plot_data_lp)
-
- plt.savefig("generated_svg/" + plot_type + "plot.svg", format="svg")
- data = ext_data_line.dataplotLine(plot_type)
-
- _data = None
- if is_json:
- _data = toJson(plot_type, data[0], data[1])
- else:
- _data = toDf(data[0], data[1])
- print(_data)
-
-
-def heatPlot(plot_type, is_json):
- df_hp = sns.load_dataset("flights")
- flights = df_hp.pivot("month", "year", "passengers")
- plot_data_hp = sns.heatmap(flights)
- ext_data_heat = LayerData(plot_data_hp)
-
- plt.savefig("generated_svg/" + plot_type + "plot.svg", format="svg")
- data = ext_data_heat.dataplotHeat(plot_type)
-
- # TODO: display in df annd json
-
-
-def boxPlot(plot_type, is_json):
- df_bxp = sns.load_dataset("titanic")
- plot_data_bxp = sns.boxplot(data=df_bxp, x="age", y="class")
- ext_data_box = LayerData(plot_data_bxp)
-
- plt.savefig("generated_svg/" + plot_type + "plot.svg", format="svg")
- data = ext_data_box.dataplotBox(plot_type)
-
-
-def toJson(name, x_data, y_data):
- values = []
- for i in range(len(x_data)):
- values.append({"x": x_data[i], "y": y_data[i]})
-
- data = {"type": name, "data": {"datasets": [{"data": values}]}}
-
- return data
-
-
-def toDf(x_data, y_data):
- data = pd.DataFrame({"x": x_data, "y": y_data})
- return data
-
-
-def main():
- # print("countplot data::::")
- # countPlot("barplot", True)
-
- print("barplot data::::")
- barPlot("barplot", True)
-
- # print("scatterplot data::::")
- # scatterPlot("scatterplot", True)
-
- # print("lineplot data::::")
- # linePlot("line", True)
-
- # print("heatmap data::::")
- # # heatPlot("matrix", True)
- # heatPlot("heatmap", True)
-
- # print("boxplot data::::")
- # boxPlot("box", True)
-
-
-if __name__ == "__main__":
- main()
diff --git a/maidr/test.py b/maidr/test.py
deleted file mode 100644
index 806ba25..0000000
--- a/maidr/test.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# import matplotlib.pyplot as plt
-import pydataset
-import seaborn as sns
-
-import maidr
-
-# # Let's say you have a barplot
-# df = pydataset.data("diamonds")
-# sns.countplot(df, x="cut", file="jy.html")
-# df = pydataset.data("economics")
-# Line plot
-# sns.lineplot(df, x="date", y="pop", file="jy.html")
-
-# Test scatterplot
-df = pydataset.data("mpg")
-sns.scatterplot(df, x="displ", y="hwy")
diff --git a/maidr/utils/__init__.py b/maidr/utils/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/maidr/utils/figure_manager.py b/maidr/utils/figure_manager.py
new file mode 100644
index 0000000..30981c7
--- /dev/null
+++ b/maidr/utils/figure_manager.py
@@ -0,0 +1,54 @@
+from __future__ import annotations
+
+from matplotlib.container import BarContainer
+from matplotlib.figure import Figure
+
+from maidr.core.maidr import Maidr
+from maidr.core.maidr_data_factory import MaidrDataFactory
+from maidr.core.enum.plot_type import PlotType
+
+
+class FigureManager:
+ @staticmethod
+ def create_maidr(
+ fig: Figure | None, plot, plot_type: list[PlotType] | None
+ ) -> Maidr:
+ if not fig:
+ raise ValueError("Figure not found")
+ if not fig.axes:
+ raise ValueError("Axes not found")
+ if not plot:
+ raise ValueError("Plot not found")
+ if not plot_type:
+ raise ValueError("Plot type not found")
+ if len(fig.axes) != len(plot_type):
+ raise ValueError(
+ "Lengths of plots {0} and their {1} types do not match".format(
+ len(fig.axes), len(plot_type)
+ )
+ )
+
+ maidr_data = [
+ MaidrDataFactory.create(ax, plot, plt_type)
+ for ax, plt_type in zip(fig.axes, plot_type)
+ ]
+ return Maidr(fig, maidr_data)
+
+ @staticmethod
+ def get_figure(artist: BarContainer | None) -> Figure | None:
+ if not artist:
+ return None
+
+ fig = None
+ # bar container - get figure from the first occurrence of any artist
+ if isinstance(artist, BarContainer):
+ fig = next(
+ (
+ child_artist.get_figure()
+ for child_artist in artist.get_children()
+ if child_artist.get_figure()
+ ),
+ None,
+ )
+
+ return fig
diff --git a/poetry.lock b/poetry.lock
index baa5eca..ca674f9 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,14 +1,14 @@
-# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
[[package]]
name = "alabaster"
-version = "0.7.13"
-description = "A configurable sidebar-enabled Sphinx theme"
+version = "0.7.16"
+description = "A light, configurable Sphinx theme"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.9"
files = [
- {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
- {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
+ {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"},
+ {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"},
]
[[package]]
@@ -24,15 +24,18 @@ files = [
[[package]]
name = "babel"
-version = "2.12.1"
+version = "2.14.0"
description = "Internationalization utilities"
optional = false
python-versions = ">=3.7"
files = [
- {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
- {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
+ {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"},
+ {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"},
]
+[package.extras]
+dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"]
+
[[package]]
name = "black"
version = "23.3.0"
@@ -83,119 +86,134 @@ uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "certifi"
-version = "2023.5.7"
+version = "2024.2.2"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
files = [
- {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"},
- {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"},
+ {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
+ {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
]
[[package]]
name = "cfgv"
-version = "3.3.1"
+version = "3.4.0"
description = "Validate configuration and produce human readable error messages."
optional = false
-python-versions = ">=3.6.1"
+python-versions = ">=3.8"
files = [
- {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
- {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"},
+ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
+ {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
]
[[package]]
name = "charset-normalizer"
-version = "3.1.0"
+version = "3.3.2"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7.0"
files = [
- {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
- {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
- {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
- {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
- {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
- {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
- {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
+ {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
+ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
]
[[package]]
name = "click"
-version = "8.1.3"
+version = "8.1.7"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
- {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
- {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
+ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
+ {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[package.dependencies]
@@ -214,98 +232,91 @@ files = [
[[package]]
name = "contourpy"
-version = "1.0.7"
+version = "1.2.0"
description = "Python library for calculating contours of 2D quadrilateral grids"
optional = false
-python-versions = ">=3.8"
-files = [
- {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:95c3acddf921944f241b6773b767f1cbce71d03307270e2d769fd584d5d1092d"},
- {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fc1464c97579da9f3ab16763c32e5c5d5bb5fa1ec7ce509a4ca6108b61b84fab"},
- {file = "contourpy-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8acf74b5d383414401926c1598ed77825cd530ac7b463ebc2e4f46638f56cce6"},
- {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c71fdd8f1c0f84ffd58fca37d00ca4ebaa9e502fb49825484da075ac0b0b803"},
- {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f99e9486bf1bb979d95d5cffed40689cb595abb2b841f2991fc894b3452290e8"},
- {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f4d8941a9564cda3f7fa6a6cd9b32ec575830780677932abdec7bcb61717b0"},
- {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e20e5a1908e18aaa60d9077a6d8753090e3f85ca25da6e25d30dc0a9e84c2c6"},
- {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a877ada905f7d69b2a31796c4b66e31a8068b37aa9b78832d41c82fc3e056ddd"},
- {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6381fa66866b0ea35e15d197fc06ac3840a9b2643a6475c8fff267db8b9f1e69"},
- {file = "contourpy-1.0.7-cp310-cp310-win32.whl", hash = "sha256:3c184ad2433635f216645fdf0493011a4667e8d46b34082f5a3de702b6ec42e3"},
- {file = "contourpy-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:3caea6365b13119626ee996711ab63e0c9d7496f65641f4459c60a009a1f3e80"},
- {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed33433fc3820263a6368e532f19ddb4c5990855e4886088ad84fd7c4e561c71"},
- {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38e2e577f0f092b8e6774459317c05a69935a1755ecfb621c0a98f0e3c09c9a5"},
- {file = "contourpy-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae90d5a8590e5310c32a7630b4b8618cef7563cebf649011da80874d0aa8f414"},
- {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130230b7e49825c98edf0b428b7aa1125503d91732735ef897786fe5452b1ec2"},
- {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58569c491e7f7e874f11519ef46737cea1d6eda1b514e4eb5ac7dab6aa864d02"},
- {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d43960d809c4c12508a60b66cb936e7ed57d51fb5e30b513934a4a23874fae"},
- {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:152fd8f730c31fd67fe0ffebe1df38ab6a669403da93df218801a893645c6ccc"},
- {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9056c5310eb1daa33fc234ef39ebfb8c8e2533f088bbf0bc7350f70a29bde1ac"},
- {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a9d7587d2fdc820cc9177139b56795c39fb8560f540bba9ceea215f1f66e1566"},
- {file = "contourpy-1.0.7-cp311-cp311-win32.whl", hash = "sha256:4ee3ee247f795a69e53cd91d927146fb16c4e803c7ac86c84104940c7d2cabf0"},
- {file = "contourpy-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:5caeacc68642e5f19d707471890f037a13007feba8427eb7f2a60811a1fc1350"},
- {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd7dc0e6812b799a34f6d12fcb1000539098c249c8da54f3566c6a6461d0dbad"},
- {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0f9d350b639db6c2c233d92c7f213d94d2e444d8e8fc5ca44c9706cf72193772"},
- {file = "contourpy-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e96a08b62bb8de960d3a6afbc5ed8421bf1a2d9c85cc4ea73f4bc81b4910500f"},
- {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:031154ed61f7328ad7f97662e48660a150ef84ee1bc8876b6472af88bf5a9b98"},
- {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e9ebb4425fc1b658e13bace354c48a933b842d53c458f02c86f371cecbedecc"},
- {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efb8f6d08ca7998cf59eaf50c9d60717f29a1a0a09caa46460d33b2924839dbd"},
- {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6c180d89a28787e4b73b07e9b0e2dac7741261dbdca95f2b489c4f8f887dd810"},
- {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b8d587cc39057d0afd4166083d289bdeff221ac6d3ee5046aef2d480dc4b503c"},
- {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:769eef00437edf115e24d87f8926955f00f7704bede656ce605097584f9966dc"},
- {file = "contourpy-1.0.7-cp38-cp38-win32.whl", hash = "sha256:62398c80ef57589bdbe1eb8537127321c1abcfdf8c5f14f479dbbe27d0322e66"},
- {file = "contourpy-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:57119b0116e3f408acbdccf9eb6ef19d7fe7baf0d1e9aaa5381489bc1aa56556"},
- {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30676ca45084ee61e9c3da589042c24a57592e375d4b138bd84d8709893a1ba4"},
- {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e927b3868bd1e12acee7cc8f3747d815b4ab3e445a28d2e5373a7f4a6e76ba1"},
- {file = "contourpy-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:366a0cf0fc079af5204801786ad7a1c007714ee3909e364dbac1729f5b0849e5"},
- {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ba9bb365446a22411f0673abf6ee1fea3b2cf47b37533b970904880ceb72f3"},
- {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b0bf0c30d432278793d2141362ac853859e87de0a7dee24a1cea35231f0d50"},
- {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7281244c99fd7c6f27c1c6bfafba878517b0b62925a09b586d88ce750a016d2"},
- {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b6d0f9e1d39dbfb3977f9dd79f156c86eb03e57a7face96f199e02b18e58d32a"},
- {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f6979d20ee5693a1057ab53e043adffa1e7418d734c1532e2d9e915b08d8ec2"},
- {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5dd34c1ae752515318224cba7fc62b53130c45ac6a1040c8b7c1a223c46e8967"},
- {file = "contourpy-1.0.7-cp39-cp39-win32.whl", hash = "sha256:c5210e5d5117e9aec8c47d9156d1d3835570dd909a899171b9535cb4a3f32693"},
- {file = "contourpy-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:60835badb5ed5f4e194a6f21c09283dd6e007664a86101431bf870d9e86266c4"},
- {file = "contourpy-1.0.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ce41676b3d0dd16dbcfabcc1dc46090aaf4688fd6e819ef343dbda5a57ef0161"},
- {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a011cf354107b47c58ea932d13b04d93c6d1d69b8b6dce885e642531f847566"},
- {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31a55dccc8426e71817e3fe09b37d6d48ae40aae4ecbc8c7ad59d6893569c436"},
- {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69f8ff4db108815addd900a74df665e135dbbd6547a8a69333a68e1f6e368ac2"},
- {file = "contourpy-1.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efe99298ba37e37787f6a2ea868265465410822f7bea163edcc1bd3903354ea9"},
- {file = "contourpy-1.0.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a1e97b86f73715e8670ef45292d7cc033548266f07d54e2183ecb3c87598888f"},
- {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc331c13902d0f50845099434cd936d49d7a2ca76cb654b39691974cb1e4812d"},
- {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24847601071f740837aefb730e01bd169fbcaa610209779a78db7ebb6e6a7051"},
- {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abf298af1e7ad44eeb93501e40eb5a67abbf93b5d90e468d01fc0c4451971afa"},
- {file = "contourpy-1.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:64757f6460fc55d7e16ed4f1de193f362104285c667c112b50a804d482777edd"},
- {file = "contourpy-1.0.7.tar.gz", hash = "sha256:d8165a088d31798b59e91117d1f5fc3df8168d8b48c4acc10fc0df0d0bdbcc5e"},
+python-versions = ">=3.9"
+files = [
+ {file = "contourpy-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0274c1cb63625972c0c007ab14dd9ba9e199c36ae1a231ce45d725cbcbfd10a8"},
+ {file = "contourpy-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab459a1cbbf18e8698399c595a01f6dcc5c138220ca3ea9e7e6126232d102bb4"},
+ {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fdd887f17c2f4572ce548461e4f96396681212d858cae7bd52ba3310bc6f00f"},
+ {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d16edfc3fc09968e09ddffada434b3bf989bf4911535e04eada58469873e28e"},
+ {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c203f617abc0dde5792beb586f827021069fb6d403d7f4d5c2b543d87edceb9"},
+ {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b69303ceb2e4d4f146bf82fda78891ef7bcd80c41bf16bfca3d0d7eb545448aa"},
+ {file = "contourpy-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:884c3f9d42d7218304bc74a8a7693d172685c84bd7ab2bab1ee567b769696df9"},
+ {file = "contourpy-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4a1b1208102be6e851f20066bf0e7a96b7d48a07c9b0cfe6d0d4545c2f6cadab"},
+ {file = "contourpy-1.2.0-cp310-cp310-win32.whl", hash = "sha256:34b9071c040d6fe45d9826cbbe3727d20d83f1b6110d219b83eb0e2a01d79488"},
+ {file = "contourpy-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:bd2f1ae63998da104f16a8b788f685e55d65760cd1929518fd94cd682bf03e41"},
+ {file = "contourpy-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dd10c26b4eadae44783c45ad6655220426f971c61d9b239e6f7b16d5cdaaa727"},
+ {file = "contourpy-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5c6b28956b7b232ae801406e529ad7b350d3f09a4fde958dfdf3c0520cdde0dd"},
+ {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebeac59e9e1eb4b84940d076d9f9a6cec0064e241818bcb6e32124cc5c3e377a"},
+ {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:139d8d2e1c1dd52d78682f505e980f592ba53c9f73bd6be102233e358b401063"},
+ {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e9dc350fb4c58adc64df3e0703ab076f60aac06e67d48b3848c23647ae4310e"},
+ {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18fc2b4ed8e4a8fe849d18dce4bd3c7ea637758c6343a1f2bae1e9bd4c9f4686"},
+ {file = "contourpy-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:16a7380e943a6d52472096cb7ad5264ecee36ed60888e2a3d3814991a0107286"},
+ {file = "contourpy-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8d8faf05be5ec8e02a4d86f616fc2a0322ff4a4ce26c0f09d9f7fb5330a35c95"},
+ {file = "contourpy-1.2.0-cp311-cp311-win32.whl", hash = "sha256:67b7f17679fa62ec82b7e3e611c43a016b887bd64fb933b3ae8638583006c6d6"},
+ {file = "contourpy-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:99ad97258985328b4f207a5e777c1b44a83bfe7cf1f87b99f9c11d4ee477c4de"},
+ {file = "contourpy-1.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:575bcaf957a25d1194903a10bc9f316c136c19f24e0985a2b9b5608bdf5dbfe0"},
+ {file = "contourpy-1.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9e6c93b5b2dbcedad20a2f18ec22cae47da0d705d454308063421a3b290d9ea4"},
+ {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:464b423bc2a009088f19bdf1f232299e8b6917963e2b7e1d277da5041f33a779"},
+ {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68ce4788b7d93e47f84edd3f1f95acdcd142ae60bc0e5493bfd120683d2d4316"},
+ {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d7d1f8871998cdff5d2ff6a087e5e1780139abe2838e85b0b46b7ae6cc25399"},
+ {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e739530c662a8d6d42c37c2ed52a6f0932c2d4a3e8c1f90692ad0ce1274abe0"},
+ {file = "contourpy-1.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:247b9d16535acaa766d03037d8e8fb20866d054d3c7fbf6fd1f993f11fc60ca0"},
+ {file = "contourpy-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:461e3ae84cd90b30f8d533f07d87c00379644205b1d33a5ea03381edc4b69431"},
+ {file = "contourpy-1.2.0-cp312-cp312-win32.whl", hash = "sha256:1c2559d6cffc94890b0529ea7eeecc20d6fadc1539273aa27faf503eb4656d8f"},
+ {file = "contourpy-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:491b1917afdd8638a05b611a56d46587d5a632cabead889a5440f7c638bc6ed9"},
+ {file = "contourpy-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5fd1810973a375ca0e097dee059c407913ba35723b111df75671a1976efa04bc"},
+ {file = "contourpy-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:999c71939aad2780f003979b25ac5b8f2df651dac7b38fb8ce6c46ba5abe6ae9"},
+ {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7caf9b241464c404613512d5594a6e2ff0cc9cb5615c9475cc1d9b514218ae8"},
+ {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:266270c6f6608340f6c9836a0fb9b367be61dde0c9a9a18d5ece97774105ff3e"},
+ {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbd50d0a0539ae2e96e537553aff6d02c10ed165ef40c65b0e27e744a0f10af8"},
+ {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11f8d2554e52f459918f7b8e6aa20ec2a3bce35ce95c1f0ef4ba36fbda306df5"},
+ {file = "contourpy-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ce96dd400486e80ac7d195b2d800b03e3e6a787e2a522bfb83755938465a819e"},
+ {file = "contourpy-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d3364b999c62f539cd403f8123ae426da946e142312a514162adb2addd8d808"},
+ {file = "contourpy-1.2.0-cp39-cp39-win32.whl", hash = "sha256:1c88dfb9e0c77612febebb6ac69d44a8d81e3dc60f993215425b62c1161353f4"},
+ {file = "contourpy-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:78e6ad33cf2e2e80c5dfaaa0beec3d61face0fb650557100ee36db808bfa6843"},
+ {file = "contourpy-1.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:be16975d94c320432657ad2402f6760990cb640c161ae6da1363051805fa8108"},
+ {file = "contourpy-1.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b95a225d4948b26a28c08307a60ac00fb8671b14f2047fc5476613252a129776"},
+ {file = "contourpy-1.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0d7e03c0f9a4f90dc18d4e77e9ef4ec7b7bbb437f7f675be8e530d65ae6ef956"},
+ {file = "contourpy-1.2.0.tar.gz", hash = "sha256:171f311cb758de7da13fc53af221ae47a5877be5a0843a9fe150818c51ed276a"},
]
[package.dependencies]
-numpy = ">=1.16"
+numpy = ">=1.20,<2.0"
[package.extras]
-bokeh = ["bokeh", "chromedriver", "selenium"]
-docs = ["furo", "sphinx-copybutton"]
-mypy = ["contourpy[bokeh]", "docutils-stubs", "mypy (==0.991)", "types-Pillow"]
-test = ["Pillow", "matplotlib", "pytest"]
-test-no-images = ["pytest"]
+bokeh = ["bokeh", "selenium"]
+docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"]
+mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.6.1)", "types-Pillow"]
+test = ["Pillow", "contourpy[test-no-images]", "matplotlib"]
+test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"]
[[package]]
name = "cycler"
-version = "0.11.0"
+version = "0.12.1"
description = "Composable style cycles"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
files = [
- {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"},
- {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"},
+ {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"},
+ {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"},
]
+[package.extras]
+docs = ["ipython", "matplotlib", "numpydoc", "sphinx"]
+tests = ["pytest", "pytest-cov", "pytest-xdist"]
+
[[package]]
name = "distlib"
-version = "0.3.6"
+version = "0.3.8"
description = "Distribution utilities"
optional = false
python-versions = "*"
files = [
- {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"},
- {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
+ {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
+ {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
]
[[package]]
@@ -332,13 +343,13 @@ files = [
[[package]]
name = "exceptiongroup"
-version = "1.1.1"
+version = "1.2.0"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
- {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"},
- {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"},
+ {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
+ {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
]
[package.extras]
@@ -346,42 +357,83 @@ test = ["pytest (>=6)"]
[[package]]
name = "filelock"
-version = "3.12.1"
+version = "3.13.1"
description = "A platform independent file lock."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "filelock-3.12.1-py3-none-any.whl", hash = "sha256:42f1e4ff2b497311213d61ad7aac5fed9050608e5309573f101eefa94143134a"},
- {file = "filelock-3.12.1.tar.gz", hash = "sha256:82b1f7da46f0ae42abf1bc78e548667f484ac59d2bcec38c713cee7e2eb51e83"},
+ {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"},
+ {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"},
]
[package.extras]
-docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
-testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"]
+docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"]
+typing = ["typing-extensions (>=4.8)"]
[[package]]
name = "fonttools"
-version = "4.39.4"
+version = "4.48.1"
description = "Tools to manipulate font files"
optional = false
python-versions = ">=3.8"
files = [
- {file = "fonttools-4.39.4-py3-none-any.whl", hash = "sha256:106caf6167c4597556b31a8d9175a3fdc0356fdcd70ab19973c3b0d4c893c461"},
- {file = "fonttools-4.39.4.zip", hash = "sha256:dba8d7cdb8e2bac1b3da28c5ed5960de09e59a2fe7e63bb73f5a59e57b0430d2"},
+ {file = "fonttools-4.48.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:702ae93058c81f46461dc4b2c79f11d3c3d8fd7296eaf8f75b4ba5bbf813cd5f"},
+ {file = "fonttools-4.48.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97f0a49fa6aa2d6205c6f72f4f98b74ef4b9bfdcb06fd78e6fe6c7af4989b63e"},
+ {file = "fonttools-4.48.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3260db55f1843e57115256e91247ad9f68cb02a434b51262fe0019e95a98738"},
+ {file = "fonttools-4.48.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e740a7602c2bb71e1091269b5dbe89549749a8817dc294b34628ffd8b2bf7124"},
+ {file = "fonttools-4.48.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4108b1d247953dd7c90ec8f457a2dec5fceb373485973cc852b14200118a51ee"},
+ {file = "fonttools-4.48.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56339ec557f0c342bddd7c175f5e41c45fc21282bee58a86bd9aa322bec715f2"},
+ {file = "fonttools-4.48.1-cp310-cp310-win32.whl", hash = "sha256:bff5b38d0e76eb18e0b8abbf35d384e60b3371be92f7be36128ee3e67483b3ec"},
+ {file = "fonttools-4.48.1-cp310-cp310-win_amd64.whl", hash = "sha256:f7449493886da6a17472004d3818cc050ba3f4a0aa03fb47972e4fa5578e6703"},
+ {file = "fonttools-4.48.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:18b35fd1a850ed7233a99bbd6774485271756f717dac8b594958224b54118b61"},
+ {file = "fonttools-4.48.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cad5cfd044ea2e306fda44482b3dd32ee47830fa82dfa4679374b41baa294f5f"},
+ {file = "fonttools-4.48.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f30e605c7565d0da6f0aec75a30ec372072d016957cd8fc4469721a36ea59b7"},
+ {file = "fonttools-4.48.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aee76fd81a8571c68841d6ef0da750d5ff08ff2c5f025576473016f16ac3bcf7"},
+ {file = "fonttools-4.48.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5057ade278e67923000041e2b195c9ea53e87f227690d499b6a4edd3702f7f01"},
+ {file = "fonttools-4.48.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b10633aafc5932995a391ec07eba5e79f52af0003a1735b2306b3dab8a056d48"},
+ {file = "fonttools-4.48.1-cp311-cp311-win32.whl", hash = "sha256:0d533f89819f9b3ee2dbedf0fed3825c425850e32bdda24c558563c71be0064e"},
+ {file = "fonttools-4.48.1-cp311-cp311-win_amd64.whl", hash = "sha256:d20588466367f05025bb1efdf4e5d498ca6d14bde07b6928b79199c588800f0a"},
+ {file = "fonttools-4.48.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0a2417547462e468edf35b32e3dd06a6215ac26aa6316b41e03b8eeaf9f079ea"},
+ {file = "fonttools-4.48.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cf5a0cd974f85a80b74785db2d5c3c1fd6cc09a2ba3c837359b2b5da629ee1b0"},
+ {file = "fonttools-4.48.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0452fcbfbce752ba596737a7c5ec5cf76bc5f83847ce1781f4f90eab14ece252"},
+ {file = "fonttools-4.48.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578c00f93868f64a4102ecc5aa600a03b49162c654676c3fadc33de2ddb88a81"},
+ {file = "fonttools-4.48.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:63dc592a16cd08388d8c4c7502b59ac74190b23e16dfc863c69fe1ea74605b68"},
+ {file = "fonttools-4.48.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9b58638d8a85e3a1b32ec0a91d9f8171a877b4b81c408d4cb3257d0dee63e092"},
+ {file = "fonttools-4.48.1-cp312-cp312-win32.whl", hash = "sha256:d10979ef14a8beaaa32f613bb698743f7241d92f437a3b5e32356dfb9769c65d"},
+ {file = "fonttools-4.48.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdfd7557d1bd294a200bd211aa665ca3b02998dcc18f8211a5532da5b8fad5c5"},
+ {file = "fonttools-4.48.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3cdb9a92521b81bf717ebccf592bd0292e853244d84115bfb4db0c426de58348"},
+ {file = "fonttools-4.48.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b4ec6d42a7555f5ae35f3b805482f0aad0f1baeeef54859492ea3b782959d4a"},
+ {file = "fonttools-4.48.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:902e9c4e9928301912f34a6638741b8ae0b64824112b42aaf240e06b735774b1"},
+ {file = "fonttools-4.48.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8c8b54bd1420c184a995f980f1a8076f87363e2bb24239ef8c171a369d85a31"},
+ {file = "fonttools-4.48.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:12ee86abca46193359ea69216b3a724e90c66ab05ab220d39e3fc068c1eb72ac"},
+ {file = "fonttools-4.48.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6978bade7b6c0335095bdd0bd97f8f3d590d2877b370f17e03e0865241694eb5"},
+ {file = "fonttools-4.48.1-cp38-cp38-win32.whl", hash = "sha256:bcd77f89fc1a6b18428e7a55dde8ef56dae95640293bfb8f4e929929eba5e2a2"},
+ {file = "fonttools-4.48.1-cp38-cp38-win_amd64.whl", hash = "sha256:f40441437b039930428e04fb05ac3a132e77458fb57666c808d74a556779e784"},
+ {file = "fonttools-4.48.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0d2b01428f7da26f229a5656defc824427b741e454b4e210ad2b25ed6ea2aed4"},
+ {file = "fonttools-4.48.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:df48798f9a4fc4c315ab46e17873436c8746f5df6eddd02fad91299b2af7af95"},
+ {file = "fonttools-4.48.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2eb4167bde04e172a93cf22c875d8b0cff76a2491f67f5eb069566215302d45d"},
+ {file = "fonttools-4.48.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c900508c46274d32d308ae8e82335117f11aaee1f7d369ac16502c9a78930b0a"},
+ {file = "fonttools-4.48.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:594206b31c95fcfa65f484385171fabb4ec69f7d2d7f56d27f17db26b7a31814"},
+ {file = "fonttools-4.48.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:292922dc356d7f11f5063b4111a8b719efb8faea92a2a88ed296408d449d8c2e"},
+ {file = "fonttools-4.48.1-cp39-cp39-win32.whl", hash = "sha256:4709c5bf123ba10eac210d2d5c9027d3f472591d9f1a04262122710fa3d23199"},
+ {file = "fonttools-4.48.1-cp39-cp39-win_amd64.whl", hash = "sha256:63c73b9dd56a94a3cbd2f90544b5fca83666948a9e03370888994143b8d7c070"},
+ {file = "fonttools-4.48.1-py3-none-any.whl", hash = "sha256:e3e33862fc5261d46d9aae3544acb36203b1a337d00bdb5d3753aae50dac860e"},
+ {file = "fonttools-4.48.1.tar.gz", hash = "sha256:8b8a45254218679c7f1127812761e7854ed5c8e34349aebf581e8c9204e7495a"},
]
[package.extras]
-all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"]
+all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"]
graphite = ["lz4 (>=1.7.4.2)"]
-interpolatable = ["munkres", "scipy"]
-lxml = ["lxml (>=4.0,<5)"]
+interpolatable = ["munkres", "pycairo", "scipy"]
+lxml = ["lxml (>=4.0)"]
pathops = ["skia-pathops (>=0.5.0)"]
plot = ["matplotlib"]
repacker = ["uharfbuzz (>=0.23.0)"]
symfont = ["sympy"]
type1 = ["xattr"]
ufo = ["fs (>=2.2.0,<3)"]
-unicode = ["unicodedata2 (>=15.0.0)"]
+unicode = ["unicodedata2 (>=15.1.0)"]
woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"]
[[package]]
@@ -436,13 +488,13 @@ test = ["pytest (>=6.2.4)", "snapshottest (>=0.6.0)", "zombie-imp"]
[[package]]
name = "identify"
-version = "2.5.24"
+version = "2.5.34"
description = "File identification library for Python"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "identify-2.5.24-py2.py3-none-any.whl", hash = "sha256:986dbfb38b1140e763e413e6feb44cd731faf72d1909543178aa79b0e258265d"},
- {file = "identify-2.5.24.tar.gz", hash = "sha256:0aac67d5b4812498056d28a9a512a483f5085cc28640b02b258a59dac34301d4"},
+ {file = "identify-2.5.34-py2.py3-none-any.whl", hash = "sha256:a4316013779e433d08b96e5eabb7f641e6c7942e4ab5d4c509ebd2e7a8994aed"},
+ {file = "identify-2.5.34.tar.gz", hash = "sha256:ee17bc9d499899bc9eaec1ac7bf2dc9eedd480db9d88b96d123d3b64a9d34f5d"},
]
[package.extras]
@@ -450,13 +502,13 @@ license = ["ukkonen"]
[[package]]
name = "idna"
-version = "3.4"
+version = "3.6"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.5"
files = [
- {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
- {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+ {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"},
+ {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
]
[[package]]
@@ -498,13 +550,13 @@ files = [
[[package]]
name = "jinja2"
-version = "3.1.2"
+version = "3.1.3"
description = "A very fast and expressive template engine."
optional = false
python-versions = ">=3.7"
files = [
- {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
- {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
+ {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
+ {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
]
[package.dependencies]
@@ -515,172 +567,224 @@ i18n = ["Babel (>=2.7)"]
[[package]]
name = "kiwisolver"
-version = "1.4.4"
+version = "1.4.5"
description = "A fast implementation of the Cassowary constraint solver"
optional = false
python-versions = ">=3.7"
files = [
- {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"},
- {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"},
- {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"},
- {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"},
- {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"},
- {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"},
- {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"},
- {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"},
- {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"},
- {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"},
- {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"},
- {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"},
- {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"},
- {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"},
- {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"},
- {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"},
- {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"},
- {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"},
- {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"},
- {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"},
- {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"},
- {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"},
- {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"},
- {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"},
- {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"},
- {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"},
- {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"},
- {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"},
- {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"},
- {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"},
- {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"},
- {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"},
- {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"},
- {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"},
- {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"},
- {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"},
- {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"},
- {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"},
- {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"},
- {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"},
- {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"},
- {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"},
- {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"},
- {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"},
- {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"},
- {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"},
- {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"},
- {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"},
- {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"},
- {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"},
- {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"},
- {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"},
- {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"},
- {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"},
- {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"},
- {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"},
- {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"},
- {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"},
- {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"},
- {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"},
- {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"},
- {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"},
- {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"},
- {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"},
- {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"},
- {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"},
- {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"},
- {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"},
+ {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"},
+ {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"},
+ {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"},
+ {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"},
+ {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"},
+ {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"},
+ {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"},
+ {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"},
+ {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"},
+ {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"},
+ {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"},
+ {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"},
+ {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"},
+ {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"},
+ {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"},
+ {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"},
+ {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"},
+ {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"},
+ {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"},
+ {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"},
+ {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"},
+ {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"},
]
[[package]]
name = "lxml"
-version = "4.9.2"
+version = "4.9.4"
description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"
files = [
- {file = "lxml-4.9.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2"},
- {file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892"},
- {file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a"},
- {file = "lxml-4.9.2-cp27-cp27m-win32.whl", hash = "sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de"},
- {file = "lxml-4.9.2-cp27-cp27m-win_amd64.whl", hash = "sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3"},
- {file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50"},
- {file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975"},
- {file = "lxml-4.9.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c"},
- {file = "lxml-4.9.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a"},
- {file = "lxml-4.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4"},
- {file = "lxml-4.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4"},
- {file = "lxml-4.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7"},
- {file = "lxml-4.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184"},
- {file = "lxml-4.9.2-cp310-cp310-win32.whl", hash = "sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda"},
- {file = "lxml-4.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab"},
- {file = "lxml-4.9.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9"},
- {file = "lxml-4.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf"},
- {file = "lxml-4.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380"},
- {file = "lxml-4.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92"},
- {file = "lxml-4.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1"},
- {file = "lxml-4.9.2-cp311-cp311-win32.whl", hash = "sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33"},
- {file = "lxml-4.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd"},
- {file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0"},
- {file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e"},
- {file = "lxml-4.9.2-cp35-cp35m-win32.whl", hash = "sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df"},
- {file = "lxml-4.9.2-cp35-cp35m-win_amd64.whl", hash = "sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5"},
- {file = "lxml-4.9.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53"},
- {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7"},
- {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe"},
- {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c"},
- {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1"},
- {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e"},
- {file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74"},
- {file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38"},
- {file = "lxml-4.9.2-cp36-cp36m-win32.whl", hash = "sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5"},
- {file = "lxml-4.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3"},
- {file = "lxml-4.9.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03"},
- {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941"},
- {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726"},
- {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b"},
- {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894"},
- {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45"},
- {file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e"},
- {file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b"},
- {file = "lxml-4.9.2-cp37-cp37m-win32.whl", hash = "sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe"},
- {file = "lxml-4.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9"},
- {file = "lxml-4.9.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8"},
- {file = "lxml-4.9.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24"},
- {file = "lxml-4.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889"},
- {file = "lxml-4.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f"},
- {file = "lxml-4.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03"},
- {file = "lxml-4.9.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c"},
- {file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f"},
- {file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457"},
- {file = "lxml-4.9.2-cp38-cp38-win32.whl", hash = "sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b"},
- {file = "lxml-4.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7"},
- {file = "lxml-4.9.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1"},
- {file = "lxml-4.9.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140"},
- {file = "lxml-4.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4"},
- {file = "lxml-4.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf"},
- {file = "lxml-4.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947"},
- {file = "lxml-4.9.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5"},
- {file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5"},
- {file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2"},
- {file = "lxml-4.9.2-cp39-cp39-win32.whl", hash = "sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1"},
- {file = "lxml-4.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f"},
- {file = "lxml-4.9.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c"},
- {file = "lxml-4.9.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a"},
- {file = "lxml-4.9.2-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419"},
- {file = "lxml-4.9.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05"},
- {file = "lxml-4.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f"},
- {file = "lxml-4.9.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9"},
- {file = "lxml-4.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5"},
- {file = "lxml-4.9.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746"},
- {file = "lxml-4.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7"},
- {file = "lxml-4.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409"},
- {file = "lxml-4.9.2.tar.gz", hash = "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67"},
+ {file = "lxml-4.9.4-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e214025e23db238805a600f1f37bf9f9a15413c7bf5f9d6ae194f84980c78722"},
+ {file = "lxml-4.9.4-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ec53a09aee61d45e7dbe7e91252ff0491b6b5fee3d85b2d45b173d8ab453efc1"},
+ {file = "lxml-4.9.4-cp27-cp27m-win32.whl", hash = "sha256:7d1d6c9e74c70ddf524e3c09d9dc0522aba9370708c2cb58680ea40174800013"},
+ {file = "lxml-4.9.4-cp27-cp27m-win_amd64.whl", hash = "sha256:cb53669442895763e61df5c995f0e8361b61662f26c1b04ee82899c2789c8f69"},
+ {file = "lxml-4.9.4-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:647bfe88b1997d7ae8d45dabc7c868d8cb0c8412a6e730a7651050b8c7289cf2"},
+ {file = "lxml-4.9.4-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4d973729ce04784906a19108054e1fd476bc85279a403ea1a72fdb051c76fa48"},
+ {file = "lxml-4.9.4-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:056a17eaaf3da87a05523472ae84246f87ac2f29a53306466c22e60282e54ff8"},
+ {file = "lxml-4.9.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:aaa5c173a26960fe67daa69aa93d6d6a1cd714a6eb13802d4e4bd1d24a530644"},
+ {file = "lxml-4.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:647459b23594f370c1c01768edaa0ba0959afc39caeeb793b43158bb9bb6a663"},
+ {file = "lxml-4.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:bdd9abccd0927673cffe601d2c6cdad1c9321bf3437a2f507d6b037ef91ea307"},
+ {file = "lxml-4.9.4-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:00e91573183ad273e242db5585b52670eddf92bacad095ce25c1e682da14ed91"},
+ {file = "lxml-4.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a602ed9bd2c7d85bd58592c28e101bd9ff9c718fbde06545a70945ffd5d11868"},
+ {file = "lxml-4.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:de362ac8bc962408ad8fae28f3967ce1a262b5d63ab8cefb42662566737f1dc7"},
+ {file = "lxml-4.9.4-cp310-cp310-win32.whl", hash = "sha256:33714fcf5af4ff7e70a49731a7cc8fd9ce910b9ac194f66eaa18c3cc0a4c02be"},
+ {file = "lxml-4.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:d3caa09e613ece43ac292fbed513a4bce170681a447d25ffcbc1b647d45a39c5"},
+ {file = "lxml-4.9.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:359a8b09d712df27849e0bcb62c6a3404e780b274b0b7e4c39a88826d1926c28"},
+ {file = "lxml-4.9.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:43498ea734ccdfb92e1886dfedaebeb81178a241d39a79d5351ba2b671bff2b2"},
+ {file = "lxml-4.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4855161013dfb2b762e02b3f4d4a21cc7c6aec13c69e3bffbf5022b3e708dd97"},
+ {file = "lxml-4.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c71b5b860c5215fdbaa56f715bc218e45a98477f816b46cfde4a84d25b13274e"},
+ {file = "lxml-4.9.4-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9a2b5915c333e4364367140443b59f09feae42184459b913f0f41b9fed55794a"},
+ {file = "lxml-4.9.4-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d82411dbf4d3127b6cde7da0f9373e37ad3a43e89ef374965465928f01c2b979"},
+ {file = "lxml-4.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:273473d34462ae6e97c0f4e517bd1bf9588aa67a1d47d93f760a1282640e24ac"},
+ {file = "lxml-4.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:389d2b2e543b27962990ab529ac6720c3dded588cc6d0f6557eec153305a3622"},
+ {file = "lxml-4.9.4-cp311-cp311-win32.whl", hash = "sha256:8aecb5a7f6f7f8fe9cac0bcadd39efaca8bbf8d1bf242e9f175cbe4c925116c3"},
+ {file = "lxml-4.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:c7721a3ef41591341388bb2265395ce522aba52f969d33dacd822da8f018aff8"},
+ {file = "lxml-4.9.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:dbcb2dc07308453db428a95a4d03259bd8caea97d7f0776842299f2d00c72fc8"},
+ {file = "lxml-4.9.4-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:01bf1df1db327e748dcb152d17389cf6d0a8c5d533ef9bab781e9d5037619229"},
+ {file = "lxml-4.9.4-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e8f9f93a23634cfafbad6e46ad7d09e0f4a25a2400e4a64b1b7b7c0fbaa06d9d"},
+ {file = "lxml-4.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3f3f00a9061605725df1816f5713d10cd94636347ed651abdbc75828df302b20"},
+ {file = "lxml-4.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:953dd5481bd6252bd480d6ec431f61d7d87fdcbbb71b0d2bdcfc6ae00bb6fb10"},
+ {file = "lxml-4.9.4-cp312-cp312-win32.whl", hash = "sha256:266f655d1baff9c47b52f529b5f6bec33f66042f65f7c56adde3fcf2ed62ae8b"},
+ {file = "lxml-4.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:f1faee2a831fe249e1bae9cbc68d3cd8a30f7e37851deee4d7962b17c410dd56"},
+ {file = "lxml-4.9.4-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:23d891e5bdc12e2e506e7d225d6aa929e0a0368c9916c1fddefab88166e98b20"},
+ {file = "lxml-4.9.4-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e96a1788f24d03e8d61679f9881a883ecdf9c445a38f9ae3f3f193ab6c591c66"},
+ {file = "lxml-4.9.4-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:5557461f83bb7cc718bc9ee1f7156d50e31747e5b38d79cf40f79ab1447afd2d"},
+ {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:fdb325b7fba1e2c40b9b1db407f85642e32404131c08480dd652110fc908561b"},
+ {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d74d4a3c4b8f7a1f676cedf8e84bcc57705a6d7925e6daef7a1e54ae543a197"},
+ {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ac7674d1638df129d9cb4503d20ffc3922bd463c865ef3cb412f2c926108e9a4"},
+ {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:ddd92e18b783aeb86ad2132d84a4b795fc5ec612e3545c1b687e7747e66e2b53"},
+ {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bd9ac6e44f2db368ef8986f3989a4cad3de4cd55dbdda536e253000c801bcc7"},
+ {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bc354b1393dce46026ab13075f77b30e40b61b1a53e852e99d3cc5dd1af4bc85"},
+ {file = "lxml-4.9.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f836f39678cb47c9541f04d8ed4545719dc31ad850bf1832d6b4171e30d65d23"},
+ {file = "lxml-4.9.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:9c131447768ed7bc05a02553d939e7f0e807e533441901dd504e217b76307745"},
+ {file = "lxml-4.9.4-cp36-cp36m-win32.whl", hash = "sha256:bafa65e3acae612a7799ada439bd202403414ebe23f52e5b17f6ffc2eb98c2be"},
+ {file = "lxml-4.9.4-cp36-cp36m-win_amd64.whl", hash = "sha256:6197c3f3c0b960ad033b9b7d611db11285bb461fc6b802c1dd50d04ad715c225"},
+ {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:7b378847a09d6bd46047f5f3599cdc64fcb4cc5a5a2dd0a2af610361fbe77b16"},
+ {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:1343df4e2e6e51182aad12162b23b0a4b3fd77f17527a78c53f0f23573663545"},
+ {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6dbdacf5752fbd78ccdb434698230c4f0f95df7dd956d5f205b5ed6911a1367c"},
+ {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:506becdf2ecaebaf7f7995f776394fcc8bd8a78022772de66677c84fb02dd33d"},
+ {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca8e44b5ba3edb682ea4e6185b49661fc22b230cf811b9c13963c9f982d1d964"},
+ {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9d9d5726474cbbef279fd709008f91a49c4f758bec9c062dfbba88eab00e3ff9"},
+ {file = "lxml-4.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:bbdd69e20fe2943b51e2841fc1e6a3c1de460d630f65bde12452d8c97209464d"},
+ {file = "lxml-4.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8671622256a0859f5089cbe0ce4693c2af407bc053dcc99aadff7f5310b4aa02"},
+ {file = "lxml-4.9.4-cp37-cp37m-win32.whl", hash = "sha256:dd4fda67f5faaef4f9ee5383435048ee3e11ad996901225ad7615bc92245bc8e"},
+ {file = "lxml-4.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6bee9c2e501d835f91460b2c904bc359f8433e96799f5c2ff20feebd9bb1e590"},
+ {file = "lxml-4.9.4-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:1f10f250430a4caf84115b1e0f23f3615566ca2369d1962f82bef40dd99cd81a"},
+ {file = "lxml-4.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:3b505f2bbff50d261176e67be24e8909e54b5d9d08b12d4946344066d66b3e43"},
+ {file = "lxml-4.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:1449f9451cd53e0fd0a7ec2ff5ede4686add13ac7a7bfa6988ff6d75cff3ebe2"},
+ {file = "lxml-4.9.4-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:4ece9cca4cd1c8ba889bfa67eae7f21d0d1a2e715b4d5045395113361e8c533d"},
+ {file = "lxml-4.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59bb5979f9941c61e907ee571732219fa4774d5a18f3fa5ff2df963f5dfaa6bc"},
+ {file = "lxml-4.9.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b1980dbcaad634fe78e710c8587383e6e3f61dbe146bcbfd13a9c8ab2d7b1192"},
+ {file = "lxml-4.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9ae6c3363261021144121427b1552b29e7b59de9d6a75bf51e03bc072efb3c37"},
+ {file = "lxml-4.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bcee502c649fa6351b44bb014b98c09cb00982a475a1912a9881ca28ab4f9cd9"},
+ {file = "lxml-4.9.4-cp38-cp38-win32.whl", hash = "sha256:a8edae5253efa75c2fc79a90068fe540b197d1c7ab5803b800fccfe240eed33c"},
+ {file = "lxml-4.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:701847a7aaefef121c5c0d855b2affa5f9bd45196ef00266724a80e439220e46"},
+ {file = "lxml-4.9.4-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:f610d980e3fccf4394ab3806de6065682982f3d27c12d4ce3ee46a8183d64a6a"},
+ {file = "lxml-4.9.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:aa9b5abd07f71b081a33115d9758ef6077924082055005808f68feccb27616bd"},
+ {file = "lxml-4.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:365005e8b0718ea6d64b374423e870648ab47c3a905356ab6e5a5ff03962b9a9"},
+ {file = "lxml-4.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:16b9ec51cc2feab009e800f2c6327338d6ee4e752c76e95a35c4465e80390ccd"},
+ {file = "lxml-4.9.4-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:a905affe76f1802edcac554e3ccf68188bea16546071d7583fb1b693f9cf756b"},
+ {file = "lxml-4.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fd814847901df6e8de13ce69b84c31fc9b3fb591224d6762d0b256d510cbf382"},
+ {file = "lxml-4.9.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:91bbf398ac8bb7d65a5a52127407c05f75a18d7015a270fdd94bbcb04e65d573"},
+ {file = "lxml-4.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f99768232f036b4776ce419d3244a04fe83784bce871b16d2c2e984c7fcea847"},
+ {file = "lxml-4.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bb5bd6212eb0edfd1e8f254585290ea1dadc3687dd8fd5e2fd9a87c31915cdab"},
+ {file = "lxml-4.9.4-cp39-cp39-win32.whl", hash = "sha256:88f7c383071981c74ec1998ba9b437659e4fd02a3c4a4d3efc16774eb108d0ec"},
+ {file = "lxml-4.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:936e8880cc00f839aa4173f94466a8406a96ddce814651075f95837316369899"},
+ {file = "lxml-4.9.4-pp310-pypy310_pp73-macosx_11_0_x86_64.whl", hash = "sha256:f6c35b2f87c004270fa2e703b872fcc984d714d430b305145c39d53074e1ffe0"},
+ {file = "lxml-4.9.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:606d445feeb0856c2b424405236a01c71af7c97e5fe42fbc778634faef2b47e4"},
+ {file = "lxml-4.9.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a1bdcbebd4e13446a14de4dd1825f1e778e099f17f79718b4aeaf2403624b0f7"},
+ {file = "lxml-4.9.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0a08c89b23117049ba171bf51d2f9c5f3abf507d65d016d6e0fa2f37e18c0fc5"},
+ {file = "lxml-4.9.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:232fd30903d3123be4c435fb5159938c6225ee8607b635a4d3fca847003134ba"},
+ {file = "lxml-4.9.4-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:231142459d32779b209aa4b4d460b175cadd604fed856f25c1571a9d78114771"},
+ {file = "lxml-4.9.4-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:520486f27f1d4ce9654154b4494cf9307b495527f3a2908ad4cb48e4f7ed7ef7"},
+ {file = "lxml-4.9.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:562778586949be7e0d7435fcb24aca4810913771f845d99145a6cee64d5b67ca"},
+ {file = "lxml-4.9.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a9e7c6d89c77bb2770c9491d988f26a4b161d05c8ca58f63fb1f1b6b9a74be45"},
+ {file = "lxml-4.9.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:786d6b57026e7e04d184313c1359ac3d68002c33e4b1042ca58c362f1d09ff58"},
+ {file = "lxml-4.9.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:95ae6c5a196e2f239150aa4a479967351df7f44800c93e5a975ec726fef005e2"},
+ {file = "lxml-4.9.4-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:9b556596c49fa1232b0fff4b0e69b9d4083a502e60e404b44341e2f8fb7187f5"},
+ {file = "lxml-4.9.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:cc02c06e9e320869d7d1bd323df6dd4281e78ac2e7f8526835d3d48c69060683"},
+ {file = "lxml-4.9.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:857d6565f9aa3464764c2cb6a2e3c2e75e1970e877c188f4aeae45954a314e0c"},
+ {file = "lxml-4.9.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c42ae7e010d7d6bc51875d768110c10e8a59494855c3d4c348b068f5fb81fdcd"},
+ {file = "lxml-4.9.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f10250bb190fb0742e3e1958dd5c100524c2cc5096c67c8da51233f7448dc137"},
+ {file = "lxml-4.9.4.tar.gz", hash = "sha256:b1541e50b78e15fa06a2670157a1962ef06591d4c998b998047fff5e3236880e"},
]
[package.extras]
cssselect = ["cssselect (>=0.7)"]
html5 = ["html5lib"]
htmlsoup = ["BeautifulSoup4"]
-source = ["Cython (>=0.29.7)"]
+source = ["Cython (==0.29.37)"]
[[package]]
name = "markdown-it-py"
@@ -708,131 +812,118 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
[[package]]
name = "markupsafe"
-version = "2.1.3"
+version = "2.1.5"
description = "Safely add untrusted strings to HTML/XML markup."
optional = false
python-versions = ">=3.7"
files = [
- {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
- {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
+ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
]
[[package]]
name = "matplotlib"
-version = "3.7.1"
+version = "3.8.2"
description = "Python plotting package"
optional = false
-python-versions = ">=3.8"
-files = [
- {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:95cbc13c1fc6844ab8812a525bbc237fa1470863ff3dace7352e910519e194b1"},
- {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:08308bae9e91aca1ec6fd6dda66237eef9f6294ddb17f0d0b3c863169bf82353"},
- {file = "matplotlib-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:544764ba51900da4639c0f983b323d288f94f65f4024dc40ecb1542d74dc0500"},
- {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d94989191de3fcc4e002f93f7f1be5da476385dde410ddafbb70686acf00ea"},
- {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99bc9e65901bb9a7ce5e7bb24af03675cbd7c70b30ac670aa263240635999a4"},
- {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb7d248c34a341cd4c31a06fd34d64306624c8cd8d0def7abb08792a5abfd556"},
- {file = "matplotlib-3.7.1-cp310-cp310-win32.whl", hash = "sha256:ce463ce590f3825b52e9fe5c19a3c6a69fd7675a39d589e8b5fbe772272b3a24"},
- {file = "matplotlib-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d7bc90727351fb841e4d8ae620d2d86d8ed92b50473cd2b42ce9186104ecbba"},
- {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:770a205966d641627fd5cf9d3cb4b6280a716522cd36b8b284a8eb1581310f61"},
- {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f67bfdb83a8232cb7a92b869f9355d677bce24485c460b19d01970b64b2ed476"},
- {file = "matplotlib-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2bf092f9210e105f414a043b92af583c98f50050559616930d884387d0772aba"},
- {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89768d84187f31717349c6bfadc0e0d8c321e8eb34522acec8a67b1236a66332"},
- {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83111e6388dec67822e2534e13b243cc644c7494a4bb60584edbff91585a83c6"},
- {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a867bf73a7eb808ef2afbca03bcdb785dae09595fbe550e1bab0cd023eba3de0"},
- {file = "matplotlib-3.7.1-cp311-cp311-win32.whl", hash = "sha256:fbdeeb58c0cf0595efe89c05c224e0a502d1aa6a8696e68a73c3efc6bc354304"},
- {file = "matplotlib-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c0bd19c72ae53e6ab979f0ac6a3fafceb02d2ecafa023c5cca47acd934d10be7"},
- {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:6eb88d87cb2c49af00d3bbc33a003f89fd9f78d318848da029383bfc08ecfbfb"},
- {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:cf0e4f727534b7b1457898c4f4ae838af1ef87c359b76dcd5330fa31893a3ac7"},
- {file = "matplotlib-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46a561d23b91f30bccfd25429c3c706afe7d73a5cc64ef2dfaf2b2ac47c1a5dc"},
- {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8704726d33e9aa8a6d5215044b8d00804561971163563e6e6591f9dcf64340cc"},
- {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4cf327e98ecf08fcbb82685acaf1939d3338548620ab8dfa02828706402c34de"},
- {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:617f14ae9d53292ece33f45cba8503494ee199a75b44de7717964f70637a36aa"},
- {file = "matplotlib-3.7.1-cp38-cp38-win32.whl", hash = "sha256:7c9a4b2da6fac77bcc41b1ea95fadb314e92508bf5493ceff058e727e7ecf5b0"},
- {file = "matplotlib-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:14645aad967684e92fc349493fa10c08a6da514b3d03a5931a1bac26e6792bd1"},
- {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:81a6b377ea444336538638d31fdb39af6be1a043ca5e343fe18d0f17e098770b"},
- {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28506a03bd7f3fe59cd3cd4ceb2a8d8a2b1db41afede01f66c42561b9be7b4b7"},
- {file = "matplotlib-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c587963b85ce41e0a8af53b9b2de8dddbf5ece4c34553f7bd9d066148dc719c"},
- {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8bf26ade3ff0f27668989d98c8435ce9327d24cffb7f07d24ef609e33d582439"},
- {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:def58098f96a05f90af7e92fd127d21a287068202aa43b2a93476170ebd99e87"},
- {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f883a22a56a84dba3b588696a2b8a1ab0d2c3d41be53264115c71b0a942d8fdb"},
- {file = "matplotlib-3.7.1-cp39-cp39-win32.whl", hash = "sha256:4f99e1b234c30c1e9714610eb0c6d2f11809c9c78c984a613ae539ea2ad2eb4b"},
- {file = "matplotlib-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:3ba2af245e36990facf67fde840a760128ddd71210b2ab6406e640188d69d136"},
- {file = "matplotlib-3.7.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3032884084f541163f295db8a6536e0abb0db464008fadca6c98aaf84ccf4717"},
- {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a2cb34336110e0ed8bb4f650e817eed61fa064acbefeb3591f1b33e3a84fd96"},
- {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b867e2f952ed592237a1828f027d332d8ee219ad722345b79a001f49df0936eb"},
- {file = "matplotlib-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bfb8c8ea253be947ccb2bc2d1bb3862c2bccc662ad1b4626e1f5e004557042"},
- {file = "matplotlib-3.7.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:438196cdf5dc8d39b50a45cb6e3f6274edbcf2254f85fa9b895bf85851c3a613"},
- {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21e9cff1a58d42e74d01153360de92b326708fb205250150018a52c70f43c290"},
- {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d4725d70b7c03e082bbb8a34639ede17f333d7247f56caceb3801cb6ff703d"},
- {file = "matplotlib-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:97cc368a7268141afb5690760921765ed34867ffb9655dd325ed207af85c7529"},
- {file = "matplotlib-3.7.1.tar.gz", hash = "sha256:7b73305f25eab4541bd7ee0b96d87e53ae9c9f1823be5659b806cd85786fe882"},
+python-versions = ">=3.9"
+files = [
+ {file = "matplotlib-3.8.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:09796f89fb71a0c0e1e2f4bdaf63fb2cefc84446bb963ecdeb40dfee7dfa98c7"},
+ {file = "matplotlib-3.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9c6976748a25e8b9be51ea028df49b8e561eed7809146da7a47dbecebab367"},
+ {file = "matplotlib-3.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b78e4f2cedf303869b782071b55fdde5987fda3038e9d09e58c91cc261b5ad18"},
+ {file = "matplotlib-3.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e208f46cf6576a7624195aa047cb344a7f802e113bb1a06cfd4bee431de5e31"},
+ {file = "matplotlib-3.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46a569130ff53798ea5f50afce7406e91fdc471ca1e0e26ba976a8c734c9427a"},
+ {file = "matplotlib-3.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:830f00640c965c5b7f6bc32f0d4ce0c36dfe0379f7dd65b07a00c801713ec40a"},
+ {file = "matplotlib-3.8.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d86593ccf546223eb75a39b44c32788e6f6440d13cfc4750c1c15d0fcb850b63"},
+ {file = "matplotlib-3.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a5430836811b7652991939012f43d2808a2db9b64ee240387e8c43e2e5578c8"},
+ {file = "matplotlib-3.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9576723858a78751d5aacd2497b8aef29ffea6d1c95981505877f7ac28215c6"},
+ {file = "matplotlib-3.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ba9cbd8ac6cf422f3102622b20f8552d601bf8837e49a3afed188d560152788"},
+ {file = "matplotlib-3.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:03f9d160a29e0b65c0790bb07f4f45d6a181b1ac33eb1bb0dd225986450148f0"},
+ {file = "matplotlib-3.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:3773002da767f0a9323ba1a9b9b5d00d6257dbd2a93107233167cfb581f64717"},
+ {file = "matplotlib-3.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4c318c1e95e2f5926fba326f68177dee364aa791d6df022ceb91b8221bd0a627"},
+ {file = "matplotlib-3.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:091275d18d942cf1ee9609c830a1bc36610607d8223b1b981c37d5c9fc3e46a4"},
+ {file = "matplotlib-3.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b0f3b8ea0e99e233a4bcc44590f01604840d833c280ebb8fe5554fd3e6cfe8d"},
+ {file = "matplotlib-3.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7b1704a530395aaf73912be741c04d181f82ca78084fbd80bc737be04848331"},
+ {file = "matplotlib-3.8.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533b0e3b0c6768eef8cbe4b583731ce25a91ab54a22f830db2b031e83cca9213"},
+ {file = "matplotlib-3.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:0f4fc5d72b75e2c18e55eb32292659cf731d9d5b312a6eb036506304f4675630"},
+ {file = "matplotlib-3.8.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:deaed9ad4da0b1aea77fe0aa0cebb9ef611c70b3177be936a95e5d01fa05094f"},
+ {file = "matplotlib-3.8.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:172f4d0fbac3383d39164c6caafd3255ce6fa58f08fc392513a0b1d3b89c4f89"},
+ {file = "matplotlib-3.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7d36c2209d9136cd8e02fab1c0ddc185ce79bc914c45054a9f514e44c787917"},
+ {file = "matplotlib-3.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5864bdd7da445e4e5e011b199bb67168cdad10b501750367c496420f2ad00843"},
+ {file = "matplotlib-3.8.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ef8345b48e95cee45ff25192ed1f4857273117917a4dcd48e3905619bcd9c9b8"},
+ {file = "matplotlib-3.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:7c48d9e221b637c017232e3760ed30b4e8d5dfd081daf327e829bf2a72c731b4"},
+ {file = "matplotlib-3.8.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:aa11b3c6928a1e496c1a79917d51d4cd5d04f8a2e75f21df4949eeefdf697f4b"},
+ {file = "matplotlib-3.8.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1095fecf99eeb7384dabad4bf44b965f929a5f6079654b681193edf7169ec20"},
+ {file = "matplotlib-3.8.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:bddfb1db89bfaa855912261c805bd0e10218923cc262b9159a49c29a7a1c1afa"},
+ {file = "matplotlib-3.8.2.tar.gz", hash = "sha256:01a978b871b881ee76017152f1f1a0cbf6bd5f7b8ff8c96df0df1bd57d8755a1"},
]
[package.dependencies]
contourpy = ">=1.0.1"
cycler = ">=0.10"
fonttools = ">=4.22.0"
-kiwisolver = ">=1.0.1"
-numpy = ">=1.20"
+kiwisolver = ">=1.3.1"
+numpy = ">=1.21,<2"
packaging = ">=20.0"
-pillow = ">=6.2.0"
+pillow = ">=8"
pyparsing = ">=2.3.1"
python-dateutil = ">=2.7"
@@ -874,232 +965,252 @@ setuptools = "*"
[[package]]
name = "numpy"
-version = "1.24.3"
+version = "1.26.4"
description = "Fundamental package for array computing in Python"
optional = false
-python-versions = ">=3.8"
-files = [
- {file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"},
- {file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"},
- {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"},
- {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"},
- {file = "numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"},
- {file = "numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"},
- {file = "numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"},
- {file = "numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"},
- {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"},
- {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"},
- {file = "numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"},
- {file = "numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"},
- {file = "numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"},
- {file = "numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"},
- {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"},
- {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"},
- {file = "numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"},
- {file = "numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"},
- {file = "numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"},
- {file = "numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"},
- {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"},
- {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"},
- {file = "numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"},
- {file = "numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"},
- {file = "numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"},
- {file = "numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"},
- {file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"},
- {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"},
+python-versions = ">=3.9"
+files = [
+ {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"},
+ {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"},
+ {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"},
+ {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"},
+ {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"},
+ {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"},
+ {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"},
+ {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"},
+ {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"},
+ {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"},
+ {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"},
+ {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"},
+ {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"},
+ {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"},
+ {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"},
+ {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"},
+ {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"},
+ {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"},
+ {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"},
+ {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"},
+ {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"},
+ {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"},
+ {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"},
+ {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"},
+ {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"},
+ {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"},
+ {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"},
+ {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"},
+ {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"},
+ {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"},
+ {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"},
+ {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"},
+ {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"},
+ {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"},
+ {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"},
+ {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"},
]
[[package]]
name = "packaging"
-version = "23.1"
+version = "23.2"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.7"
files = [
- {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
- {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
+ {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
+ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
]
[[package]]
name = "pandas"
-version = "2.0.2"
+version = "2.2.0"
description = "Powerful data structures for data analysis, time series, and statistics"
optional = false
-python-versions = ">=3.8"
-files = [
- {file = "pandas-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ebb9f1c22ddb828e7fd017ea265a59d80461d5a79154b49a4207bd17514d122"},
- {file = "pandas-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eb09a242184092f424b2edd06eb2b99d06dc07eeddff9929e8667d4ed44e181"},
- {file = "pandas-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7319b6e68de14e6209460f72a8d1ef13c09fb3d3ef6c37c1e65b35d50b5c145"},
- {file = "pandas-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd46bde7309088481b1cf9c58e3f0e204b9ff9e3244f441accd220dd3365ce7c"},
- {file = "pandas-2.0.2-cp310-cp310-win32.whl", hash = "sha256:51a93d422fbb1bd04b67639ba4b5368dffc26923f3ea32a275d2cc450f1d1c86"},
- {file = "pandas-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:66d00300f188fa5de73f92d5725ced162488f6dc6ad4cecfe4144ca29debe3b8"},
- {file = "pandas-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02755de164da6827764ceb3bbc5f64b35cb12394b1024fdf88704d0fa06e0e2f"},
- {file = "pandas-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0a1e0576611641acde15c2322228d138258f236d14b749ad9af498ab69089e2d"},
- {file = "pandas-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6b5f14cd24a2ed06e14255ff40fe2ea0cfaef79a8dd68069b7ace74bd6acbba"},
- {file = "pandas-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50e451932b3011b61d2961b4185382c92cc8c6ee4658dcd4f320687bb2d000ee"},
- {file = "pandas-2.0.2-cp311-cp311-win32.whl", hash = "sha256:7b21cb72958fc49ad757685db1919021d99650d7aaba676576c9e88d3889d456"},
- {file = "pandas-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:c4af689352c4fe3d75b2834933ee9d0ccdbf5d7a8a7264f0ce9524e877820c08"},
- {file = "pandas-2.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:69167693cb8f9b3fc060956a5d0a0a8dbfed5f980d9fd2c306fb5b9c855c814c"},
- {file = "pandas-2.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:30a89d0fec4263ccbf96f68592fd668939481854d2ff9da709d32a047689393b"},
- {file = "pandas-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a18e5c72b989ff0f7197707ceddc99828320d0ca22ab50dd1b9e37db45b010c0"},
- {file = "pandas-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7376e13d28eb16752c398ca1d36ccfe52bf7e887067af9a0474de6331dd948d2"},
- {file = "pandas-2.0.2-cp38-cp38-win32.whl", hash = "sha256:6d6d10c2142d11d40d6e6c0a190b1f89f525bcf85564707e31b0a39e3b398e08"},
- {file = "pandas-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:e69140bc2d29a8556f55445c15f5794490852af3de0f609a24003ef174528b79"},
- {file = "pandas-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b42b120458636a981077cfcfa8568c031b3e8709701315e2bfa866324a83efa8"},
- {file = "pandas-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f908a77cbeef9bbd646bd4b81214cbef9ac3dda4181d5092a4aa9797d1bc7774"},
- {file = "pandas-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:713f2f70abcdade1ddd68fc91577cb090b3544b07ceba78a12f799355a13ee44"},
- {file = "pandas-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf3f0c361a4270185baa89ec7ab92ecaa355fe783791457077473f974f654df5"},
- {file = "pandas-2.0.2-cp39-cp39-win32.whl", hash = "sha256:598e9020d85a8cdbaa1815eb325a91cfff2bb2b23c1442549b8a3668e36f0f77"},
- {file = "pandas-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:77550c8909ebc23e56a89f91b40ad01b50c42cfbfab49b3393694a50549295ea"},
- {file = "pandas-2.0.2.tar.gz", hash = "sha256:dd5476b6c3fe410ee95926873f377b856dbc4e81a9c605a0dc05aaccc6a7c6c6"},
+python-versions = ">=3.9"
+files = [
+ {file = "pandas-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8108ee1712bb4fa2c16981fba7e68b3f6ea330277f5ca34fa8d557e986a11670"},
+ {file = "pandas-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:736da9ad4033aeab51d067fc3bd69a0ba36f5a60f66a527b3d72e2030e63280a"},
+ {file = "pandas-2.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38e0b4fc3ddceb56ec8a287313bc22abe17ab0eb184069f08fc6a9352a769b18"},
+ {file = "pandas-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20404d2adefe92aed3b38da41d0847a143a09be982a31b85bc7dd565bdba0f4e"},
+ {file = "pandas-2.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ea3ee3f125032bfcade3a4cf85131ed064b4f8dd23e5ce6fa16473e48ebcaf5"},
+ {file = "pandas-2.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9670b3ac00a387620489dfc1bca66db47a787f4e55911f1293063a78b108df1"},
+ {file = "pandas-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:5a946f210383c7e6d16312d30b238fd508d80d927014f3b33fb5b15c2f895430"},
+ {file = "pandas-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a1b438fa26b208005c997e78672f1aa8138f67002e833312e6230f3e57fa87d5"},
+ {file = "pandas-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8ce2fbc8d9bf303ce54a476116165220a1fedf15985b09656b4b4275300e920b"},
+ {file = "pandas-2.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2707514a7bec41a4ab81f2ccce8b382961a29fbe9492eab1305bb075b2b1ff4f"},
+ {file = "pandas-2.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85793cbdc2d5bc32620dc8ffa715423f0c680dacacf55056ba13454a5be5de88"},
+ {file = "pandas-2.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cfd6c2491dc821b10c716ad6776e7ab311f7df5d16038d0b7458bc0b67dc10f3"},
+ {file = "pandas-2.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a146b9dcacc3123aa2b399df1a284de5f46287a4ab4fbfc237eac98a92ebcb71"},
+ {file = "pandas-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbc1b53c0e1fdf16388c33c3cca160f798d38aea2978004dd3f4d3dec56454c9"},
+ {file = "pandas-2.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a41d06f308a024981dcaa6c41f2f2be46a6b186b902c94c2674e8cb5c42985bc"},
+ {file = "pandas-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:159205c99d7a5ce89ecfc37cb08ed179de7783737cea403b295b5eda8e9c56d1"},
+ {file = "pandas-2.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1e1f3861ea9132b32f2133788f3b14911b68102d562715d71bd0013bc45440"},
+ {file = "pandas-2.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:761cb99b42a69005dec2b08854fb1d4888fdf7b05db23a8c5a099e4b886a2106"},
+ {file = "pandas-2.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a20628faaf444da122b2a64b1e5360cde100ee6283ae8effa0d8745153809a2e"},
+ {file = "pandas-2.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f5be5d03ea2073627e7111f61b9f1f0d9625dc3c4d8dda72cc827b0c58a1d042"},
+ {file = "pandas-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:a626795722d893ed6aacb64d2401d017ddc8a2341b49e0384ab9bf7112bdec30"},
+ {file = "pandas-2.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9f66419d4a41132eb7e9a73dcec9486cf5019f52d90dd35547af11bc58f8637d"},
+ {file = "pandas-2.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:57abcaeda83fb80d447f28ab0cc7b32b13978f6f733875ebd1ed14f8fbc0f4ab"},
+ {file = "pandas-2.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e60f1f7dba3c2d5ca159e18c46a34e7ca7247a73b5dd1a22b6d59707ed6b899a"},
+ {file = "pandas-2.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb61dc8567b798b969bcc1fc964788f5a68214d333cade8319c7ab33e2b5d88a"},
+ {file = "pandas-2.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:52826b5f4ed658fa2b729264d63f6732b8b29949c7fd234510d57c61dbeadfcd"},
+ {file = "pandas-2.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bde2bc699dbd80d7bc7f9cab1e23a95c4375de615860ca089f34e7c64f4a8de7"},
+ {file = "pandas-2.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:3de918a754bbf2da2381e8a3dcc45eede8cd7775b047b923f9006d5f876802ae"},
+ {file = "pandas-2.2.0.tar.gz", hash = "sha256:30b83f7c3eb217fb4d1b494a57a2fda5444f17834f5df2de6b2ffff68dc3c8e2"},
]
[package.dependencies]
numpy = [
- {version = ">=1.23.2", markers = "python_version >= \"3.11\""},
- {version = ">=1.21.0", markers = "python_version >= \"3.10\" and python_version < \"3.11\""},
+ {version = ">=1.22.4,<2", markers = "python_version < \"3.11\""},
+ {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""},
+ {version = ">=1.26.0,<2", markers = "python_version >= \"3.12\""},
]
python-dateutil = ">=2.8.2"
pytz = ">=2020.1"
-tzdata = ">=2022.1"
+tzdata = ">=2022.7"
[package.extras]
-all = ["PyQt5 (>=5.15.1)", "SQLAlchemy (>=1.4.16)", "beautifulsoup4 (>=4.9.3)", "bottleneck (>=1.3.2)", "brotlipy (>=0.7.0)", "fastparquet (>=0.6.3)", "fsspec (>=2021.07.0)", "gcsfs (>=2021.07.0)", "html5lib (>=1.1)", "hypothesis (>=6.34.2)", "jinja2 (>=3.0.0)", "lxml (>=4.6.3)", "matplotlib (>=3.6.1)", "numba (>=0.53.1)", "numexpr (>=2.7.3)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pandas-gbq (>=0.15.0)", "psycopg2 (>=2.8.6)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.2)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "python-snappy (>=0.6.0)", "pyxlsb (>=1.0.8)", "qtpy (>=2.2.0)", "s3fs (>=2021.08.0)", "scipy (>=1.7.1)", "tables (>=3.6.1)", "tabulate (>=0.8.9)", "xarray (>=0.21.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)", "zstandard (>=0.15.2)"]
-aws = ["s3fs (>=2021.08.0)"]
-clipboard = ["PyQt5 (>=5.15.1)", "qtpy (>=2.2.0)"]
-compression = ["brotlipy (>=0.7.0)", "python-snappy (>=0.6.0)", "zstandard (>=0.15.2)"]
-computation = ["scipy (>=1.7.1)", "xarray (>=0.21.0)"]
-excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pyxlsb (>=1.0.8)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)"]
-feather = ["pyarrow (>=7.0.0)"]
-fss = ["fsspec (>=2021.07.0)"]
-gcp = ["gcsfs (>=2021.07.0)", "pandas-gbq (>=0.15.0)"]
-hdf5 = ["tables (>=3.6.1)"]
-html = ["beautifulsoup4 (>=4.9.3)", "html5lib (>=1.1)", "lxml (>=4.6.3)"]
-mysql = ["SQLAlchemy (>=1.4.16)", "pymysql (>=1.0.2)"]
-output-formatting = ["jinja2 (>=3.0.0)", "tabulate (>=0.8.9)"]
-parquet = ["pyarrow (>=7.0.0)"]
-performance = ["bottleneck (>=1.3.2)", "numba (>=0.53.1)", "numexpr (>=2.7.1)"]
-plot = ["matplotlib (>=3.6.1)"]
-postgresql = ["SQLAlchemy (>=1.4.16)", "psycopg2 (>=2.8.6)"]
-spss = ["pyreadstat (>=1.1.2)"]
-sql-other = ["SQLAlchemy (>=1.4.16)"]
-test = ["hypothesis (>=6.34.2)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"]
-xml = ["lxml (>=4.6.3)"]
+all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"]
+aws = ["s3fs (>=2022.11.0)"]
+clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"]
+compression = ["zstandard (>=0.19.0)"]
+computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"]
+consortium-standard = ["dataframe-api-compat (>=0.1.7)"]
+excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"]
+feather = ["pyarrow (>=10.0.1)"]
+fss = ["fsspec (>=2022.11.0)"]
+gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"]
+hdf5 = ["tables (>=3.8.0)"]
+html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"]
+mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"]
+output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"]
+parquet = ["pyarrow (>=10.0.1)"]
+performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"]
+plot = ["matplotlib (>=3.6.3)"]
+postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"]
+spss = ["pyreadstat (>=1.2.0)"]
+sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"]
+test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
+xml = ["lxml (>=4.9.2)"]
[[package]]
name = "pathspec"
-version = "0.11.1"
+version = "0.12.1"
description = "Utility library for gitignore style pattern matching of file paths."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"},
- {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"},
+ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
+ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
]
[[package]]
name = "pillow"
-version = "9.5.0"
+version = "10.2.0"
description = "Python Imaging Library (Fork)"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"},
- {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"},
- {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"},
- {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"},
- {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"},
- {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"},
- {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"},
- {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"},
- {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"},
- {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"},
- {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"},
- {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"},
- {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"},
- {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"},
- {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"},
- {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"},
- {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"},
- {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"},
- {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"},
- {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"},
- {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"},
- {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"},
- {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"},
- {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"},
- {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"},
- {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"},
- {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"},
- {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"},
- {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"},
- {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"},
- {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"},
- {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"},
- {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"},
- {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"},
- {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"},
- {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"},
- {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"},
- {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"},
- {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"},
- {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"},
- {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"},
- {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"},
- {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"},
- {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"},
- {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"},
- {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"},
- {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"},
- {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"},
- {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"},
- {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"},
- {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"},
- {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"},
- {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"},
- {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"},
- {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"},
- {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"},
- {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"},
- {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"},
- {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"},
- {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"},
- {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"},
- {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"},
- {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"},
- {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"},
- {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"},
- {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"},
+ {file = "pillow-10.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e"},
+ {file = "pillow-10.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588"},
+ {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fad5ff2f13d69b7e74ce5b4ecd12cc0ec530fcee76356cac6742785ff71c452"},
+ {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da2b52b37dad6d9ec64e653637a096905b258d2fc2b984c41ae7d08b938a67e4"},
+ {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:47c0995fc4e7f79b5cfcab1fc437ff2890b770440f7696a3ba065ee0fd496563"},
+ {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:322bdf3c9b556e9ffb18f93462e5f749d3444ce081290352c6070d014c93feb2"},
+ {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:51f1a1bffc50e2e9492e87d8e09a17c5eea8409cda8d3f277eb6edc82813c17c"},
+ {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69ffdd6120a4737710a9eee73e1d2e37db89b620f702754b8f6e62594471dee0"},
+ {file = "pillow-10.2.0-cp310-cp310-win32.whl", hash = "sha256:c6dafac9e0f2b3c78df97e79af707cdc5ef8e88208d686a4847bab8266870023"},
+ {file = "pillow-10.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:aebb6044806f2e16ecc07b2a2637ee1ef67a11840a66752751714a0d924adf72"},
+ {file = "pillow-10.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:7049e301399273a0136ff39b84c3678e314f2158f50f517bc50285fb5ec847ad"},
+ {file = "pillow-10.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35bb52c37f256f662abdfa49d2dfa6ce5d93281d323a9af377a120e89a9eafb5"},
+ {file = "pillow-10.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c23f307202661071d94b5e384e1e1dc7dfb972a28a2310e4ee16103e66ddb67"},
+ {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773efe0603db30c281521a7c0214cad7836c03b8ccff897beae9b47c0b657d61"},
+ {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e"},
+ {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:716d30ed977be8b37d3ef185fecb9e5a1d62d110dfbdcd1e2a122ab46fddb03f"},
+ {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a086c2af425c5f62a65e12fbf385f7c9fcb8f107d0849dba5839461a129cf311"},
+ {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c8de2789052ed501dd829e9cae8d3dcce7acb4777ea4a479c14521c942d395b1"},
+ {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:609448742444d9290fd687940ac0b57fb35e6fd92bdb65386e08e99af60bf757"},
+ {file = "pillow-10.2.0-cp311-cp311-win32.whl", hash = "sha256:823ef7a27cf86df6597fa0671066c1b596f69eba53efa3d1e1cb8b30f3533068"},
+ {file = "pillow-10.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1da3b2703afd040cf65ec97efea81cfba59cdbed9c11d8efc5ab09df9509fc56"},
+ {file = "pillow-10.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:edca80cbfb2b68d7b56930b84a0e45ae1694aeba0541f798e908a49d66b837f1"},
+ {file = "pillow-10.2.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:1b5e1b74d1bd1b78bc3477528919414874748dd363e6272efd5abf7654e68bef"},
+ {file = "pillow-10.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac"},
+ {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7c2286c23cd350b80d2fc9d424fc797575fb16f854b831d16fd47ceec078f2c"},
+ {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e23412b5c41e58cec602f1135c57dfcf15482013ce6e5f093a86db69646a5aa"},
+ {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:52a50aa3fb3acb9cf7213573ef55d31d6eca37f5709c69e6858fe3bc04a5c2a2"},
+ {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:127cee571038f252a552760076407f9cff79761c3d436a12af6000cd182a9d04"},
+ {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8d12251f02d69d8310b046e82572ed486685c38f02176bd08baf216746eb947f"},
+ {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54f1852cd531aa981bc0965b7d609f5f6cc8ce8c41b1139f6ed6b3c54ab82bfb"},
+ {file = "pillow-10.2.0-cp312-cp312-win32.whl", hash = "sha256:257d8788df5ca62c980314053197f4d46eefedf4e6175bc9412f14412ec4ea2f"},
+ {file = "pillow-10.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:154e939c5f0053a383de4fd3d3da48d9427a7e985f58af8e94d0b3c9fcfcf4f9"},
+ {file = "pillow-10.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:f379abd2f1e3dddb2b61bc67977a6b5a0a3f7485538bcc6f39ec76163891ee48"},
+ {file = "pillow-10.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8373c6c251f7ef8bda6675dd6d2b3a0fcc31edf1201266b5cf608b62a37407f9"},
+ {file = "pillow-10.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:870ea1ada0899fd0b79643990809323b389d4d1d46c192f97342eeb6ee0b8483"},
+ {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4b6b1e20608493548b1f32bce8cca185bf0480983890403d3b8753e44077129"},
+ {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3031709084b6e7852d00479fd1d310b07d0ba82765f973b543c8af5061cf990e"},
+ {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:3ff074fc97dd4e80543a3e91f69d58889baf2002b6be64347ea8cf5533188213"},
+ {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:cb4c38abeef13c61d6916f264d4845fab99d7b711be96c326b84df9e3e0ff62d"},
+ {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b1b3020d90c2d8e1dae29cf3ce54f8094f7938460fb5ce8bc5c01450b01fbaf6"},
+ {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:170aeb00224ab3dc54230c797f8404507240dd868cf52066f66a41b33169bdbe"},
+ {file = "pillow-10.2.0-cp38-cp38-win32.whl", hash = "sha256:c4225f5220f46b2fde568c74fca27ae9771536c2e29d7c04f4fb62c83275ac4e"},
+ {file = "pillow-10.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0689b5a8c5288bc0504d9fcee48f61a6a586b9b98514d7d29b840143d6734f39"},
+ {file = "pillow-10.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b792a349405fbc0163190fde0dc7b3fef3c9268292586cf5645598b48e63dc67"},
+ {file = "pillow-10.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c570f24be1e468e3f0ce7ef56a89a60f0e05b30a3669a459e419c6eac2c35364"},
+ {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8ecd059fdaf60c1963c58ceb8997b32e9dc1b911f5da5307aab614f1ce5c2fb"},
+ {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c365fd1703040de1ec284b176d6af5abe21b427cb3a5ff68e0759e1e313a5e7e"},
+ {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:70c61d4c475835a19b3a5aa42492409878bbca7438554a1f89d20d58a7c75c01"},
+ {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6f491cdf80ae540738859d9766783e3b3c8e5bd37f5dfa0b76abdecc5081f13"},
+ {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d189550615b4948f45252d7f005e53c2040cea1af5b60d6f79491a6e147eef7"},
+ {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:49d9ba1ed0ef3e061088cd1e7538a0759aab559e2e0a80a36f9fd9d8c0c21591"},
+ {file = "pillow-10.2.0-cp39-cp39-win32.whl", hash = "sha256:babf5acfede515f176833ed6028754cbcd0d206f7f614ea3447d67c33be12516"},
+ {file = "pillow-10.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:0304004f8067386b477d20a518b50f3fa658a28d44e4116970abfcd94fac34a8"},
+ {file = "pillow-10.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:0fb3e7fc88a14eacd303e90481ad983fd5b69c761e9e6ef94c983f91025da869"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:322209c642aabdd6207517e9739c704dc9f9db943015535783239022002f054a"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eedd52442c0a5ff4f887fab0c1c0bb164d8635b32c894bc1faf4c618dd89df2"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb28c753fd5eb3dd859b4ee95de66cc62af91bcff5db5f2571d32a520baf1f04"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:33870dc4653c5017bf4c8873e5488d8f8d5f8935e2f1fb9a2208c47cdd66efd2"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3c31822339516fb3c82d03f30e22b1d038da87ef27b6a78c9549888f8ceda39a"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a2b56ba36e05f973d450582fb015594aaa78834fefe8dfb8fcd79b93e64ba4c6"},
+ {file = "pillow-10.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d8e6aeb9201e655354b3ad049cb77d19813ad4ece0df1249d3c793de3774f8c7"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:2247178effb34a77c11c0e8ac355c7a741ceca0a732b27bf11e747bbc950722f"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15587643b9e5eb26c48e49a7b33659790d28f190fc514a322d55da2fb5c2950e"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753cd8f2086b2b80180d9b3010dd4ed147efc167c90d3bf593fe2af21265e5a5"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7c8f97e8e7a9009bcacbe3766a36175056c12f9a44e6e6f2d5caad06dcfbf03b"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d1b35bcd6c5543b9cb547dee3150c93008f8dd0f1fef78fc0cd2b141c5baf58a"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe4c15f6c9285dc54ce6553a3ce908ed37c8f3825b5a51a15c91442bb955b868"},
+ {file = "pillow-10.2.0.tar.gz", hash = "sha256:e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e"},
]
[package.extras]
docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"]
+fpx = ["olefile"]
+mic = ["olefile"]
tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
+typing = ["typing-extensions"]
+xmp = ["defusedxml"]
[[package]]
name = "platformdirs"
-version = "3.5.3"
+version = "4.2.0"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "platformdirs-3.5.3-py3-none-any.whl", hash = "sha256:0ade98a4895e87dc51d47151f7d2ec290365a585151d97b4d8d6312ed6132fed"},
- {file = "platformdirs-3.5.3.tar.gz", hash = "sha256:e48fabd87db8f3a7df7150a4a5ea22c546ee8bc39bc2473244730d4b56d2cc4e"},
+ {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"},
+ {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"},
]
[package.extras]
-docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"]
+docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"]
[[package]]
name = "pluggy"
-version = "1.0.0"
+version = "1.4.0"
description = "plugin and hook calling mechanisms for python"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
files = [
- {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
- {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
+ {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
+ {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
]
[package.extras]
@@ -1108,13 +1219,13 @@ testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "pre-commit"
-version = "3.3.2"
+version = "3.6.1"
description = "A framework for managing and maintaining multi-language pre-commit hooks."
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
files = [
- {file = "pre_commit-3.3.2-py2.py3-none-any.whl", hash = "sha256:8056bc52181efadf4aac792b1f4f255dfd2fb5a350ded7335d251a68561e8cb6"},
- {file = "pre_commit-3.3.2.tar.gz", hash = "sha256:66e37bec2d882de1f17f88075047ef8962581f83c234ac08da21a0c58953d1f0"},
+ {file = "pre_commit-3.6.1-py2.py3-none-any.whl", hash = "sha256:9fe989afcf095d2c4796ce7c553cf28d4d4a9b9346de3cda079bcf40748454a4"},
+ {file = "pre_commit-3.6.1.tar.gz", hash = "sha256:c90961d8aa706f75d60935aba09469a6b0bcb8345f127c3fbee4bdc5f114cf4b"},
]
[package.dependencies]
@@ -1126,18 +1237,18 @@ virtualenv = ">=20.10.0"
[[package]]
name = "pydantic"
-version = "2.5.3"
+version = "2.6.1"
description = "Data validation using Python type hints"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"},
- {file = "pydantic-2.5.3.tar.gz", hash = "sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a"},
+ {file = "pydantic-2.6.1-py3-none-any.whl", hash = "sha256:0b6a909df3192245cb736509a92ff69e4fef76116feffec68e93a567347bae6f"},
+ {file = "pydantic-2.6.1.tar.gz", hash = "sha256:4fd5c182a2488dc63e6d32737ff19937888001e2a6d86e94b3f233104a5d1fa9"},
]
[package.dependencies]
annotated-types = ">=0.4.0"
-pydantic-core = "2.14.6"
+pydantic-core = "2.16.2"
typing-extensions = ">=4.6.1"
[package.extras]
@@ -1145,116 +1256,90 @@ email = ["email-validator (>=2.0.0)"]
[[package]]
name = "pydantic-core"
-version = "2.14.6"
+version = "2.16.2"
description = ""
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"},
- {file = "pydantic_core-2.14.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c"},
- {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4"},
- {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534"},
- {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08"},
- {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d"},
- {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245"},
- {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c"},
- {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66"},
- {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590"},
- {file = "pydantic_core-2.14.6-cp310-none-win32.whl", hash = "sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7"},
- {file = "pydantic_core-2.14.6-cp310-none-win_amd64.whl", hash = "sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87"},
- {file = "pydantic_core-2.14.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4"},
- {file = "pydantic_core-2.14.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421"},
- {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b"},
- {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e"},
- {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96"},
- {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b"},
- {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1"},
- {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937"},
- {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622"},
- {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2"},
- {file = "pydantic_core-2.14.6-cp311-none-win32.whl", hash = "sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2"},
- {file = "pydantic_core-2.14.6-cp311-none-win_amd64.whl", hash = "sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23"},
- {file = "pydantic_core-2.14.6-cp311-none-win_arm64.whl", hash = "sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6"},
- {file = "pydantic_core-2.14.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec"},
- {file = "pydantic_core-2.14.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7"},
- {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51"},
- {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f"},
- {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a"},
- {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af"},
- {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b"},
- {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd"},
- {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91"},
- {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c"},
- {file = "pydantic_core-2.14.6-cp312-none-win32.whl", hash = "sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786"},
- {file = "pydantic_core-2.14.6-cp312-none-win_amd64.whl", hash = "sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40"},
- {file = "pydantic_core-2.14.6-cp312-none-win_arm64.whl", hash = "sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8"},
- {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e"},
- {file = "pydantic_core-2.14.6-cp37-none-win32.whl", hash = "sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6"},
- {file = "pydantic_core-2.14.6-cp37-none-win_amd64.whl", hash = "sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391"},
- {file = "pydantic_core-2.14.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149"},
- {file = "pydantic_core-2.14.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b"},
- {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb"},
- {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7"},
- {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8"},
- {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42"},
- {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80"},
- {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d"},
- {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1"},
- {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60"},
- {file = "pydantic_core-2.14.6-cp38-none-win32.whl", hash = "sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe"},
- {file = "pydantic_core-2.14.6-cp38-none-win_amd64.whl", hash = "sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8"},
- {file = "pydantic_core-2.14.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab"},
- {file = "pydantic_core-2.14.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f"},
- {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0"},
- {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b"},
- {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160"},
- {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b"},
- {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab"},
- {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0"},
- {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9"},
- {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411"},
- {file = "pydantic_core-2.14.6-cp39-none-win32.whl", hash = "sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975"},
- {file = "pydantic_core-2.14.6-cp39-none-win_amd64.whl", hash = "sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9"},
- {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95"},
- {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277"},
- {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670"},
- {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e"},
- {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d"},
- {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d"},
- {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94"},
- {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66"},
- {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2"},
- {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24"},
- {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd"},
- {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8"},
- {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f"},
- {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a"},
- {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda"},
- {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145"},
- {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1"},
- {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e"},
- {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052"},
- {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba"},
- {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4"},
- {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d"},
- {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2"},
- {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03"},
- {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f"},
- {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a"},
- {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf"},
- {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556"},
- {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341"},
- {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e"},
- {file = "pydantic_core-2.14.6.tar.gz", hash = "sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3fab4e75b8c525a4776e7630b9ee48aea50107fea6ca9f593c98da3f4d11bf7c"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8bde5b48c65b8e807409e6f20baee5d2cd880e0fad00b1a811ebc43e39a00ab2"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2924b89b16420712e9bb8192396026a8fbd6d8726224f918353ac19c4c043d2a"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16aa02e7a0f539098e215fc193c8926c897175d64c7926d00a36188917717a05"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:936a787f83db1f2115ee829dd615c4f684ee48ac4de5779ab4300994d8af325b"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:459d6be6134ce3b38e0ef76f8a672924460c455d45f1ad8fdade36796df1ddc8"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9ee4febb249c591d07b2d4dd36ebcad0ccd128962aaa1801508320896575ef"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40a0bd0bed96dae5712dab2aba7d334a6c67cbcac2ddfca7dbcc4a8176445990"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:870dbfa94de9b8866b37b867a2cb37a60c401d9deb4a9ea392abf11a1f98037b"},
+ {file = "pydantic_core-2.16.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:308974fdf98046db28440eb3377abba274808bf66262e042c412eb2adf852731"},
+ {file = "pydantic_core-2.16.2-cp310-none-win32.whl", hash = "sha256:a477932664d9611d7a0816cc3c0eb1f8856f8a42435488280dfbf4395e141485"},
+ {file = "pydantic_core-2.16.2-cp310-none-win_amd64.whl", hash = "sha256:8f9142a6ed83d90c94a3efd7af8873bf7cefed2d3d44387bf848888482e2d25f"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:406fac1d09edc613020ce9cf3f2ccf1a1b2f57ab00552b4c18e3d5276c67eb11"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce232a6170dd6532096cadbf6185271e4e8c70fc9217ebe105923ac105da9978"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90fec23b4b05a09ad988e7a4f4e081711a90eb2a55b9c984d8b74597599180f"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8aafeedb6597a163a9c9727d8a8bd363a93277701b7bfd2749fbefee2396469e"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9957433c3a1b67bdd4c63717eaf174ebb749510d5ea612cd4e83f2d9142f3fc8"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0d7a9165167269758145756db43a133608a531b1e5bb6a626b9ee24bc38a8f7"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dffaf740fe2e147fedcb6b561353a16243e654f7fe8e701b1b9db148242e1272"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8ed79883b4328b7f0bd142733d99c8e6b22703e908ec63d930b06be3a0e7113"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cf903310a34e14651c9de056fcc12ce090560864d5a2bb0174b971685684e1d8"},
+ {file = "pydantic_core-2.16.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:46b0d5520dbcafea9a8645a8164658777686c5c524d381d983317d29687cce97"},
+ {file = "pydantic_core-2.16.2-cp311-none-win32.whl", hash = "sha256:70651ff6e663428cea902dac297066d5c6e5423fda345a4ca62430575364d62b"},
+ {file = "pydantic_core-2.16.2-cp311-none-win_amd64.whl", hash = "sha256:98dc6f4f2095fc7ad277782a7c2c88296badcad92316b5a6e530930b1d475ebc"},
+ {file = "pydantic_core-2.16.2-cp311-none-win_arm64.whl", hash = "sha256:ef6113cd31411eaf9b39fc5a8848e71c72656fd418882488598758b2c8c6dfa0"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:88646cae28eb1dd5cd1e09605680c2b043b64d7481cdad7f5003ebef401a3039"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7b883af50eaa6bb3299780651e5be921e88050ccf00e3e583b1e92020333304b"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bf26c2e2ea59d32807081ad51968133af3025c4ba5753e6a794683d2c91bf6e"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99af961d72ac731aae2a1b55ccbdae0733d816f8bfb97b41909e143de735f522"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02906e7306cb8c5901a1feb61f9ab5e5c690dbbeaa04d84c1b9ae2a01ebe9379"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5362d099c244a2d2f9659fb3c9db7c735f0004765bbe06b99be69fbd87c3f15"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ac426704840877a285d03a445e162eb258924f014e2f074e209d9b4ff7bf380"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b94cbda27267423411c928208e89adddf2ea5dd5f74b9528513f0358bba019cb"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6db58c22ac6c81aeac33912fb1af0e930bc9774166cdd56eade913d5f2fff35e"},
+ {file = "pydantic_core-2.16.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396fdf88b1b503c9c59c84a08b6833ec0c3b5ad1a83230252a9e17b7dfb4cffc"},
+ {file = "pydantic_core-2.16.2-cp312-none-win32.whl", hash = "sha256:7c31669e0c8cc68400ef0c730c3a1e11317ba76b892deeefaf52dcb41d56ed5d"},
+ {file = "pydantic_core-2.16.2-cp312-none-win_amd64.whl", hash = "sha256:a3b7352b48fbc8b446b75f3069124e87f599d25afb8baa96a550256c031bb890"},
+ {file = "pydantic_core-2.16.2-cp312-none-win_arm64.whl", hash = "sha256:a9e523474998fb33f7c1a4d55f5504c908d57add624599e095c20fa575b8d943"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ae34418b6b389d601b31153b84dce480351a352e0bb763684a1b993d6be30f17"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:732bd062c9e5d9582a30e8751461c1917dd1ccbdd6cafb032f02c86b20d2e7ec"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b52776a2e3230f4854907a1e0946eec04d41b1fc64069ee774876bbe0eab55"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ef551c053692b1e39e3f7950ce2296536728871110e7d75c4e7753fb30ca87f4"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ebb892ed8599b23fa8f1799e13a12c87a97a6c9d0f497525ce9858564c4575a4"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa6c8c582036275997a733427b88031a32ffa5dfc3124dc25a730658c47a572f"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ba0884a91f1aecce75202473ab138724aa4fb26d7707f2e1fa6c3e68c84fbf"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7924e54f7ce5d253d6160090ddc6df25ed2feea25bfb3339b424a9dd591688bc"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69a7b96b59322a81c2203be537957313b07dd333105b73db0b69212c7d867b4b"},
+ {file = "pydantic_core-2.16.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7e6231aa5bdacda78e96ad7b07d0c312f34ba35d717115f4b4bff6cb87224f0f"},
+ {file = "pydantic_core-2.16.2-cp38-none-win32.whl", hash = "sha256:41dac3b9fce187a25c6253ec79a3f9e2a7e761eb08690e90415069ea4a68ff7a"},
+ {file = "pydantic_core-2.16.2-cp38-none-win_amd64.whl", hash = "sha256:f685dbc1fdadb1dcd5b5e51e0a378d4685a891b2ddaf8e2bba89bd3a7144e44a"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:55749f745ebf154c0d63d46c8c58594d8894b161928aa41adbb0709c1fe78b77"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b30b0dd58a4509c3bd7eefddf6338565c4905406aee0c6e4a5293841411a1286"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18de31781cdc7e7b28678df7c2d7882f9692ad060bc6ee3c94eb15a5d733f8f7"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5864b0242f74b9dd0b78fd39db1768bc3f00d1ffc14e596fd3e3f2ce43436a33"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8f9186ca45aee030dc8234118b9c0784ad91a0bb27fc4e7d9d6608a5e3d386c"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc6f6c9be0ab6da37bc77c2dda5f14b1d532d5dbef00311ee6e13357a418e646"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa057095f621dad24a1e906747179a69780ef45cc8f69e97463692adbcdae878"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ad84731a26bcfb299f9eab56c7932d46f9cad51c52768cace09e92a19e4cf55"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3b052c753c4babf2d1edc034c97851f867c87d6f3ea63a12e2700f159f5c41c3"},
+ {file = "pydantic_core-2.16.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e0f686549e32ccdb02ae6f25eee40cc33900910085de6aa3790effd391ae10c2"},
+ {file = "pydantic_core-2.16.2-cp39-none-win32.whl", hash = "sha256:7afb844041e707ac9ad9acad2188a90bffce2c770e6dc2318be0c9916aef1469"},
+ {file = "pydantic_core-2.16.2-cp39-none-win_amd64.whl", hash = "sha256:9da90d393a8227d717c19f5397688a38635afec89f2e2d7af0df037f3249c39a"},
+ {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f60f920691a620b03082692c378661947d09415743e437a7478c309eb0e4f82"},
+ {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:47924039e785a04d4a4fa49455e51b4eb3422d6eaacfde9fc9abf8fdef164e8a"},
+ {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6294e76b0380bb7a61eb8a39273c40b20beb35e8c87ee101062834ced19c545"},
+ {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe56851c3f1d6f5384b3051c536cc81b3a93a73faf931f404fef95217cf1e10d"},
+ {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d776d30cde7e541b8180103c3f294ef7c1862fd45d81738d156d00551005784"},
+ {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:72f7919af5de5ecfaf1eba47bf9a5d8aa089a3340277276e5636d16ee97614d7"},
+ {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:4bfcbde6e06c56b30668a0c872d75a7ef3025dc3c1823a13cf29a0e9b33f67e8"},
+ {file = "pydantic_core-2.16.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ff7c97eb7a29aba230389a2661edf2e9e06ce616c7e35aa764879b6894a44b25"},
+ {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9b5f13857da99325dcabe1cc4e9e6a3d7b2e2c726248ba5dd4be3e8e4a0b6d0e"},
+ {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a7e41e3ada4cca5f22b478c08e973c930e5e6c7ba3588fb8e35f2398cdcc1545"},
+ {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60eb8ceaa40a41540b9acae6ae7c1f0a67d233c40dc4359c256ad2ad85bdf5e5"},
+ {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7beec26729d496a12fd23cf8da9944ee338c8b8a17035a560b585c36fe81af20"},
+ {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:22c5f022799f3cd6741e24f0443ead92ef42be93ffda0d29b2597208c94c3753"},
+ {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:eca58e319f4fd6df004762419612122b2c7e7d95ffafc37e890252f869f3fb2a"},
+ {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed957db4c33bc99895f3a1672eca7e80e8cda8bd1e29a80536b4ec2153fa9804"},
+ {file = "pydantic_core-2.16.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:459c0d338cc55d099798618f714b21b7ece17eb1a87879f2da20a3ff4c7628e2"},
+ {file = "pydantic_core-2.16.2.tar.gz", hash = "sha256:0ba503850d8b8dcc18391f10de896ae51d37fe5fe43dbfb6a35c5c5cad271a06"},
]
[package.dependencies]
@@ -1262,27 +1347,28 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
[[package]]
name = "pygments"
-version = "2.15.1"
+version = "2.17.2"
description = "Pygments is a syntax highlighting package written in Python."
optional = false
python-versions = ">=3.7"
files = [
- {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"},
- {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"},
+ {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"},
+ {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"},
]
[package.extras]
plugins = ["importlib-metadata"]
+windows-terminal = ["colorama (>=0.4.6)"]
[[package]]
name = "pyparsing"
-version = "3.0.9"
+version = "3.1.1"
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
optional = false
python-versions = ">=3.6.8"
files = [
- {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
- {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
+ {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"},
+ {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"},
]
[package.extras]
@@ -1290,13 +1376,13 @@ diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pytest"
-version = "7.3.2"
+version = "7.4.4"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.7"
files = [
- {file = "pytest-7.3.2-py3-none-any.whl", hash = "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295"},
- {file = "pytest-7.3.2.tar.gz", hash = "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b"},
+ {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"},
+ {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"},
]
[package.dependencies]
@@ -1375,62 +1461,73 @@ test = ["coverage[toml] (>=6,<8)", "pytest (>=7,<8)", "pytest-clarity (>=1.0.1)"
[[package]]
name = "pytz"
-version = "2023.3"
+version = "2024.1"
description = "World timezone definitions, modern and historical"
optional = false
python-versions = "*"
files = [
- {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"},
- {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"},
+ {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
+ {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
]
[[package]]
name = "pyyaml"
-version = "6.0"
+version = "6.0.1"
description = "YAML parser and emitter for Python"
optional = false
python-versions = ">=3.6"
files = [
- {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
- {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
- {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
- {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
- {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
- {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
- {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
- {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"},
- {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"},
- {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"},
- {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"},
- {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"},
- {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"},
- {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"},
- {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
- {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
- {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
- {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
- {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
- {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
- {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
- {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
- {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
- {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
- {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
- {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
- {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
- {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
- {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
- {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
- {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
- {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
- {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
- {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
- {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
- {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
- {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
- {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
- {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
- {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
+ {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
+ {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
+ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
+ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
+ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
+ {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
+ {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
+ {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
+ {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
+ {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
+ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
+ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
+ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
+ {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
+ {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
+ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
+ {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
+ {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
+ {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
+ {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
+ {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
+ {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
+ {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
+ {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
+ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
+ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
+ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
+ {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
+ {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
+ {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
+ {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
+ {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
+ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
+ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
+ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
+ {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
+ {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
+ {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
+ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
]
[[package]]
@@ -1509,19 +1606,19 @@ stats = ["scipy (>=1.3)", "statsmodels (>=0.10)"]
[[package]]
name = "setuptools"
-version = "67.8.0"
+version = "69.1.0"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "setuptools-67.8.0-py3-none-any.whl", hash = "sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f"},
- {file = "setuptools-67.8.0.tar.gz", hash = "sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"},
+ {file = "setuptools-69.1.0-py3-none-any.whl", hash = "sha256:c054629b81b946d63a9c6e732bc8b2513a7c3ea645f11d0139a2191d735c60c6"},
+ {file = "setuptools-69.1.0.tar.gz", hash = "sha256:850894c4195f09c4ed30dba56213bf7c3f21d86ed6bdaafb5df5972593bfc401"},
]
[package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
-testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
-testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
+testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "shellingham"
@@ -1569,13 +1666,13 @@ files = [
[[package]]
name = "sphinx"
-version = "7.0.1"
+version = "7.2.6"
description = "Python documentation generator"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
files = [
- {file = "Sphinx-7.0.1.tar.gz", hash = "sha256:61e025f788c5977d9412587e733733a289e2b9fdc2fef8868ddfbfc4ccfe881d"},
- {file = "sphinx-7.0.1-py3-none-any.whl", hash = "sha256:60c5e04756c1709a98845ed27a2eed7a556af3993afb66e77fec48189f742616"},
+ {file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"},
+ {file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"},
]
[package.dependencies]
@@ -1586,7 +1683,7 @@ docutils = ">=0.18.1,<0.21"
imagesize = ">=1.3"
Jinja2 = ">=3.0"
packaging = ">=21.0"
-Pygments = ">=2.13"
+Pygments = ">=2.14"
requests = ">=2.25.0"
snowballstemmer = ">=2.0"
sphinxcontrib-applehelp = "*"
@@ -1594,56 +1691,59 @@ sphinxcontrib-devhelp = "*"
sphinxcontrib-htmlhelp = ">=2.0.0"
sphinxcontrib-jsmath = "*"
sphinxcontrib-qthelp = "*"
-sphinxcontrib-serializinghtml = ">=1.1.5"
+sphinxcontrib-serializinghtml = ">=1.1.9"
[package.extras]
docs = ["sphinxcontrib-websupport"]
lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"]
-test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"]
+test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools (>=67.0)"]
[[package]]
name = "sphinxcontrib-applehelp"
-version = "1.0.4"
+version = "1.0.8"
description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
files = [
- {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"},
- {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"},
+ {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"},
+ {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"},
]
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
+standalone = ["Sphinx (>=5)"]
test = ["pytest"]
[[package]]
name = "sphinxcontrib-devhelp"
-version = "1.0.2"
-description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
+version = "1.0.6"
+description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents"
optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.9"
files = [
- {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
- {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
+ {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"},
+ {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"},
]
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
+standalone = ["Sphinx (>=5)"]
test = ["pytest"]
[[package]]
name = "sphinxcontrib-htmlhelp"
-version = "2.0.1"
+version = "2.0.5"
description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
files = [
- {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"},
- {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"},
+ {file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"},
+ {file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"},
]
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
+standalone = ["Sphinx (>=5)"]
test = ["html5lib", "pytest"]
[[package]]
@@ -1662,32 +1762,34 @@ test = ["flake8", "mypy", "pytest"]
[[package]]
name = "sphinxcontrib-qthelp"
-version = "1.0.3"
-description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
+version = "1.0.7"
+description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents"
optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.9"
files = [
- {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
- {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
+ {file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"},
+ {file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"},
]
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
+standalone = ["Sphinx (>=5)"]
test = ["pytest"]
[[package]]
name = "sphinxcontrib-serializinghtml"
-version = "1.1.5"
-description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
+version = "1.1.10"
+description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)"
optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.9"
files = [
- {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
- {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
+ {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"},
+ {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"},
]
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
+standalone = ["Sphinx (>=5)"]
test = ["pytest"]
[[package]]
@@ -1714,62 +1816,62 @@ files = [
[[package]]
name = "typing-extensions"
-version = "4.8.0"
+version = "4.9.0"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
- {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
- {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
+ {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
+ {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
]
[[package]]
name = "tzdata"
-version = "2023.3"
+version = "2024.1"
description = "Provider of IANA time zone data"
optional = false
python-versions = ">=2"
files = [
- {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"},
- {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"},
+ {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"},
+ {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"},
]
[[package]]
name = "urllib3"
-version = "2.0.3"
+version = "2.2.0"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"},
- {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"},
+ {file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"},
+ {file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"},
]
[package.extras]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
-secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
+h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"]
[[package]]
name = "virtualenv"
-version = "20.23.0"
+version = "20.25.0"
description = "Virtual Python Environment builder"
optional = false
python-versions = ">=3.7"
files = [
- {file = "virtualenv-20.23.0-py3-none-any.whl", hash = "sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e"},
- {file = "virtualenv-20.23.0.tar.gz", hash = "sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924"},
+ {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"},
+ {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"},
]
[package.dependencies]
-distlib = ">=0.3.6,<1"
-filelock = ">=3.11,<4"
-platformdirs = ">=3.2,<4"
+distlib = ">=0.3.7,<1"
+filelock = ">=3.12.2,<4"
+platformdirs = ">=3.9.1,<5"
[package.extras]
-docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"]
-test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.7.1)", "time-machine (>=2.9)"]
+docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
+test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
[metadata]
lock-version = "2.0"
diff --git a/tests/test_maidr.py b/tests/test_maidr.py
new file mode 100644
index 0000000..e69de29