From cb375886c3c63591a0e2ff109e79337a9a195bc0 Mon Sep 17 00:00:00 2001 From: Jorgelmh Date: Wed, 8 Jan 2025 05:37:33 +0000 Subject: [PATCH] deploy: 4fdbc85ca1a75d5a74caa72f52608a074586d674 --- .buildinfo | 4 + .nojekyll | 0 ADVANCED.html | 456 ++++++++ CHANGELOG.html | 536 ++++++++++ LICENSE.html | 382 +++++++ LICENSE_THIRD_PARTY.html | 687 ++++++++++++ MLMODEL.html | 525 ++++++++++ README.html | 702 +++++++++++++ STYLEGUIDE.html | 830 +++++++++++++++ _autosummary/mlfmu.api.MlFmuBuilder.html | 621 +++++++++++ _autosummary/mlfmu.api.MlFmuCommand.html | 442 ++++++++ _autosummary/mlfmu.api.MlFmuProcess.html | 454 ++++++++ _autosummary/mlfmu.api.html | 421 ++++++++ ...u.types.fmu_component.BaseModelConfig.html | 504 +++++++++ ...lfmu.types.fmu_component.FmiCausality.html | 577 +++++++++++ ....types.fmu_component.FmiInputVariable.html | 563 ++++++++++ .../mlfmu.types.fmu_component.FmiModel.html | 636 ++++++++++++ ...types.fmu_component.FmiOutputVariable.html | 553 ++++++++++ ...mu.types.fmu_component.FmiVariability.html | 595 +++++++++++ ...mlfmu.types.fmu_component.FmiVariable.html | 479 +++++++++ ...u.types.fmu_component.FmiVariableType.html | 586 +++++++++++ ...fmu.types.fmu_component.InputVariable.html | 539 ++++++++++ ...fmu.types.fmu_component.InternalState.html | 589 +++++++++++ ...mu.types.fmu_component.ModelComponent.html | 642 ++++++++++++ ...mu.types.fmu_component.OutputVariable.html | 539 ++++++++++ .../mlfmu.types.fmu_component.Variable.html | 583 +++++++++++ _autosummary/mlfmu.types.fmu_component.html | 404 ++++++++ _autosummary/mlfmu.types.html | 371 +++++++ .../mlfmu.types.onnx_model.ONNXModel.html | 539 ++++++++++ _autosummary/mlfmu.types.onnx_model.html | 368 +++++++ _autosummary/mlfmu.utils.builder.html | 567 ++++++++++ _autosummary/mlfmu.utils.fmi_builder.html | 419 ++++++++ _autosummary/mlfmu.utils.html | 387 +++++++ _autosummary/mlfmu.utils.interface.html | 442 ++++++++ _autosummary/mlfmu.utils.logging.html | 409 ++++++++ _autosummary/mlfmu.utils.path.html | 411 ++++++++ _autosummary/mlfmu.utils.signals.html | 401 +++++++ _autosummary/mlfmu.utils.strings.html | 393 +++++++ _sources/ADVANCED.md.txt | 2 + _sources/CHANGELOG.md.txt | 2 + _sources/LICENSE.md.txt | 3 + _sources/LICENSE_THIRD_PARTY.md.txt | 4 + _sources/MLMODEL.md.txt | 2 + _sources/README.md.txt | 2 + _sources/STYLEGUIDE.md.txt | 2 + .../mlfmu.api.MlFmuBuilder.rst.txt | 39 + .../mlfmu.api.MlFmuCommand.rst.txt | 31 + .../mlfmu.api.MlFmuProcess.rst.txt | 31 + _sources/_autosummary/mlfmu.api.rst.txt | 24 + ...ypes.fmu_component.BaseModelConfig.rst.txt | 56 + ...u.types.fmu_component.FmiCausality.rst.txt | 78 ++ ...pes.fmu_component.FmiInputVariable.rst.txt | 67 ++ ...mlfmu.types.fmu_component.FmiModel.rst.txt | 44 + ...es.fmu_component.FmiOutputVariable.rst.txt | 66 ++ ...types.fmu_component.FmiVariability.rst.txt | 80 ++ ...mu.types.fmu_component.FmiVariable.rst.txt | 35 + ...ypes.fmu_component.FmiVariableType.rst.txt | 79 ++ ....types.fmu_component.InputVariable.rst.txt | 64 ++ ....types.fmu_component.InternalState.rst.txt | 62 ++ ...types.fmu_component.ModelComponent.rst.txt | 68 ++ ...types.fmu_component.OutputVariable.rst.txt | 64 ++ ...mlfmu.types.fmu_component.Variable.rst.txt | 63 ++ .../mlfmu.types.fmu_component.rst.txt | 29 + .../mlfmu.types.onnx_model.ONNXModel.rst.txt | 39 + .../mlfmu.types.onnx_model.rst.txt | 17 + _sources/_autosummary/mlfmu.types.rst.txt | 16 + .../_autosummary/mlfmu.utils.builder.rst.txt | 21 + .../mlfmu.utils.fmi_builder.rst.txt | 14 + .../mlfmu.utils.interface.rst.txt | 15 + .../_autosummary/mlfmu.utils.logging.rst.txt | 13 + .../_autosummary/mlfmu.utils.path.rst.txt | 13 + _sources/_autosummary/mlfmu.utils.rst.txt | 21 + .../_autosummary/mlfmu.utils.signals.rst.txt | 13 + .../_autosummary/mlfmu.utils.strings.rst.txt | 13 + _sources/api.rst.txt | 11 + _sources/cli.mlfmu.rst.txt | 3 + _sources/cli.rst.txt | 7 + _sources/index.rst.txt | 28 + _static/basic.css | 914 ++++++++++++++++ _static/debug.css | 69 ++ _static/doctools.js | 149 +++ _static/documentation_options.js | 13 + _static/file.png | Bin 0 -> 286 bytes _static/language_data.js | 192 ++++ _static/minus.png | Bin 0 -> 90 bytes _static/mlfmu_logo_v1.svg | 1 + _static/plus.png | Bin 0 -> 90 bytes _static/pygments.css | 258 +++++ _static/scripts/furo-extensions.js | 0 _static/scripts/furo.js | 3 + _static/scripts/furo.js.LICENSE.txt | 7 + _static/scripts/furo.js.map | 1 + _static/searchtools.js | 632 +++++++++++ _static/skeleton.css | 296 ++++++ _static/sphinx_highlight.js | 154 +++ _static/styles/furo-extensions.css | 2 + _static/styles/furo-extensions.css.map | 1 + _static/styles/furo.css | 2 + _static/styles/furo.css.map | 1 + api.html | 373 +++++++ branch/main/.buildinfo | 4 + branch/main/ADVANCED.html | 456 ++++++++ branch/main/CHANGELOG.html | 551 ++++++++++ branch/main/LICENSE.html | 382 +++++++ branch/main/LICENSE_THIRD_PARTY.html | 687 ++++++++++++ branch/main/MLMODEL.html | 525 ++++++++++ branch/main/README.html | 702 +++++++++++++ branch/main/STYLEGUIDE.html | 830 +++++++++++++++ .../_autosummary/mlfmu.api.MlFmuBuilder.html | 621 +++++++++++ .../_autosummary/mlfmu.api.MlFmuCommand.html | 442 ++++++++ .../_autosummary/mlfmu.api.MlFmuProcess.html | 454 ++++++++ branch/main/_autosummary/mlfmu.api.html | 421 ++++++++ ...u.types.fmu_component.BaseModelConfig.html | 504 +++++++++ ...lfmu.types.fmu_component.FmiCausality.html | 577 +++++++++++ ....types.fmu_component.FmiInputVariable.html | 563 ++++++++++ .../mlfmu.types.fmu_component.FmiModel.html | 636 ++++++++++++ ...types.fmu_component.FmiOutputVariable.html | 553 ++++++++++ ...mu.types.fmu_component.FmiVariability.html | 595 +++++++++++ ...mlfmu.types.fmu_component.FmiVariable.html | 479 +++++++++ ...u.types.fmu_component.FmiVariableType.html | 586 +++++++++++ ...fmu.types.fmu_component.InputVariable.html | 539 ++++++++++ ...fmu.types.fmu_component.InternalState.html | 589 +++++++++++ ...mu.types.fmu_component.ModelComponent.html | 642 ++++++++++++ ...mu.types.fmu_component.OutputVariable.html | 539 ++++++++++ .../mlfmu.types.fmu_component.Variable.html | 583 +++++++++++ .../mlfmu.types.fmu_component.html | 404 ++++++++ branch/main/_autosummary/mlfmu.types.html | 371 +++++++ .../mlfmu.types.onnx_model.ONNXModel.html | 539 ++++++++++ .../_autosummary/mlfmu.types.onnx_model.html | 368 +++++++ .../_autosummary/mlfmu.utils.builder.html | 567 ++++++++++ .../_autosummary/mlfmu.utils.fmi_builder.html | 419 ++++++++ branch/main/_autosummary/mlfmu.utils.html | 387 +++++++ .../_autosummary/mlfmu.utils.interface.html | 442 ++++++++ .../_autosummary/mlfmu.utils.logging.html | 409 ++++++++ .../main/_autosummary/mlfmu.utils.path.html | 411 ++++++++ .../_autosummary/mlfmu.utils.signals.html | 401 +++++++ .../_autosummary/mlfmu.utils.strings.html | 393 +++++++ branch/main/_sources/ADVANCED.md.txt | 2 + branch/main/_sources/CHANGELOG.md.txt | 2 + branch/main/_sources/LICENSE.md.txt | 3 + .../main/_sources/LICENSE_THIRD_PARTY.md.txt | 4 + branch/main/_sources/MLMODEL.md.txt | 2 + branch/main/_sources/README.md.txt | 2 + branch/main/_sources/STYLEGUIDE.md.txt | 2 + .../mlfmu.api.MlFmuBuilder.rst.txt | 39 + .../mlfmu.api.MlFmuCommand.rst.txt | 31 + .../mlfmu.api.MlFmuProcess.rst.txt | 31 + .../_sources/_autosummary/mlfmu.api.rst.txt | 24 + ...ypes.fmu_component.BaseModelConfig.rst.txt | 56 + ...u.types.fmu_component.FmiCausality.rst.txt | 78 ++ ...pes.fmu_component.FmiInputVariable.rst.txt | 67 ++ ...mlfmu.types.fmu_component.FmiModel.rst.txt | 44 + ...es.fmu_component.FmiOutputVariable.rst.txt | 66 ++ ...types.fmu_component.FmiVariability.rst.txt | 80 ++ ...mu.types.fmu_component.FmiVariable.rst.txt | 35 + ...ypes.fmu_component.FmiVariableType.rst.txt | 79 ++ ....types.fmu_component.InputVariable.rst.txt | 64 ++ ....types.fmu_component.InternalState.rst.txt | 62 ++ ...types.fmu_component.ModelComponent.rst.txt | 68 ++ ...types.fmu_component.OutputVariable.rst.txt | 64 ++ ...mlfmu.types.fmu_component.Variable.rst.txt | 63 ++ .../mlfmu.types.fmu_component.rst.txt | 29 + .../mlfmu.types.onnx_model.ONNXModel.rst.txt | 39 + .../mlfmu.types.onnx_model.rst.txt | 17 + .../_sources/_autosummary/mlfmu.types.rst.txt | 16 + .../_autosummary/mlfmu.utils.builder.rst.txt | 21 + .../mlfmu.utils.fmi_builder.rst.txt | 14 + .../mlfmu.utils.interface.rst.txt | 15 + .../_autosummary/mlfmu.utils.logging.rst.txt | 13 + .../_autosummary/mlfmu.utils.path.rst.txt | 13 + .../_sources/_autosummary/mlfmu.utils.rst.txt | 21 + .../_autosummary/mlfmu.utils.signals.rst.txt | 13 + .../_autosummary/mlfmu.utils.strings.rst.txt | 13 + branch/main/_sources/api.rst.txt | 11 + branch/main/_sources/cli.mlfmu.rst.txt | 3 + branch/main/_sources/cli.rst.txt | 7 + branch/main/_sources/index.rst.txt | 28 + branch/main/_static/basic.css | 914 ++++++++++++++++ branch/main/_static/debug.css | 69 ++ branch/main/_static/doctools.js | 149 +++ branch/main/_static/documentation_options.js | 13 + branch/main/_static/file.png | Bin 0 -> 286 bytes branch/main/_static/language_data.js | 192 ++++ branch/main/_static/minus.png | Bin 0 -> 90 bytes branch/main/_static/mlfmu_logo_v1.svg | 1 + branch/main/_static/plus.png | Bin 0 -> 90 bytes branch/main/_static/pygments.css | 258 +++++ .../main/_static/scripts/furo-extensions.js | 0 branch/main/_static/scripts/furo.js | 3 + .../main/_static/scripts/furo.js.LICENSE.txt | 7 + branch/main/_static/scripts/furo.js.map | 1 + branch/main/_static/searchtools.js | 632 +++++++++++ branch/main/_static/skeleton.css | 296 ++++++ branch/main/_static/sphinx_highlight.js | 154 +++ .../main/_static/styles/furo-extensions.css | 2 + .../_static/styles/furo-extensions.css.map | 1 + branch/main/_static/styles/furo.css | 2 + branch/main/_static/styles/furo.css.map | 1 + branch/main/api.html | 373 +++++++ branch/main/cli.html | 369 +++++++ branch/main/cli.mlfmu.html | 470 +++++++++ branch/main/genindex.html | 979 ++++++++++++++++++ branch/main/index.html | 485 +++++++++ branch/main/objects.inv | Bin 0 -> 2606 bytes branch/main/py-modindex.html | 429 ++++++++ branch/main/search.html | 353 +++++++ branch/main/searchindex.js | 1 + cli.html | 369 +++++++ cli.mlfmu.html | 470 +++++++++ genindex.html | 979 ++++++++++++++++++ index.html | 481 +++++++++ objects.inv | Bin 0 -> 2606 bytes py-modindex.html | 429 ++++++++ search.html | 353 +++++++ searchindex.js | 1 + 215 files changed, 51913 insertions(+) create mode 100644 .buildinfo create mode 100644 .nojekyll create mode 100644 ADVANCED.html create mode 100644 CHANGELOG.html create mode 100644 LICENSE.html create mode 100644 LICENSE_THIRD_PARTY.html create mode 100644 MLMODEL.html create mode 100644 README.html create mode 100644 STYLEGUIDE.html create mode 100644 _autosummary/mlfmu.api.MlFmuBuilder.html create mode 100644 _autosummary/mlfmu.api.MlFmuCommand.html create mode 100644 _autosummary/mlfmu.api.MlFmuProcess.html create mode 100644 _autosummary/mlfmu.api.html create mode 100644 _autosummary/mlfmu.types.fmu_component.BaseModelConfig.html create mode 100644 _autosummary/mlfmu.types.fmu_component.FmiCausality.html create mode 100644 _autosummary/mlfmu.types.fmu_component.FmiInputVariable.html create mode 100644 _autosummary/mlfmu.types.fmu_component.FmiModel.html create mode 100644 _autosummary/mlfmu.types.fmu_component.FmiOutputVariable.html create mode 100644 _autosummary/mlfmu.types.fmu_component.FmiVariability.html create mode 100644 _autosummary/mlfmu.types.fmu_component.FmiVariable.html create mode 100644 _autosummary/mlfmu.types.fmu_component.FmiVariableType.html create mode 100644 _autosummary/mlfmu.types.fmu_component.InputVariable.html create mode 100644 _autosummary/mlfmu.types.fmu_component.InternalState.html create mode 100644 _autosummary/mlfmu.types.fmu_component.ModelComponent.html create mode 100644 _autosummary/mlfmu.types.fmu_component.OutputVariable.html create mode 100644 _autosummary/mlfmu.types.fmu_component.Variable.html create mode 100644 _autosummary/mlfmu.types.fmu_component.html create mode 100644 _autosummary/mlfmu.types.html create mode 100644 _autosummary/mlfmu.types.onnx_model.ONNXModel.html create mode 100644 _autosummary/mlfmu.types.onnx_model.html create mode 100644 _autosummary/mlfmu.utils.builder.html create mode 100644 _autosummary/mlfmu.utils.fmi_builder.html create mode 100644 _autosummary/mlfmu.utils.html create mode 100644 _autosummary/mlfmu.utils.interface.html create mode 100644 _autosummary/mlfmu.utils.logging.html create mode 100644 _autosummary/mlfmu.utils.path.html create mode 100644 _autosummary/mlfmu.utils.signals.html create mode 100644 _autosummary/mlfmu.utils.strings.html create mode 100644 _sources/ADVANCED.md.txt create mode 100644 _sources/CHANGELOG.md.txt create mode 100644 _sources/LICENSE.md.txt create mode 100644 _sources/LICENSE_THIRD_PARTY.md.txt create mode 100644 _sources/MLMODEL.md.txt create mode 100644 _sources/README.md.txt create mode 100644 _sources/STYLEGUIDE.md.txt create mode 100644 _sources/_autosummary/mlfmu.api.MlFmuBuilder.rst.txt create mode 100644 _sources/_autosummary/mlfmu.api.MlFmuCommand.rst.txt create mode 100644 _sources/_autosummary/mlfmu.api.MlFmuProcess.rst.txt create mode 100644 _sources/_autosummary/mlfmu.api.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.BaseModelConfig.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.FmiCausality.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.FmiInputVariable.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.FmiModel.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.FmiOutputVariable.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.FmiVariability.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.FmiVariable.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.FmiVariableType.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.InputVariable.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.InternalState.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.ModelComponent.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.OutputVariable.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.Variable.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.fmu_component.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.onnx_model.ONNXModel.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.onnx_model.rst.txt create mode 100644 _sources/_autosummary/mlfmu.types.rst.txt create mode 100644 _sources/_autosummary/mlfmu.utils.builder.rst.txt create mode 100644 _sources/_autosummary/mlfmu.utils.fmi_builder.rst.txt create mode 100644 _sources/_autosummary/mlfmu.utils.interface.rst.txt create mode 100644 _sources/_autosummary/mlfmu.utils.logging.rst.txt create mode 100644 _sources/_autosummary/mlfmu.utils.path.rst.txt create mode 100644 _sources/_autosummary/mlfmu.utils.rst.txt create mode 100644 _sources/_autosummary/mlfmu.utils.signals.rst.txt create mode 100644 _sources/_autosummary/mlfmu.utils.strings.rst.txt create mode 100644 _sources/api.rst.txt create mode 100644 _sources/cli.mlfmu.rst.txt create mode 100644 _sources/cli.rst.txt create mode 100644 _sources/index.rst.txt create mode 100644 _static/basic.css create mode 100644 _static/debug.css create mode 100644 _static/doctools.js create mode 100644 _static/documentation_options.js create mode 100644 _static/file.png create mode 100644 _static/language_data.js create mode 100644 _static/minus.png create mode 100644 _static/mlfmu_logo_v1.svg create mode 100644 _static/plus.png create mode 100644 _static/pygments.css create mode 100644 _static/scripts/furo-extensions.js create mode 100644 _static/scripts/furo.js create mode 100644 _static/scripts/furo.js.LICENSE.txt create mode 100644 _static/scripts/furo.js.map create mode 100644 _static/searchtools.js create mode 100644 _static/skeleton.css create mode 100644 _static/sphinx_highlight.js create mode 100644 _static/styles/furo-extensions.css create mode 100644 _static/styles/furo-extensions.css.map create mode 100644 _static/styles/furo.css create mode 100644 _static/styles/furo.css.map create mode 100644 api.html create mode 100644 branch/main/.buildinfo create mode 100644 branch/main/ADVANCED.html create mode 100644 branch/main/CHANGELOG.html create mode 100644 branch/main/LICENSE.html create mode 100644 branch/main/LICENSE_THIRD_PARTY.html create mode 100644 branch/main/MLMODEL.html create mode 100644 branch/main/README.html create mode 100644 branch/main/STYLEGUIDE.html create mode 100644 branch/main/_autosummary/mlfmu.api.MlFmuBuilder.html create mode 100644 branch/main/_autosummary/mlfmu.api.MlFmuCommand.html create mode 100644 branch/main/_autosummary/mlfmu.api.MlFmuProcess.html create mode 100644 branch/main/_autosummary/mlfmu.api.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.BaseModelConfig.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.FmiCausality.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.FmiInputVariable.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.FmiModel.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.FmiOutputVariable.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.FmiVariability.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.FmiVariable.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.FmiVariableType.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.InputVariable.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.InternalState.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.ModelComponent.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.OutputVariable.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.Variable.html create mode 100644 branch/main/_autosummary/mlfmu.types.fmu_component.html create mode 100644 branch/main/_autosummary/mlfmu.types.html create mode 100644 branch/main/_autosummary/mlfmu.types.onnx_model.ONNXModel.html create mode 100644 branch/main/_autosummary/mlfmu.types.onnx_model.html create mode 100644 branch/main/_autosummary/mlfmu.utils.builder.html create mode 100644 branch/main/_autosummary/mlfmu.utils.fmi_builder.html create mode 100644 branch/main/_autosummary/mlfmu.utils.html create mode 100644 branch/main/_autosummary/mlfmu.utils.interface.html create mode 100644 branch/main/_autosummary/mlfmu.utils.logging.html create mode 100644 branch/main/_autosummary/mlfmu.utils.path.html create mode 100644 branch/main/_autosummary/mlfmu.utils.signals.html create mode 100644 branch/main/_autosummary/mlfmu.utils.strings.html create mode 100644 branch/main/_sources/ADVANCED.md.txt create mode 100644 branch/main/_sources/CHANGELOG.md.txt create mode 100644 branch/main/_sources/LICENSE.md.txt create mode 100644 branch/main/_sources/LICENSE_THIRD_PARTY.md.txt create mode 100644 branch/main/_sources/MLMODEL.md.txt create mode 100644 branch/main/_sources/README.md.txt create mode 100644 branch/main/_sources/STYLEGUIDE.md.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.api.MlFmuBuilder.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.api.MlFmuCommand.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.api.MlFmuProcess.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.api.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.BaseModelConfig.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.FmiCausality.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.FmiInputVariable.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.FmiModel.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.FmiOutputVariable.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariability.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariable.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariableType.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.InputVariable.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.InternalState.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.ModelComponent.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.OutputVariable.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.Variable.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.fmu_component.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.onnx_model.ONNXModel.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.onnx_model.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.types.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.utils.builder.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.utils.fmi_builder.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.utils.interface.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.utils.logging.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.utils.path.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.utils.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.utils.signals.rst.txt create mode 100644 branch/main/_sources/_autosummary/mlfmu.utils.strings.rst.txt create mode 100644 branch/main/_sources/api.rst.txt create mode 100644 branch/main/_sources/cli.mlfmu.rst.txt create mode 100644 branch/main/_sources/cli.rst.txt create mode 100644 branch/main/_sources/index.rst.txt create mode 100644 branch/main/_static/basic.css create mode 100644 branch/main/_static/debug.css create mode 100644 branch/main/_static/doctools.js create mode 100644 branch/main/_static/documentation_options.js create mode 100644 branch/main/_static/file.png create mode 100644 branch/main/_static/language_data.js create mode 100644 branch/main/_static/minus.png create mode 100644 branch/main/_static/mlfmu_logo_v1.svg create mode 100644 branch/main/_static/plus.png create mode 100644 branch/main/_static/pygments.css create mode 100644 branch/main/_static/scripts/furo-extensions.js create mode 100644 branch/main/_static/scripts/furo.js create mode 100644 branch/main/_static/scripts/furo.js.LICENSE.txt create mode 100644 branch/main/_static/scripts/furo.js.map create mode 100644 branch/main/_static/searchtools.js create mode 100644 branch/main/_static/skeleton.css create mode 100644 branch/main/_static/sphinx_highlight.js create mode 100644 branch/main/_static/styles/furo-extensions.css create mode 100644 branch/main/_static/styles/furo-extensions.css.map create mode 100644 branch/main/_static/styles/furo.css create mode 100644 branch/main/_static/styles/furo.css.map create mode 100644 branch/main/api.html create mode 100644 branch/main/cli.html create mode 100644 branch/main/cli.mlfmu.html create mode 100644 branch/main/genindex.html create mode 100644 branch/main/index.html create mode 100644 branch/main/objects.inv create mode 100644 branch/main/py-modindex.html create mode 100644 branch/main/search.html create mode 100644 branch/main/searchindex.js create mode 100644 cli.html create mode 100644 cli.mlfmu.html create mode 100644 genindex.html create mode 100644 index.html create mode 100644 objects.inv create mode 100644 py-modindex.html create mode 100644 search.html create mode 100644 searchindex.js diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 0000000..b366aed --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. +config: beee1f21f7b508c607e0e7f2470f49c9 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/ADVANCED.html b/ADVANCED.html new file mode 100644 index 0000000..c07fd20 --- /dev/null +++ b/ADVANCED.html @@ -0,0 +1,456 @@ + + + + + + + + + Advanced Usage - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Advanced Usage

+
+

Editing generated FMU source

+

The command mlfmu build will both generate the C++ source code for the mlfmu and compile it automatically. However, it is possible to split this into two steps where it is possible to edit the source code to change the behavior of the resulting FMU.

+
mlfmu codegen --interface-file Interface.json --model-file model.onnx --fmu-source-path path/to/generated/source
+
+
+

This will result in a folder containing the source structured as below.

+
[FmuName]
+├── resources
+│   └── *.onnx
+├── sources
+│   ├── fmu.cpp
+│   └── model_definitions.h
+└── modelDescription.xml
+
+
+

Of these generated files, it is only recommended to modify fmu.cpp. +In this file one can e.g. modify the DoStep function of the generated FMU class.

+
class FmuName : public OnnxFmu
+{
+public:
+    FmuName(cppfmu::FMIString fmuResourceLocation)
+        : OnnxFmu(fmuResourceLocation)
+    { }
+
+    bool DoStep(cppfmu::FMIReal currentCommunicationPoint, cppfmu::FMIReal dt, cppfmu::FMIBoolean newStep,
+        cppfmu::FMIReal& endOfStep) override
+    {
+        // Implement custom behavior here
+        // ...
+
+        // Call the base class implementation
+        return OnnxFmu::DoStep(currentCommunicationPoint, dt, newStep, endOfStep);
+    }
+private:
+};
+
+
+

After doing the modification to the source code, one can simply run the compile command to complete the process.

+
mlfmu compile --fmu-source-path path/to/generated/source
+
+
+
+
+

Using class

+

In addition to the command line interface, one can use the same functionality of the tool through a Python class.

+
    +
  1. Import MlFmuBuilder and create an instance of it:

  2. +
+
from mlfmu.api import MlFmuBuilder
+from pathlib import Path
+
+builder = MlFmuBuilder(
+    ml_model_file = Path("path/to/model.onnx")
+    interface_file = Path("path/to/interface.json")
+)
+
+
+
    +
  1. Call the same commands using the class:

  2. +
+
    +
  • Run build

  • +
+
builder.build()
+
+
+
    +
  • Run codegen and then compile

  • +
+
builder.generate()
+
+# Do something ...
+
+builder.compile()
+
+
+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/CHANGELOG.html b/CHANGELOG.html new file mode 100644 index 0000000..6a6c172 --- /dev/null +++ b/CHANGELOG.html @@ -0,0 +1,536 @@ + + + + + + + + + Changelog - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Changelog

+

All notable changes to the [mlfmu] project will be documented in this file.
+The changelog format is based on Keep a Changelog.

+
+

[1.0.2]

+
+

Changed

+
    +
  • MLFMU logo is added and conf.py is updated.

  • +
  • Added checks for Windows vs Linux and fixed compilation for Linux/MacOS, updated README. Tested with Ubuntu 20.04, Ubuntu 22.04 and MacOS 14.4.

  • +
+
+
+
+

[1.0.1]

+
+

Changed

+
    +
  • Update generated docs; cleaning, fix for warnings, add missing pages and info, update authors and maintainers.

  • +
  • Add where the source code for cppfmu can be found, add third party license.

  • +
  • Added missing unit tests for the template data generated when building the FMU.

  • +
  • Unit tests for the modelDescription.xml generation.

  • +
  • Unit tests for the Interface JSON validation.

  • +
  • Wind turbine power prediction model example is included in the mlfmu\examples\wind_to_power_pyspark directory.

  • +
  • README.md : Interface.json is updated to show how to define vectors as inputs.

  • +
  • Changed from pip/tox to uv as package manager

  • +
  • README.md : Completely rewrote section “Development Setup”, introducing uv as package manager.

  • +
  • Added missing docstrings for py/cpp/h files with help of Github Copilot

  • +
  • Moved CMake + conan + c++ package files and folders with cpp code inside src folder to be included in package

  • +
  • Replace pkg_resources with importlib.metadata for getting packages version to work in python 3.12

  • +
  • Replace deprecated root_validator with model_validator in pydanitc class

  • +
  • Remove unnecessary hard coded values in utils/builder.py

  • +
  • Complete cli interface

    +
      +
    • Add subparsers to cli argparser to handle several different commands

    • +
    • Create MlFmuBuilder from args and run code according to command

    • +
    +
  • +
  • Change cli test to match the new cli interface/parser

  • +
  • Default agent_(input/output)_indexes is [] by default instead of None

  • +
  • Updated doc by running publish-interface-docs

  • +
  • Deleted azure files from old azure devops repo

  • +
  • The generated modelDescription.xml files now also contain with a list of the outputs of the FMU.

  • +
  • OnnxFmu cpp template class updated to be able to initialize state with FMU Variables

    +
      +
    • Add variables to specify which FMU variable that should be used to initialize which state

    • +
    • Add function to DoStep that initializes the state at the beginning of the first time step.

    • +
    +
  • +
  • model_definitions_template.h

    +
      +
    • Add definitions for the the number of states that should be initialized and array of index/value reference pairs to describe how the states should be initialized

    • +
    +
  • +
  • Fmu Component json interface

    +
      +
    • Add name, description and start_value to state in the json interface

    • +
    • States changed from a single InternalState to a list of InternalState

    • +
    +
  • +
  • Fixed typo from ‘tunnable’ to ‘tunable’

  • +
  • Fixed number of onnx output check to be correct (1-3 and not always raising exception)

  • +
  • Fix correct fmi causality for parameters

  • +
  • Fix correct default variability for parameters

  • +
  • Fix expanding of array variables into one variable per index for inputs and parameters to work as outputs

  • +
  • Default build target in builder to wind_to_power example

  • +
  • CMakeList.txt (from old repo) to be able to take an arbitrary path where the fmu files to be compiled are located

  • +
  • Builder to run commands to compile generated files into an fmu

    +
      +
    • Can take and keep track of arbitrary paths

    • +
    +
  • +
  • Builder checks if the files needed to compile the fmu exists before trying to compile the fmu

  • +
  • Replaced “TODO: Trow Error?” with raising a fitting exception

  • +
  • replaced black formatter with ruff formatter

  • +
  • Changed publishing workflow to use OpenID Connect (Trusted Publisher Management) when publishing to PyPI

  • +
  • Updated copyright statement

  • +
  • VS Code settings: Turned off automatic venv activation

  • +
  • Edited descriptions in the examples/wind_to_power/config/interface.json

  • +
+
+
+

Added

+
    +
  • Added BSD 3-Clause License

  • +
  • Added mypy as static type checker (in addition to pyright)

  • +
  • Add .gitattributes to handle line endings, removed eol from .editorconfig

  • +
  • Add .github/pull_request_template.md for enabling PR templates on Github

  • +
  • Add conan dependency to pyproject.toml

  • +
  • Add MlFmuBuilder class to generate code and compile FMU

    +
      +
    • Find default paths to files and directories if not given in cli

    • +
    • Run functions in utils/builder.py according to which command is being run

    • +
    • Clean up temporary/build files after the process is done

    • +
    +
  • +
  • Added feature to be able to initialize states using previously defined parameters or inputs

    +
      +
    • This is done by setting “initializationVariable” = “{variable name}”, instead of using the “name” and “start_value” attributes

    • +
    • Added flag in schema to allow a variable to be reused when initializing states

    • +
    • Allowed for multiple states to use the same variable for initialization

    • +
    +
  • +
  • .clang-format to consistently format cpp code

  • +
  • Added code to generate parameters for initialization of state

  • +
  • Wind to power model example in examples

    +
      +
    • Onnx file containing ml model

    • +
    • Interface json file containing information needed not contained in onnx file

    • +
    +
  • +
  • The generated fmu files resulting from running running builder on the new wind_to_power example

  • +
  • CMakeLists.txt and conanfile.txt from old repo to configure compiling/building FMU from generated files

  • +
+
+
+

Removed

+
    +
  • VS Code settings: Removed the setting which added the /src folder to PythonPath. This is no longer necessary. uv installs the project itself as a package in “editable” mode, which removes the need to manually add /src to the PythonPath environment variable.

  • +
+
+
+

GitHub workflows

+
    +
  • (all workflows): Adapted to use uv as package manager

  • +
  • _test_future.yml : updated Python version to 3.13.0-alpha - 3.13.0

  • +
  • _test_future.yml : updated name of test job to ‘test313’

  • +
+
+
+

Dependencies

+
    +
  • Updated to ruff>=0.6.3 (from ruff==0.2.1)

  • +
  • Updated to pyright>=1.1.378 (from pyright==1.1.350)

  • +
  • Updated to sourcery>=1.22 (from sourcery==1.15)

  • +
  • Updated to pytest>=8.3 (from pytest>=7.4)

  • +
  • updated to pytest-cov>=5.0 (from pytest-cov>=4.1)

  • +
  • Updated to Sphinx>=8.0 (from Sphinx>=7.2)

  • +
  • Updated to sphinx-argparse-cli>=1.17 (from sphinx-argparse-cli>=1.11)

  • +
  • Updated to myst-parser>=4.0 (from myst-parser>=2.0)

  • +
  • Updated to furo>=2024.8 (from furo>=2023.9.10)

  • +
  • Updated to setup-python@v5 (from setup-python@v4)

  • +
  • Updated to actions-gh-pages@v4 (from actions-gh-pages@v3)

  • +
  • Updated to upload-artifact@v4 (from upload-artifact@v3)

  • +
  • Updated to download-artifact@v4 (from download-artifact@v3)

  • +
  • Updated to dictIO>=0.3.4 (from dictIO>=0.3.1)

  • +
+
+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/LICENSE.html b/LICENSE.html new file mode 100644 index 0000000..35583ed --- /dev/null +++ b/LICENSE.html @@ -0,0 +1,382 @@ + + + + + + + + + LICENSE - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

LICENSE

+

BSD 3-Clause License

+

Copyright (c) 2024 DNV open source

+

Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met:

+
    +
  1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer.

  2. +
  3. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution.

  4. +
  5. Neither the name of the copyright holder nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission.

  6. +
+

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/LICENSE_THIRD_PARTY.html b/LICENSE_THIRD_PARTY.html new file mode 100644 index 0000000..dc46067 --- /dev/null +++ b/LICENSE_THIRD_PARTY.html @@ -0,0 +1,687 @@ + + + + + + + + + LICENSE THIRD PARTY - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

LICENSE THIRD PARTY

+
+

cppfmu

+

Source code & license at: https://github.com/viproma/cppfmu

+
+

Mozilla Public License Version 2.0

+
+
    +
  1. Definitions

  2. +
+

1.1. “Contributor” +means each individual or legal entity that creates, contributes to +the creation of, or owns Covered Software.

+

1.2. “Contributor Version” +means the combination of the Contributions of others (if any) used +by a Contributor and that particular Contributor’s Contribution.

+

1.3. “Contribution” +means Covered Software of a particular Contributor.

+

1.4. “Covered Software” +means Source Code Form to which the initial Contributor has attached +the notice in Exhibit A, the Executable Form of such Source Code +Form, and Modifications of such Source Code Form, in each case +including portions thereof.

+

1.5. “Incompatible With Secondary Licenses” +means

+
(a) that the initial Contributor has attached the notice described
+    in Exhibit B to the Covered Software; or
+
+(b) that the Covered Software was made available under the terms of
+    version 1.1 or earlier of the License, but not also under the
+    terms of a Secondary License.
+
+
+

1.6. “Executable Form” +means any form of the work other than Source Code Form.

+

1.7. “Larger Work” +means a work that combines Covered Software with other material, in +a separate file or files, that is not Covered Software.

+

1.8. “License” +means this document.

+

1.9. “Licensable” +means having the right to grant, to the maximum extent possible, +whether at the time of the initial grant or subsequently, any and +all of the rights conveyed by this License.

+

1.10. “Modifications” +means any of the following:

+
(a) any file in Source Code Form that results from an addition to,
+    deletion from, or modification of the contents of Covered
+    Software; or
+
+(b) any new file in Source Code Form that contains any Covered
+    Software.
+
+
+

1.11. “Patent Claims” of a Contributor +means any patent claim(s), including without limitation, method, +process, and apparatus claims, in any patent Licensable by such +Contributor that would be infringed, but for the grant of the +License, by the making, using, selling, offering for sale, having +made, import, or transfer of either its Contributions or its +Contributor Version.

+

1.12. “Secondary License” +means either the GNU General Public License, Version 2.0, the GNU +Lesser General Public License, Version 2.1, the GNU Affero General +Public License, Version 3.0, or any later versions of those +licenses.

+

1.13. “Source Code Form” +means the form of the work preferred for making modifications.

+

1.14. “You” (or “Your”) +means an individual or a legal entity exercising rights under this +License. For legal entities, “You” includes any entity that +controls, is controlled by, or is under common control with You. For +purposes of this definition, “control” means (a) the power, direct +or indirect, to cause the direction or management of such entity, +whether by contract or otherwise, or (b) ownership of more than +fifty percent (50%) of the outstanding shares or beneficial +ownership of such entity.

+
+
    +
  1. License Grants and Conditions

  2. +
+

2.1. Grants

+

Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license:

+

(a) under intellectual property rights (other than patent or trademark) +Licensable by such Contributor to use, reproduce, make available, +modify, display, perform, distribute, and otherwise exploit its +Contributions, either on an unmodified basis, with Modifications, or +as part of a Larger Work; and

+

(b) under Patent Claims of such Contributor to make, use, sell, offer +for sale, have made, import, and otherwise transfer either its +Contributions or its Contributor Version.

+

2.2. Effective Date

+

The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution.

+

2.3. Limitations on Grant Scope

+

The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor:

+

(a) for any code that a Contributor has removed from Covered Software; +or

+

(b) for infringements caused by: (i) Your and any other third party’s +modifications of Covered Software, or (ii) the combination of its +Contributions with other software (except as part of its Contributor +Version); or

+

(c) under Patent Claims infringed by Covered Software in the absence of +its Contributions.

+

This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4).

+

2.4. Subsequent Licenses

+

No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3).

+

2.5. Representation

+

Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License.

+

2.6. Fair Use

+

This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents.

+

2.7. Conditions

+

Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1.

+
+
    +
  1. Responsibilities

  2. +
+

3.1. Distribution of Source Form

+

All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients’ rights in the Source Code +Form.

+

3.2. Distribution of Executable Form

+

If You distribute Covered Software in Executable Form then:

+

(a) such Covered Software must also be made available in Source Code +Form, as described in Section 3.1, and You must inform recipients of +the Executable Form how they can obtain a copy of such Source Code +Form by reasonable means in a timely manner, at a charge no more +than the cost of distribution to the recipient; and

+

(b) You may distribute such Executable Form under the terms of this +License, or sublicense it under different terms, provided that the +license for the Executable Form does not attempt to limit or alter +the recipients’ rights in the Source Code Form under this License.

+

3.3. Distribution of a Larger Work

+

You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s).

+

3.4. Notices

+

You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies.

+

3.5. Application of Additional Terms

+

You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction.

+
+
    +
  1. Inability to Comply Due to Statute or Regulation

  2. +
+

If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it.

+
+
    +
  1. Termination

  2. +
+

5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice.

+

5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate.

+

5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination.

+
+
    +
  1. Disclaimer of Warranty

  2. +
+

Covered Software is provided under this License on an “as is” +basis, without warranty of any kind, either expressed, implied, or +statutory, including, without limitation, warranties that the +Covered Software is free of defects, merchantable, fit for a +particular purpose or non-infringing. The entire risk as to the +quality and performance of the Covered Software is with You. +Should any Covered Software prove defective in any respect, You +(not any Contributor) assume the cost of any necessary servicing, +repair, or correction. This disclaimer of warranty constitutes an +essential part of this License. No use of any Covered Software is +authorized under this License except under this disclaimer.

+
+
    +
  1. Limitation of Liability

  2. +
+

Under no circumstances and under no legal theory, whether tort +(including negligence), contract, or otherwise, shall any +Contributor, or anyone who distributes Covered Software as +permitted above, be liable to You for any direct, indirect, +special, incidental, or consequential damages of any character +including, without limitation, damages for lost profits, loss of +goodwill, work stoppage, computer failure or malfunction, or any +and all other commercial damages or losses, even if such party +shall have been informed of the possibility of such damages. This +limitation of liability shall not apply to liability for death or +personal injury resulting from such party’s negligence to the +extent applicable law prohibits such limitation. Some +jurisdictions do not allow the exclusion or limitation of +incidental or consequential damages, so this exclusion and +limitation may not apply to You.

+
+
    +
  1. Litigation

  2. +
+

Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party’s ability to bring +cross-claims or counter-claims.

+
+
    +
  1. Miscellaneous

  2. +
+

This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor.

+
+
    +
  1. Versions of the License

  2. +
+

10.1. New Versions

+

Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number.

+

10.2. Effect of New Versions

+

You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward.

+

10.3. Modified Versions

+

If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License).

+

10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses

+

If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached.

+
+

Exhibit A - Source Code Form License Notice

+

This Source Code Form is subject to the terms of the Mozilla Public +License, v. 2.0. If a copy of the MPL was not distributed with this +file, You can obtain one at http://mozilla.org/MPL/2.0/.

+

If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice.

+

You may add additional accurate notices of copyright ownership.

+
+

Exhibit B - “Incompatible With Secondary Licenses” Notice

+

This Source Code Form is “Incompatible With Secondary Licenses”, as +defined by the Mozilla Public License, v. 2.0.

+
+
+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/MLMODEL.html b/MLMODEL.html new file mode 100644 index 0000000..9a8424a --- /dev/null +++ b/MLMODEL.html @@ -0,0 +1,525 @@ + + + + + + + + + ML Model - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

ML Model

+
+

Onnx file

+

There are some requirements for the onnx file to be compatible with this tool. This is so that the ML FMU tool knows how to connect the inputs and outputs of the onnx file to the FMU, to use it correctly.

+

If the model takes a single input and has a single output it is already compatible as long as the input and output is shaped as (1, X) and can be directly connected to the variables of the FMU.

+
+

The possible configuration of inputs and outputs of the model

+
+        graph TD;
+subgraph 0["Only direct inputs"]
+    inputs_3["inputs"]-->Model_3["Model"]
+    Model_3["Model"]-->outputs_3["outputs"]
+end
+
+subgraph 3["All input types"]
+    inputs_0["inputs"]-->Model_0["Model"]
+    state_0["state"]-->Model_0["Model"]
+    time_0["time"]-->Model_0["Model"]
+    Model_0["Model"]-->outputs_0["outputs"]
+end
+
+subgraph 1["Inputs and States"]
+    inputs_1["inputs"]-->Model_1["Model"]
+    state_1["state"]-->Model_1["Model"]
+    Model_1["Model"]-->outputs_1["outputs"]
+end
+
+subgraph 2["Inputs and time input"]
+    inputs_2["inputs"]-->Model_2["Model"]
+    time_2["time"]-->Model_2["Model"]
+    Model_2["Model"]-->outputs_2["outputs"]
+end
+
+    
+
+
+

Usage in FMU

+
+        graph TD;
+
+    fmu_inputs["FMU inputs"]-->inputs
+    fmu_parameters["FMU parameters"]-->inputs
+    inputs --> Model
+
+    previous_outputs["previous outputs"] --> state
+    state --> Model
+
+    simulator-->time
+    time-->Model
+
+    Model-->outputs
+    outputs-->fmu_outputs["FMU outputs"]
+
+    subgraph ONNX
+        inputs
+        state
+        time
+        outputs
+        Model
+    end
+
+    
+
+

Examples

+
+

Model that only uses “pure” inputs and outputs

+
class Model():
+    num_inputs: int = 2
+    num_outputs: int = 2
+
+    ...
+
+    def call(self, all_inputs):
+        inputs, *_ = all_inputs
+
+        # Do something with the inputs
+        outputs = self.layers(inputs)
+
+        return outputs
+
+
+
+
+

Model using every input type

+

Say we have trained an ML model to predict the derivatives of outputs from some data as shown below:

+
class DerivativePredictor():
+    def call(self, all_inputs):
+        prev_outputs, prev_inputs, curr_inputs, time = all_inputs
+
+        # Do some ML stuff
+        derivative = ...
+
+        return derivative
+
+
+

However, the FMU we want to create cannot use the same inputs and outputs as the trained ML model.

+

We do not want to have previous inputs and outputs as inputs to the FMU. Instead we want it to remember the previous inputs and outputs itself. To do this we need to use the state inside the generated MLFMU using this tool.

+

We also do not want the FMU to output the derivative, but instead use the derivative to integrate the outputs. This makes it possible for the outputs themselves to be the output of the FMU.

+

To do this we need to make a wrapper around the trained ML model so that it is compatible with the tool and what we want the generated FMU to do.

+
class ModelWrapper():
+    num_inputs: int = 2
+    num_outputs: int = 2
+    derivative_predictor: DerivativePredictor = None
+
+    def call(self, all_inputs):
+        # Unpack inputs
+        inputs, state, time = all_inputs
+
+        # Unpack state into what is known to be saved in state
+        # What is contained in state is decided by what is output from this function and the state settings in interface.json
+        previous_outputs = state[:,:self.num_outputs]
+        previous_inputs = state[:,self.num_outputs:]
+
+        # Unpack time input
+        current_time =  all_inputs[:,:1]
+        dt = all_inputs[:,1:2]
+
+        # Predict something (e.g. a derivative) from the unpacked input data
+        outputs_derivative = self.derivative_predictor([previous_outputs, previous_inputs, inputs, current_time])
+
+        # Do other calculation to get data that needs to be output from the FMU
+        outputs = previous_outputs + dt * output_derivative
+
+        # Format outputs from the model to contain everything that needs to output from the FMU and/or saved as state
+        # Saving the state is easier if outputs are in the same order as they are expected to be saved in state
+        all_outputs = self.concat([outputs, inputs])
+
+        return all_outputs
+
+
+
+
+
+ +
+
+ +
+ +
+
+ + + + + + + + + + \ No newline at end of file diff --git a/README.html b/README.html new file mode 100644 index 0000000..9ea6447 --- /dev/null +++ b/README.html @@ -0,0 +1,702 @@ + + + + + + + + + mlfmu - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+

pypi +versions +license +ci +docs

+
+

mlfmu

+

MLFMU serves as a tool for developers looking to integrate machine learning models into simulation environments. It enables the creation of Functional Mock-up Units (FMUs), which are simulation models that adhere to the FMI standard (https://fmi-standard.org/), from trained machine learning models exported in the ONNX format (https://onnx.ai/). The mlfmu package streamlines the process of transforming ONNX models into FMUs, facilitating their use in a wide range of simulation platforms that support the FMI standard such as the Open Simulation Platform or DNV’s Simulation Trust Center

+
+

Features

+
    +
  • Compile trained ML models into FMUs (Functional Mock-up Units).

  • +
  • Easy to integrate in building pipelines.

  • +
  • Declarative solution, just define what the inputs/outputs/parameters of your co-simulation model should look like and MLFMU will take care of the rest.

  • +
  • Support for FMU signal vectors in FMI 2.0.

  • +
  • Advanced customizations by enabling you to change the C++ code of the FMU.

  • +
+
+
+

Installation

+
pip install mlfmu
+
+
+

You may need to run conan profile detect before running the tool. See the notes further down in this README w.r.t. required cppstd version for Windows/Linux/MacOS.

+
+
+

Creating ML FMUs

+
+

Create your own ML model

+

Before you use this mlfmu tool, you should create your machine learning (ML) model, using whatever your preferred tool is.

+
    +
  1. Define the architecture of your ML model and prepare the model to receive the inputs following to MLFMU’s input format.

  2. +
+
+

Note 1: This example subclasses a Keras model for demonstration purposes. However, the tool is flexible and can accommodate other frameworks such as PyTorch, TensorFlow, Scikit-learn, and more.

+
+
+

Note 2: We showcase a simple example here. For more detailed information on how you can prepare your model to be compatible with this tool, see MLMODEL.md

+
+
# Create your ML model
+class MlModel(tf.keras.Model):
+    def init(self, num_inputs = 2):
+        # 1 hidden layer, 1 output layer
+        self.hidden_layer = tf.keras.layers.Dense(512, activation=tf.nn.relu)
+        self.output_layer = tf.keras.layers.Dense(1, activation=None)
+
+    ...
+
+    def call(self, all_inputs): # model forward pass
+        # unpack inputs
+        inputs, *_ = all_inputs
+
+        # Do something with the inputs
+        # Here we have 1 hidden layer
+        d1 = self.hidden_layer(inputs)
+        outputs = self.output_layer(d1)
+
+        return outputs
+    ...
+
+
+
    +
  1. Train your model, then save it as an ONNX file, e.g.:

  2. +
+
import onnx
+
+ml_model = MlModel()
+# compile: configure model for training
+ml_model.compile(optimizer=tf.optimizers.RMSProp, loss='mse')
+# fit: train your ML model for some number of epochs
+ml_model.fit(training_dataset, epochs=nr_epochs)
+
+# Save the trained model as ONNX at a specified path
+onnx_model = tf2onnx.convert.from_keras(ml_model)
+onnx.save(onnx_model, 'path/to/save')
+
+
+
    +
  1. (Optional) You may want to check your onnx file to make sure it produces the right output. You can do this by loading the onnx file and (using the same test input) compare the onnx model predictions to your original model predictions. +You can also check the model using Netron: https://netron.app/ or https://github.com/lutzroeder/netron

  2. +
+
+
+

Preparing for and using MLFMU

+

Given that you have an ML model, you now need to:

+
    +
  1. Prepare the FMU interface specification (.json), to specify your FMU’s inputs, parameters, and output, map these to the ML model’s inputs and output (agentInputIndexes) and to specify whether it uses time (usesTime).

  2. +
+
// Interface.json
+{
+    "name": "MyMLFMU",
+    "description": "A Machine Learning based FMU",
+    "usesTime": true,
+    "inputs": [
+        {
+            "name": "input_1",
+            "description": "My input signal to the model at position 0",
+            "agentInputIndexes": ["0"]
+        },
+        {
+            "name": "input_2",
+            "description": "My input signal as a vector with four elements at position 1 to 5",
+            "agentInputIndexes": ["1:5"],
+            "type": "real",
+            "isArray": true,
+            "length": 4
+        }
+    ],
+    "parameters": [
+        {
+            "name": "parameter_1",
+            "description": "My input signal to the model at position 1",
+            "agentInputIndexes": ["1"]
+        }
+    ],
+    "outputs": [
+        {
+            "name": "prediction",
+            "description": "The prediction generated by ML model",
+            "agentOutputIndexes": ["0"]
+        }
+    ]
+}
+
+
+

More information about the interface.json schema can be found in the mlfmu\docs\interface\schema.html

+
    +
  1. Compile the FMU:

  2. +
+
mlfmu build --interface-file interface.json --model-file model.onnx
+
+
+

or if the files are in your current working directory:

+
mlfmu build
+
+
+
+
+
+

Extended documentation

+

For more explanation on the ONNX file structure and inputs/outputs for your model, please refer to mlfmu’s MLMODEL.md.

+

For advanced usage options, e.g. editing the generated FMU source code, or using the tool via a Python class, please refer to mlfmu’s ADVANCED.md.

+
+
+

Development Setup

+

If you just want to use mlfmu, you do not need to do the following steps. This is for those aiming to do development in this repo.

+
+

1. Install uv

+

This project uses uv as package manager. +If you haven’t already, install uv, preferably using it’s “Standalone installer” method:
+..on Windows:

+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
+
+
+

..on MacOS and Linux:

+
curl -LsSf https://astral.sh/uv/install.sh | sh
+
+
+

(see docs.astral.sh/uv for all / alternative installation methods.)

+

Once installed, you can update uv to its latest version, anytime, by running:

+
uv self update
+
+
+
+
+

2. (Windows) Install Visual Studio Build Tools

+

We use conan for building the FMU. For the conan building to work later on, you will need the Visual Studio Build tools 2022 to be installed. It is best to do this before installing conan (which gets installed as part of the package dependencies, see step 5). You can download and install the Build Tools for VS 2022 (for free) from https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022.

+
+
+

3. Clone the repository

+

Clone the mlfmu repository into your local development directory:

+
git clone https://github.com/dnv-opensource/mlfmu path/to/your/dev/mlfmu
+git submodule update --init --recursive
+
+
+
+
+

4. Install dependencies

+

Run uv sync to create a virtual environment and install all project dependencies into it:

+
uv sync
+
+
+

Use the command line option -p to specifiy the Python version to resolve the dependencies against. +For instance, use -p 3.12 to specify Python 3.12 .

+
uv sync -p 3.12
+
+
+
+

Note: In case the specified Python version is not found on your machine, uv sync will automatically download and install it.

+
+

Optionally, use -U in addition to allow package upgrades. Especially in cases when you change to a newer Python version, adding -U can be useful.
+It allows the dependency resolver to upgrade dependencies to newer versions, which might be necessary to support the (newer) Python version you specified.

+
uv sync -p 3.12 -U
+
+
+
+

Note: At this point, you should have conan installed. You will want to make sure it has the correct build profile. You can auto-detect and create the profile by running conan profile detect. +After this, you can check the profile:
+.. on Windows: in C:\Users\<USRNAM>\.conan2\profiles\.default (replace <USRNAM> with your username). You want to have: compiler=msvc, compiler.cppstd=17, compiler.version=193.
+.. on Linux: in ~/.conan2/profiles/default, you will need at least compiler.cppstd=gnu17 and compiler.libcxx=libstdc++11. +.. on MacOS: in ~/.conan2/profiles/default, you will need at least compiler.cppstd=gnu20 (tested with compiler.version=14).

+
+
+
+

5. (Optional) Activate the virtual environment

+

When using uv, most of the time there will be no longer a need to manually activate the virtual environment.
+Whenever you run a command via uv run inside your project folder structure, uv will find the .venv virtual environment in the working directory or any parent directory, and activate it on the fly:

+
uv run <command>
+
+
+

However, you still can manually activate the virtual environment if needed. +While we did not face any issues using VS Code as IDE, you might e.g. use an IDE which needs the .venv manually activated in order to properly work.
+If this is the case, you can anytime activate the virtual environment using one of the “known” legacy commands:
+..on Windows:

+
.venv\Scripts\activate.bat
+
+
+

..on Linux:

+
source .venv/bin/activate
+
+
+
+
+

6. Install pre-commit hooks

+

The .pre-commit-config.yaml file in the project root directory contains a configuration for pre-commit hooks. +To install the pre-commit hooks defined therein in your local git repository, run:

+
uv run pre-commit install
+
+
+

All pre-commit hooks configured in .pre-commit-config.yaml will now run each time you commit changes.

+
+
+

7. Test that the installation works

+

To test that the installation works, run pytest in the project root folder:

+
uv run pytest
+
+
+
+
+

8. Run an example

+
cd .\examples\wind_generator\config\
+uv run mlfmu build
+
+
+

As an alternative, you can run from the main directory:

+
uv run mlfmu build --interface-file .\examples\wind_generator\config\interface.json --model-file .\examples\wind_generator\config\example.onnx
+
+
+

Note: wherever you run the build command from, is where the FMU file will be created, unless you specify otherwise with --fmu-path.

+

For more options, see uv run mlfmu --help or uv run mlfmu build --help.

+
+
+

9. Use your new ML FMU

+

The created FMU can be used for running (co-)simulations. We have tested the FMUs that we have created in the Simulation Trust Center, which uses the Open Simulation Platform software.

+
+
+

10. Compiling the documentation

+

This repository uses sphinx with .rst and .md files as well as Python docstrings, to document the code and usage. To locally build the docs:

+
cd docs
+make html
+
+
+

You can then open index.html for access to all docs (for Windows: start build\html\index.html).

+
+
+
+

Meta

+

All code in mlfmu is DNV intellectual property.

+

Copyright (c) 2024 DNV AS. All rights reserved.

+

Primary contributors:

+

Kristoffer Skare - @LinkedIn - kristoffer.skare@dnv.com

+

Jorge Luis Mendez - @LinkedIn - jorge.luis.mendez@dnv.com

+

Additional contributors (testing, docs, examples, etc.):

+

Melih Akdağ - @LinkedIn - melih.akdag@dnv.com

+

Stephanie Kemna - @LinkedIn

+

Hee Jong Park - @LinkedIn - hee.jong.park@dnv.com

+
+
+

Contributing

+
    +
  1. Fork it (https://github.com/dnv-opensource/mlfmu/fork) (Note: this is currently disabled for this repo. For development, continue with the next step.)

  2. +
  3. Create an issue in your GitHub repo

  4. +
  5. Create your branch based on the issue number and type (git checkout -b issue-name)

  6. +
  7. Evaluate and stage the changes you want to commit (git add -i)

  8. +
  9. Commit your changes (git commit -am 'place a descriptive commit message here')

  10. +
  11. Push to the branch (git push origin issue-name)

  12. +
  13. Create a new Pull Request in GitHub

  14. +
+

For your contribution, please make sure you follow the STYLEGUIDE before creating the Pull Request.

+

Note; version numbers should be updated in: CHANGELOG.md, pyproject.toml, and source/docs/conf.py.

+
+
+

Errors & fixes

+
    +
  • If you get an error similar to ..\fmu.cpp(4,10): error C1083: Cannot open include file: 'cppfmu_cs.hpp': No such file or directory, you are missing cppfmu. This is a submodule to this repository. Make sure that you do a git submodule update --init --recursive in the top level folder.

  • +
+
+
+

License & dependencies

+

This code is distributed under the BSD 3-Clause license. See LICENSE for more information.

+

It makes use of cpp-fmu, which is distributed under the MPL license at https://github.com/viproma/cppfmu.

+ +
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/STYLEGUIDE.html b/STYLEGUIDE.html new file mode 100644 index 0000000..3639ea5 --- /dev/null +++ b/STYLEGUIDE.html @@ -0,0 +1,830 @@ + + + + + + + + + Style Guide - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Style Guide

+

All code shall be Ruff formatted.

+

References, details as well as examples of bad/good styles and their respective reasoning can be found below.

+
+

References

+ +
+
+

Code Layout

+
    +
  • Use 4 spaces instead of tabs

  • +
  • Maximum line length is 120 characters (not 79 as proposed in PEP-8)

  • +
  • 2 blank lines between classes and functions

  • +
  • 1 blank line within class, between class methods

  • +
  • Use blank lines for logic separation of functionality within functions/methods wherever it is justified

  • +
  • No whitespace adjacent to parentheses, brackets, or braces

  • +
+
    # Bad
+    spam( items[ 1 ], { key1 : arg1, key2 : arg2 }, )
+
+    # Good
+    spam(items[1], {key1: arg1, key2: arg2}, [])
+
+
+
    +
  • Surround operators with single whitespace on either side.

  • +
+
    # Bad
+    x<1
+
+    # Good
+    x == 1
+
+
+
    +
  • Never end your lines with a semicolon, and do not use a semicolon to put two statements on the same line

  • +
  • When branching, always start a new block on a new line

  • +
+
    # Bad
+    if flag: return None
+
+    # Good
+    if flag:
+        return None
+
+
+
    +
  • Similarly to branching, do not write methods on one line in any case:

  • +
+
    # Bad
+    def do_something(self): print("Something")
+
+    # Good
+    def do_something(self):
+        print("Something")
+
+
+
    +
  • Place a class’s __init__ function (the constructor) always at the beginning of the class

  • +
+
+
+

Line Breaks

+
    +
  • If function arguments do not fit into the specified line length, move them to a new line with indentation

  • +
+
    # Bad
+    def long_function_name(var_one, var_two, var_three,
+        var_four):
+        print(var_one)
+
+    # Bad
+    def long_function_name(var_one, var_two, var_three,
+            var_four):
+        print(var_one)
+
+    # Better (but not preferred)
+    def long_function_name(var_one,
+                           var_two,
+                           var_three,
+                           var_four):
+        print(var_one)
+
+    # Good (and preferred)
+    def long_function_name(
+        var_one,
+        var_two,
+        var_three,
+        var_four,
+    ):
+        print(var_one)
+
+
+
    +
  • Move concatenated logical conditions to new lines if the line does not fit the maximum line size. This will help you understand the condition by looking from top to bottom. Poor formatting makes it difficult to read and understand complex predicates.

  • +
+
    # Good
+    if (
+        this_is_one_thing
+        and that_is_another_thing
+        or that_is_third_thing
+        or that_is_yet_another_thing
+        and one_more_thing
+    ):
+        do_something()
+
+
+
    +
  • Where binary operations stretch multiple lines, break lines before the binary operators, not thereafter

  • +
+
    # Bad
+    GDP = (
+        private_consumption +
+        gross_investment +
+        government_investment +
+        government_spending +
+        (exports - imports)
+    )
+
+    # Good
+    GDP = (
+        private_consumption
+        + gross_investment
+        + government_investment
+        + government_spending
+        + (exports - imports)
+    )
+
+
+
    +
  • Chaining methods should be broken up on multiple lines for better readability

  • +
+
    (
+        df.write.format("jdbc")
+        .option("url", "jdbc:postgresql:dbserver")
+        .option("dbtable", "schema.tablename")
+        .option("user", "username")
+        .option("password", "password")
+        .save()
+    )
+
+
+
    +
  • Add a trailing comma to sequences of items when the closing container token ], ), or } does not appear on the same line as the final element

  • +
+
    # Bad
+    y = [
+        0,
+        1,
+        4,
+        6
+    ]
+    z = {
+        'a': 1,
+        'b': 2
+    }
+
+    # Good
+    x = [1, 2, 3]
+
+    # Good
+    y = [
+        0,
+        1,
+        4,
+        6,         <- note the trailing comma
+    ]
+    z = {
+        'a': 1,
+        'b': 2,    <- note the trailing comma
+    }
+
+
+
+
+

String Formatting

+
    +
  • When quoting string literals, use double-quoted strings. When the string itself contains single or double quote characters, however, use the respective other one to avoid backslashes in the string. It improves readability.

  • +
  • Use f-strings to format strings:

  • +
+
    # Bad
+    print("Hello, %s. You are %s years old. You are a %s." % (name, age, profession))
+
+    # Good
+    print(f"Hello, {name}. You are {age} years old. You are a {profession}.")
+
+
+
    +
  • Use multiline strings, not \ , since it gets much more readable.

  • +
+
    raise AttributeError(
+        "Here is a multiline error message with a very long first line "
+        "and a shorter second line."
+    )
+
+
+
+
+

Naming Conventions

+
    +
  • For module names: lowercase . +Long module names can have words separated by underscores (really_long_module_name.py), but this is not required. Try to use the convention of nearby files.

  • +
  • For class names: CamelCase

  • +
  • For methods, functions, variables and attributes: lowercase_with_underscores

  • +
  • For constants: UPPERCASE or UPPERCASE_WITH_UNDERSCORES +(Python does not differentiate between variables and constants. Using UPPERCASE for constants is just a convention, but helps a lot to quickly identify variables meant to serve as constants.)

  • +
  • Implementation-specific private methods and variables will use _single_underscore_prefix

  • +
  • Don’t include the type of a variable in its name. +E.g. use senders instead of sender_list

  • +
  • Names shall be clear about what a variable, class, or function contains or does. If you struggle to come up with a clear name, rethink your architecture: Often, the difficulty in finding a crisp name for something is a hint that separation of responsibilities can be improved. The solution then is less to agree on a name, but to start a round of refactoring: The name you’re seeking often comes naturally then with refactoring to an improved architecture with clear responsibilities. +(see SRP, Single-Responsibilty Principle by Robert C. Martin)

  • +
+
+
+

Named Arguments

+
    +
  • Use named arguments to improve readability and avoid mistakes introduced with future code maintenance

  • +
+
    # Bad
+    urlget("[http://google.com](http://google.com/)", 20)
+
+    # Good
+    urlget("[http://google.com](http://google.com/)", timeout=20)
+
+
+
    +
  • Never use mutable objects as default arguments in Python. If an attribute in a class or a named parameter in a function is of a mutable data type (e.g. a list or dict), never set its default value in the declaration of an object but always set it to None first, and then only later assign the default value in the class’s constructor, or the functions body, respectively. Sounds complicated? If you prefer the shortcut, the examples below are your friend. +If your are interested in the long story including the why‘s, read these discussions on Reddit and Twitter.

  • +
+
    # Bad
+    class Foo:
+        items = []
+
+    # Good
+    class Foo:
+        items = None
+        def __init__(self):
+            self.items = []
+
+
+    # Bad
+    class Foo:
+        def __init__(self, items=[]):
+            self.items = items
+
+    # Good
+    class Foo:
+        def __init__(self, items=None):
+            self.items = items or []
+
+
+    # Bad
+    def some_function(x, y, items=[]):
+        ...
+
+    # Good
+    def some_function(x, y, items=None):
+        items = items or []
+        ...
+
+
+
+
+

Commenting

+
    +
  • First of all, if the code needs comments to clarify its work, you should think about refactoring it. The best comment to code is the code itself.

  • +
  • Describe complex, possibly incomprehensible points and side effects in the comments

  • +
  • Separate # and the comment with one whitespace

  • +
+
    #bad comment
+    # good comment
+
+
+
    +
  • Use inline comments sparsely

  • +
  • Where used, inline comments shall have 2 whitespaces before the # and one whitespace thereafter

  • +
+
    x = y + z  # inline comment
+    str1 = str2 + str3  # another inline comment
+
+
+
    +
  • If a piece of code is poorly understood, mark the piece with a @TODO: tag and your name to support future refactoring:

  • +
+
    def get_ancestors_ids(self):
+        # @TODO: Do a cache reset while saving the category tree. CLAROS, YYYY-MM-DD
+        cache_name = f"{self._meta.model_name}_ancestors_{self.pk}"
+        cached_ids = cache.get(cache_name)
+        if cached_ids:
+            return cached_ids
+
+        ids = [c.pk for c in self.get_ancestors(include_self=True)]
+        cache.set(cache_name, ids, timeout=3600)
+
+        return ids
+
+
+
+
+

Type hints

+
    +
  • Use type hints in function signatures and module-scope variables. This is good documentation and can be used with linters for type checking and error checking. Use them whenever possible.

  • +
  • Use pyi files to type annotate third-party or extension modules.

  • +
+
+
+

Docstrings

+
    +
  • All Docstrings should be written in Numpy format. For a good tutorial on Docstrings, see Documenting Python Code: A Complete Guide

  • +
  • In a Docstring, summarize function/method behavior and document its arguments, return value(s), side effects, exceptions raised, and restrictions

  • +
  • Wrap Docstrings with triple double quotes (“””)

  • +
  • The description of the arguments must be indented

  • +
+
    def some_method(name, print=False):
+        """This function does something
+
+        Parameters
+        ----------
+        name : str
+            The name to use
+        print: bool, optional
+            A flag used to print the name to the console, by default False
+
+        Raises
+        ------
+        KeyError
+            If name is not found
+
+        Returns
+        -------
+        int
+            The return code
+        """
+        ...
+        return 0
+
+
+
+
+

Exceptions

+
    +
  • Raise specific exceptions and catch specific exceptions, such as KeyError, ValueError, etc.

  • +
  • Do not raise or catch just Exception, except in rare cases where this is unavoidable, such as a try/except block on the top-level loop of some long-running process. For a good tutorial on why this matters, see The Most Diabolical Python Antipattern.

  • +
  • Minimize the amount of code in a try/except block. The larger the body of the try, +the more likely that an exception will be raised by a line of code that you didn’t expect to raise an exception.

  • +
+
+
+

Imports

+
    +
  • Avoid creating circular imports by importing modules more specialized than the one you are editing

  • +
  • Relative imports are forbidden (PEP-8 only “highly discourages” them). Where absolutely needed, the from future import absolute_import syntax should be used (see PEP-328)

  • +
  • Never use wildcard imports (from <module> import *). Always be explicit about what you’re importing. Namespaces make code easier to read, so use them.

  • +
  • Break long imports using parentheses and indent by 4 spaces. Include the trailing comma after the last import and place the closing bracket on a separate line

  • +
+
    from my_pkg.utils import (
+        some_utility_method_1,
+        some_utility_method_2,
+        some_utility_method_3,
+        some_utility_method_4,
+        some_utility_method_5,
+    )
+
+
+
    +
  • Imports should be written in the following order, separated by a blank line:

    +
      +
    1. build-in modules

    2. +
    3. third-party modules

    4. +
    5. local application/library specific imports

    6. +
    +
  • +
+
    import logging
+    import os
+    import typing as T
+
+    import pandas as pd
+    import numpy as np
+
+    import mlfmu
+    import mlfmu.my_module
+    from mlfmu.my_module import my_function, MyClass
+
+
+
    +
  • Even if a Python file is intended to be used as executable / script file only, it shall still be importable as a module, and its import should not have any side effects. Its main functionality shall hence be in a main() function, so that the code can be imported as a module for testing or being reused in the future:

  • +
+
    def main():
+        ...
+
+    if __name__ == "__main__":
+        main()
+
+
+
+
+

Unit-tests

+
    +
  • Use pytest as the preferred testing framework.

  • +
  • The name of a test shall clearly express what is being tested.

  • +
  • Each test should preferably check only one specific aspect.

  • +
+
    # Bad
+    def test_smth():
+        result = f()
+        assert isinstance(result, list)
+        assert result[0] == 1
+        assert result[1] == 2
+        assert result[2] == 3
+        assert result[3] == 4
+
+    # Good
+    def test_smth_type():
+        result = f()
+        assert isinstance(result, list), "Result should be list"
+
+    def test_smth_values():
+        result = f()
+        assert set(result) == set(expected), f"Result should be {set(expected)}"
+
+
+
+
+

And finally: It is a bad idea to use

+
    +
  • global variables.

  • +
  • iterators where they can be replaced by vectorized operations.

  • +
  • lambda where it is not required.

  • +
  • map and lambda where it can be replaced by a simple list comprehension.

  • +
  • multiple nested maps and lambdas.

  • +
  • nested functions. They are hard to test and debug.

  • +
+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.api.MlFmuBuilder.html b/_autosummary/mlfmu.api.MlFmuBuilder.html new file mode 100644 index 0000000..b7ddcb4 --- /dev/null +++ b/_autosummary/mlfmu.api.MlFmuBuilder.html @@ -0,0 +1,621 @@ + + + + + + + + + MlFmuBuilder - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

MlFmuBuilder

+
+
+class mlfmu.api.MlFmuBuilder(fmu_name: str | None = None, interface_file: Path | None = None, ml_model_file: Path | None = None, source_folder: Path | None = None, fmu_output_folder: Path | None = None, build_folder: Path | None = None, root_directory: Path | None = None)
+

Bases: object

+

Builder for creating FMUs (Functional Mock-up Units) from machine learning models.

+

This class is core to executing the different commands in the mlfmu process.

+
+
+__init__(fmu_name: str | None = None, interface_file: Path | None = None, ml_model_file: Path | None = None, source_folder: Path | None = None, fmu_output_folder: Path | None = None, build_folder: Path | None = None, root_directory: Path | None = None) None
+

Initialize a new instance of the MlFmuBuilder class.

+
+
Parameters:
+
    +
  • fmu_name (str | None, optional) – The name of the FMU., by default None

  • +
  • interface_file (Path | None, optional) – The path to the interface JSON file., by default None

  • +
  • ml_model_file (Path | None, optional) – The path to the machine learning model file., by default None

  • +
  • source_folder (Path | None, optional) – The folder containing the source code for the FMU., by default None

  • +
  • fmu_output_folder (Path | None, optional) – The folder where the built FMU will be saved., by default None

  • +
  • build_folder (Path | None, optional) – The folder where the FMU will be built., by default None

  • +
  • root_directory (Path | None, optional) – The root directory for the builder., by default None

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__([fmu_name, interface_file, ...])

Initialize a new instance of the MlFmuBuilder class.

build()

Build an FMU from the machine learning model file and interface file.

compile()

Compile the FMU from the C++ source code and model description.

default_build_folder()

Return the path to a build folder inside the temp_folder.

default_build_source_folder()

Return the path to a src folder inside the temp_folder.

default_compile_source_folder()

Return the path to the default source folder for the compile process.

default_fmu_output_folder()

Return the path to the default fmu output folder.

default_generate_source_folder()

Return the path to the default source folder for the generate process.

default_interface_file()

Return the path to a interface json file inside self.root_directory if it can be inferred.

default_model_file()

Return the path to a ml model file inside self.root_directory if it can be inferred.

generate()

Generate C++ source code and model description from the machine learning model file and interface file.

+
+

Attributes

+
+ + + + + + +

temp_folder

The temporary folder used for building the FMU.

+
+
+
+build() None
+

Build an FMU from the machine learning model file and interface file.

+

Builds an FMU from ml_model_file and interface_file and saves it to fmu_output_folder. +If the paths to the necessary files and directories are not given the function +will try to find files and directories that match the ones needed.

+
+
Raises:
+
    +
  • FileNotFoundError – if ml_model_file or interface_file do not exists or is not set and cannot be easily inferred.

  • +
  • ---

  • +
+
+
+
+ +
+
+compile() None
+

Compile the FMU from the C++ source code and model description.

+

Compiles the FMU from the FMU C++ source code and model description contained in source_folder +and saves it to fmu_output_folder.

+

If the paths to the necessary files and directories are not given the function +will try to find files and directories that match the ones needed.

+
+
Raises:
+

FileNotFoundError – if source_folder or fmu_name is not set and cannot be easily inferred.

+
+
+
+ +
+
+default_build_folder() Path
+

Return the path to a build folder inside the temp_folder. Creates the temp_folder if it is not set.

+
+
Returns:
+

the path to the build folder.

+
+
Return type:
+

Path

+
+
+
+ +
+
+default_build_source_folder() Path
+

Return the path to a src folder inside the temp_folder. Creates the temp_folder if it is not set.

+
+
Returns:
+

the path to the src folder.

+
+
Return type:
+

Path

+
+
+
+ +
+
+default_compile_source_folder() Path | None
+

Return the path to the default source folder for the compile process.

+

Searches inside self.source_folder and self.root_directory for a folder that contains a folder structure +and files that is required to be valid ml fmu source code.

+
+
Returns:
+

the path to the default source folder for the compile process.

+
+
Return type:
+

Path

+
+
+
+ +
+
+default_fmu_output_folder() Path
+

Return the path to the default fmu output folder.

+
+
Returns:
+

the path to the default fmu output folder.

+
+
Return type:
+

Path

+
+
+
+ +
+
+default_generate_source_folder() Path
+

Return the path to the default source folder for the generate process.

+
+
Returns:
+

the path to the default source folder for the generate process.

+
+
Return type:
+

Path

+
+
+
+ +
+
+default_interface_file() Path | None
+

Return the path to a interface json file inside self.root_directory if it can be inferred.

+
+
Returns:
+

the path to the interface json file, or None.

+
+
Return type:
+

Path | None

+
+
+
+ +
+
+default_model_file() Path | None
+

Return the path to a ml model file inside self.root_directory if it can be inferred.

+
+
Returns:
+

the path to the ml model file, or None.

+
+
Return type:
+

Path | None

+
+
+
+ +
+
+generate() None
+

Generate C++ source code and model description from the machine learning model file and interface file.

+

Generates FMU C++ source code and model description from ml_model_file and interface_file +and saves it to source_folder.

+

If the paths to the necessary files and directories are not given the function +will try to find files and directories that match the ones needed.

+
+
Raises:
+

FileNotFoundError – if ml_model_file or interface_file do not exists or is not set and cannot be easily inferred.

+
+
+
+ +
+
+temp_folder: TemporaryDirectory[str]
+

The temporary folder used for building the FMU.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.api.MlFmuCommand.html b/_autosummary/mlfmu.api.MlFmuCommand.html new file mode 100644 index 0000000..b23393b --- /dev/null +++ b/_autosummary/mlfmu.api.MlFmuCommand.html @@ -0,0 +1,442 @@ + + + + + + + + + MlFmuCommand - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

MlFmuCommand

+
+
+class mlfmu.api.MlFmuCommand(value, names=_not_given, *values, module=None, qualname=None, type=None, start=1, boundary=None)
+

Bases: Enum

+

Enum class for the different commands in the mlfmu process.

+
+
+__init__(*args, **kwds)
+
+ +

Methods

+
+ + + + + + +

from_string(command_string)

+
+

Attributes

+
+ + + + + + + + + + + + +

BUILD

GENERATE

COMPILE

+
+
+
+static from_string(command_string: str) MlFmuCommand | None
+
+ +
+
+BUILD = 'build'
+
+ +
+
+COMPILE = 'compile'
+
+ +
+
+GENERATE = 'codegen'
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.api.MlFmuProcess.html b/_autosummary/mlfmu.api.MlFmuProcess.html new file mode 100644 index 0000000..35e0487 --- /dev/null +++ b/_autosummary/mlfmu.api.MlFmuProcess.html @@ -0,0 +1,454 @@ + + + + + + + + + MlFmuProcess - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

MlFmuProcess

+
+
+class mlfmu.api.MlFmuProcess(command: MlFmuCommand, source_folder: Path | None = None, ml_model_file: Path | None = None, interface_file: Path | None = None, fmu_output_folder: Path | None = None)
+

Bases: object

+

Represents the ML FMU process.

+

This class encapsulates the functionality to run the ML FMU process in a self-terminated loop. +It provides methods to control the execution of the process and manage the number of runs.

+
+
+__init__(command: MlFmuCommand, source_folder: Path | None = None, ml_model_file: Path | None = None, interface_file: Path | None = None, fmu_output_folder: Path | None = None) None
+

Instantiate the MlFmuProcess.

+
+
Parameters:
+
    +
  • command (MlFmuCommand) – The command to be executed by the process.

  • +
  • source_folder (Path | None, optional) – The path to the source folder., by default None

  • +
  • ml_model_file (Path | None, optional) – The path to the ML model file., by default None

  • +
  • interface_file (Path | None, optional) – The path to the interface file., by default None

  • +
  • fmu_output_folder (Path | None, optional) – The path to the FMU output folder., by default None

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + +

__init__(command[, source_folder, ...])

Instantiate the MlFmuProcess.

run()

Run the mlfmu process.

+
+

Attributes

+
+ + + + + + + + + +

command

The command to be executed by the process.

builder

The builder object responsible for building the FMU.

+
+
+
+run() None
+

Run the mlfmu process.

+

Runs the mlfmu process in a self-terminated loop.

+
+ +
+
+builder: MlFmuBuilder
+

The builder object responsible for building the FMU.

+
+ +
+
+command: MlFmuCommand
+

The command to be executed by the process.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.api.html b/_autosummary/mlfmu.api.html new file mode 100644 index 0000000..3a4f660 --- /dev/null +++ b/_autosummary/mlfmu.api.html @@ -0,0 +1,421 @@ + + + + + + + + + mlfmu.api - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.api

+

Functions

+
+ + + + + + +

run(command, interface_file, model_file, ...)

Run the mlfmu process.

+
+

Classes

+
+ + + + + + + + + + + + +

MlFmuBuilder([fmu_name, interface_file, ...])

Builder for creating FMUs (Functional Mock-up Units) from machine learning models.

MlFmuCommand(value[, names, module, ...])

Enum class for the different commands in the mlfmu process.

MlFmuProcess(command[, source_folder, ...])

Represents the ML FMU process.

+
+
+
+mlfmu.api.run(command: MlFmuCommand, interface_file: str | None, model_file: str | None, fmu_path: str | None, source_folder: str | None) None
+

Run the mlfmu process.

+

Run the mlfmu process with the given command and optional parameters.

+
+
Parameters:
+
    +
  • command (MlFmuCommand) – which command in the mlfmu process that should be run

  • +
  • interface_file (Optional[str]) – the path to the file containing the FMU interface. Will be inferred if not provided.

  • +
  • model_file (Optional[str]) – the path to the ml model file. Will be inferred if not provided.

  • +
  • fmu_path (Optional[str]) – the path to where the built FMU should be saved. Will be inferred if not provided.

  • +
  • source_folder (Optional[str]) – the path to where the FMU source code is located. Will be inferred if not provided.

  • +
+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.BaseModelConfig.html b/_autosummary/mlfmu.types.fmu_component.BaseModelConfig.html new file mode 100644 index 0000000..a448abf --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.BaseModelConfig.html @@ -0,0 +1,504 @@ + + + + + + + + + BaseModelConfig - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

BaseModelConfig

+
+
+class mlfmu.types.fmu_component.BaseModelConfig
+

Bases: BaseModel

+

Enables the alias_generator for all cases.

+
+
+__init__(**data: Any) None
+

Create a new model by parsing and validating input data from keyword arguments.

+

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be +validated to form a valid model.

+

self is explicitly positional-only to allow self as a field name.

+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(**data)

Create a new model by parsing and validating input data from keyword arguments.

construct([_fields_set])

copy(*[, include, exclude, update, deep])

Returns a copy of the model.

dict(*[, include, exclude, by_alias, ...])

from_orm(obj)

json(*[, include, exclude, by_alias, ...])

model_construct([_fields_set])

Creates a new instance of the Model class with validated data.

model_copy(*[, update, deep])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#model_copy

model_dump(*[, mode, include, exclude, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump

model_dump_json(*[, indent, include, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump_json

model_json_schema([by_alias, ref_template, ...])

Generates a JSON schema for a model class.

model_parametrized_name(params)

Compute the class name for parametrizations of generic classes.

model_post_init(_BaseModel__context)

Override this method to perform additional initialization after __init__ and model_construct.

model_rebuild(*[, force, raise_errors, ...])

Try to rebuild the pydantic-core schema for the model.

model_validate(obj, *[, strict, ...])

Validate a pydantic model instance.

model_validate_json(json_data, *[, strict, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/json/#json-parsing

model_validate_strings(obj, *[, strict, context])

Validate the given object with string data against the Pydantic model.

parse_file(path, *[, content_type, ...])

parse_obj(obj)

parse_raw(b, *[, content_type, encoding, ...])

schema([by_alias, ref_template])

schema_json(*[, by_alias, ref_template])

update_forward_refs(**localns)

validate(value)

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + +

model_computed_fields

model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_extra

Get extra fields set during validation.

model_fields

model_fields_set

Returns the set of fields that have been explicitly set on this model instance.

+
+
+
+model_config: ClassVar[ConfigDict] = {'alias_generator': <function to_camel>, 'populate_by_name': True}
+

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.FmiCausality.html b/_autosummary/mlfmu.types.fmu_component.FmiCausality.html new file mode 100644 index 0000000..bca637d --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.FmiCausality.html @@ -0,0 +1,577 @@ + + + + + + + + + FmiCausality - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

FmiCausality

+
+
+class mlfmu.types.fmu_component.FmiCausality(value, names=_not_given, *values, module=None, qualname=None, type=None, start=1, boundary=None)
+

Bases: str, Enum

+

Enum for variable causality.

+
+
+__init__(*args, **kwds)
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

encode([encoding, errors])

Encode the string using the codec registered for encoding.

replace(old, new[, count])

Return a copy with all occurrences of substring old replaced by new.

split([sep, maxsplit])

Return a list of the substrings in the string, using sep as the separator string.

rsplit([sep, maxsplit])

Return a list of the substrings in the string, using sep as the separator string.

join(iterable, /)

Concatenate any number of strings.

capitalize()

Return a capitalized version of the string.

casefold()

Return a version of the string suitable for caseless comparisons.

title()

Return a version of the string where each word is titlecased.

center(width[, fillchar])

Return a centered string of length width.

count(sub[, start[, end]])

Return the number of non-overlapping occurrences of substring sub in string S[start:end].

expandtabs([tabsize])

Return a copy where all tab characters are expanded using spaces.

find(sub[, start[, end]])

Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].

partition(sep, /)

Partition the string into three parts using the given separator.

index(sub[, start[, end]])

Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].

ljust(width[, fillchar])

Return a left-justified string of length width.

lower()

Return a copy of the string converted to lowercase.

lstrip([chars])

Return a copy of the string with leading whitespace removed.

rfind(sub[, start[, end]])

Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].

rindex(sub[, start[, end]])

Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].

rjust(width[, fillchar])

Return a right-justified string of length width.

rstrip([chars])

Return a copy of the string with trailing whitespace removed.

rpartition(sep, /)

Partition the string into three parts using the given separator.

splitlines([keepends])

Return a list of the lines in the string, breaking at line boundaries.

strip([chars])

Return a copy of the string with leading and trailing whitespace removed.

swapcase()

Convert uppercase characters to lowercase and lowercase characters to uppercase.

translate(table, /)

Replace each character in the string using the given translation table.

upper()

Return a copy of the string converted to uppercase.

startswith(prefix[, start[, end]])

Return True if S starts with the specified prefix, False otherwise.

endswith(suffix[, start[, end]])

Return True if S ends with the specified suffix, False otherwise.

removeprefix(prefix, /)

Return a str with the given prefix string removed if present.

removesuffix(suffix, /)

Return a str with the given suffix string removed if present.

isascii()

Return True if all characters in the string are ASCII, False otherwise.

islower()

Return True if the string is a lowercase string, False otherwise.

isupper()

Return True if the string is an uppercase string, False otherwise.

istitle()

Return True if the string is a title-cased string, False otherwise.

isspace()

Return True if the string is a whitespace string, False otherwise.

isdecimal()

Return True if the string is a decimal string, False otherwise.

isdigit()

Return True if the string is a digit string, False otherwise.

isnumeric()

Return True if the string is a numeric string, False otherwise.

isalpha()

Return True if the string is an alphabetic string, False otherwise.

isalnum()

Return True if the string is an alpha-numeric string, False otherwise.

isidentifier()

Return True if the string is a valid Python identifier, False otherwise.

isprintable()

Return True if the string is printable, False otherwise.

zfill(width, /)

Pad a numeric string with zeros on the left, to fill a field of the given width.

format(*args, **kwargs)

Return a formatted version of S, using substitutions from args and kwargs.

format_map(mapping)

Return a formatted version of S, using substitutions from mapping.

maketrans

Return a translation table usable for str.translate().

__init__(*args, **kwds)

+
+

Attributes

+
+ + + + + + + + + + + + +

PARAMETER

INPUT

OUTPUT

+
+
+
+INPUT = 'input'
+
+ +
+
+OUTPUT = 'output'
+
+ +
+
+PARAMETER = 'parameter'
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.FmiInputVariable.html b/_autosummary/mlfmu.types.fmu_component.FmiInputVariable.html new file mode 100644 index 0000000..87cff7f --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.FmiInputVariable.html @@ -0,0 +1,563 @@ + + + + + + + + + FmiInputVariable - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

FmiInputVariable

+
+
+class mlfmu.types.fmu_component.FmiInputVariable(*, name: str, type: ~mlfmu.types.fmu_component.FmiVariableType = FmiVariableType.REAL, description: str | None = None, variability: ~mlfmu.types.fmu_component.FmiVariability | None = None, startValue: float | str | bool | int | None = 0, isArray: bool = False, length: int | None = None, agentInputIndexes: list[~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=True, to_upper=True, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^(\d+|\d+:\d+)$)]] = [], causality: ~mlfmu.types.fmu_component.FmiCausality, variableReferences: list[int], agentStateInitIndexes: list[list[int]] = [])
+

Bases: InputVariable

+

Data class representing an input variable in an FMI component.

+
+
+__init__(**kwargs: Any) None
+

Create an FMI input variable.

+
+
Parameters:
+
    +
  • causality (FmiCausality, optional) – Causality of the input variable., by default FmiCausality.INPUT

  • +
  • variable_references (list[int], optional) – List of variable references associated with the input variable., by default []

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(**kwargs)

Create an FMI input variable.

construct([_fields_set])

copy(*[, include, exclude, update, deep])

Returns a copy of the model.

dict(*[, include, exclude, by_alias, ...])

from_orm(obj)

json(*[, include, exclude, by_alias, ...])

model_construct([_fields_set])

Creates a new instance of the Model class with validated data.

model_copy(*[, update, deep])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#model_copy

model_dump(*[, mode, include, exclude, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump

model_dump_json(*[, indent, include, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump_json

model_json_schema([by_alias, ref_template, ...])

Generates a JSON schema for a model class.

model_parametrized_name(params)

Compute the class name for parametrizations of generic classes.

model_post_init(_BaseModel__context)

Override this method to perform additional initialization after __init__ and model_construct.

model_rebuild(*[, force, raise_errors, ...])

Try to rebuild the pydantic-core schema for the model.

model_validate(obj, *[, strict, ...])

Validate a pydantic model instance.

model_validate_json(json_data, *[, strict, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/json/#json-parsing

model_validate_strings(obj, *[, strict, context])

Validate the given object with string data against the Pydantic model.

parse_file(path, *[, content_type, ...])

parse_obj(obj)

parse_raw(b, *[, content_type, encoding, ...])

schema([by_alias, ref_template])

schema_json(*[, by_alias, ref_template])

update_forward_refs(**localns)

validate(value)

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

model_computed_fields

model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_extra

Get extra fields set during validation.

model_fields

model_fields_set

Returns the set of fields that have been explicitly set on this model instance.

causality

The causality of the input variable.

variable_references

The list of variable references associated with the input variable.

agent_state_init_indexes

List of state initialization indexes for ONNX model - concerns mapping of FMU input variables to ONNX states.

agent_input_indexes

Index or range of indices of ONNX (agent) inputs to which this FMU signal shall be linked to.

name

Unique name for the port.

type

Data type as defined by FMI standard.

description

Short FMU variable description.

variability

Signal variability as defined by FMI.

start_value

Initial value of the signal at time step 1.

is_array

When dealing with an array signal, it is essential to specify the LENGTH parameter.

length

Defines the number of entries in the signal if the signal is array.

+
+
+
+agent_state_init_indexes: list[list[int]]
+

List of state initialization indexes for ONNX model - concerns mapping of FMU input variables to ONNX states.

+
+ +
+
+causality: FmiCausality
+

The causality of the input variable.

+
+ +
+
+model_config: ClassVar[ConfigDict] = {'alias_generator': <function to_camel>, 'populate_by_name': True}
+

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

+
+ +
+
+variable_references: list[int]
+

The list of variable references associated with the input variable.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.FmiModel.html b/_autosummary/mlfmu.types.fmu_component.FmiModel.html new file mode 100644 index 0000000..95e4c54 --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.FmiModel.html @@ -0,0 +1,636 @@ + + + + + + + + + FmiModel - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

FmiModel

+
+
+class mlfmu.types.fmu_component.FmiModel(model: ModelComponent)
+

Bases: object

+

Represents an FMU model with its associated properties and variables.

+
+
+__init__(model: ModelComponent) None
+

Initialize the FmiModel object with a ModelComponent object.

+
+
Parameters:
+

model (ModelComponent) – FMU component compliant with FMISlave

+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + +

__init__(model)

Initialize the FmiModel object with a ModelComponent object.

add_state_initialization_parameters(states)

Generate or modify FmuInputVariables for initialization of states.

add_variable_references(inputs, parameters, ...)

Assign variable references to inputs, parameters and outputs from user interface to the FMU model class.

format_fmi_variable(var)

Get an inclusive list of variables from an interface variable definition.

get_fmi_model_variables()

Get a full list of all variables in the FMU, including each index of vector ports.

get_template_mapping()

Calculate the index to value reference mapping between onnx inputs/outputs/state to fmu variables.

get_total_variable_number()

Calculate the total number of variables including every index of vector ports.

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

name

The name of the FMU model.

guid

The globally unique identifier of the FMU model.

inputs

The list of input variables for the FMU model.

outputs

The list of output variables for the FMU model.

parameters

The list of parameter variables for the FMU model.

author

The author of the FMU model.

description

The description of the FMU model.

copyright

The copyright information of the FMU model.

license

The license information of the FMU model.

state_initialization_reuse

Whether the FMU model reuses state initialization.

+
+
+
+add_state_initialization_parameters(states: list[InternalState]) None
+

Generate or modify FmuInputVariables for initialization of states.

+

Generates or modifies FmuInputVariables for initialization of states for the InternalState objects +that have set start_value and name or have set initialization_variable. +Any generated parameters are appended to self.parameters.

+
+
Parameters:
+

states (list[InternalState]) – List of states from JSON interface.

+
+
Raises:
+
    +
  • ValueError – If variables with same name are found. Variables must have a unique name.

  • +
  • ValueError – If no FMU variables were found for use for initialization.

  • +
  • ValueError – If a state has a state_value != None without having a name.

  • +
+
+
+
+ +
+
+add_variable_references(inputs: list[InputVariable], parameters: list[InputVariable], outputs: list[OutputVariable]) None
+

Assign variable references to inputs, parameters and outputs from user interface to the FMU model class.

+
+
Parameters:
+
    +
  • inputs (list[InputVariable]) – List of input variables from JSON interface.

  • +
  • parameters (list[InputVariable]) – List of model parameters from JSON interface.

  • +
  • outputs (list[OutputVariable]) – List of output variables from JSON interface.

  • +
+
+
+
+ +
+
+format_fmi_variable(var: FmiInputVariable | FmiOutputVariable) list[FmiVariable]
+

Get an inclusive list of variables from an interface variable definition.

+

Vectors are separated as N number of signals, being N the size of the array.

+
+
Parameters:
+

var (FmiInputVariable | FmiOutputVariable) – Interface variable definition with the variable references.

+
+
Returns:
+

A list of FMI formatted variables.

+
+
Return type:
+

list[FmiVariable]

+
+
+
+ +
+
+get_fmi_model_variables() list[FmiVariable]
+

Get a full list of all variables in the FMU, including each index of vector ports.

+
+
Returns:
+

List of all variables in the FMU.

+
+
Return type:
+

list[FmiVariable]

+
+
+
+ +
+
+get_template_mapping() tuple[list[tuple[int, int]], list[tuple[int, int]], list[tuple[int, int]]]
+

Calculate the index to value reference mapping between onnx inputs/outputs/state to fmu variables.

+
+
Returns:
+

Tuple of lists of mappings between onnx indexes to fmu variables. +(input_mapping, output_mapping, state_init_mapping)

+
+
Return type:
+

tuple[list[tuple[int, int]], list[tuple[int, int]], list[tuple[int, int]]]

+
+
+
+ +
+
+get_total_variable_number() int
+

Calculate the total number of variables including every index of vector ports.

+
+
Returns:
+

The total number of variables.

+
+
Return type:
+

int

+
+
+
+ +
+
+author: str | None
+

The author of the FMU model.

+
+ +
+
+copyright: str | None
+

The copyright information of the FMU model.

+
+ +
+
+description: str | None
+

The description of the FMU model.

+
+ +
+
+guid: UUID | None
+

The globally unique identifier of the FMU model.

+
+ +
+
+inputs: list[FmiInputVariable]
+

The list of input variables for the FMU model.

+
+ +
+
+license: str | None
+

The license information of the FMU model.

+
+ +
+
+name: str
+

The name of the FMU model.

+
+ +
+
+outputs: list[FmiOutputVariable]
+

The list of output variables for the FMU model.

+
+ +
+
+parameters: list[FmiInputVariable]
+

The list of parameter variables for the FMU model.

+
+ +
+
+state_initialization_reuse: bool
+

Whether the FMU model reuses state initialization.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.FmiOutputVariable.html b/_autosummary/mlfmu.types.fmu_component.FmiOutputVariable.html new file mode 100644 index 0000000..8d4c3f7 --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.FmiOutputVariable.html @@ -0,0 +1,553 @@ + + + + + + + + + FmiOutputVariable - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

FmiOutputVariable

+
+
+class mlfmu.types.fmu_component.FmiOutputVariable(*, name: str, type: ~mlfmu.types.fmu_component.FmiVariableType = FmiVariableType.REAL, description: str | None = None, variability: ~mlfmu.types.fmu_component.FmiVariability | None = None, startValue: float | str | bool | int | None = 0, isArray: bool = False, length: int | None = None, agentOutputIndexes: list[~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=True, to_upper=True, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^(\d+|\d+:\d+)$)]] = [], causality: ~mlfmu.types.fmu_component.FmiCausality, variableReferences: list[int])
+

Bases: OutputVariable

+

Data class representing an output variable in an FMI component.

+
+
+__init__(**kwargs: Any) None
+

Create an FMI output variable.

+
+
Parameters:
+
    +
  • causality (FmiCausality, optional) – Causality of the output variable., by default FmiCausality.OUTPUT

  • +
  • variable_references (list[int], optional) – List of variable references associated with the output variable., by default []

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(**kwargs)

Create an FMI output variable.

construct([_fields_set])

copy(*[, include, exclude, update, deep])

Returns a copy of the model.

dict(*[, include, exclude, by_alias, ...])

from_orm(obj)

json(*[, include, exclude, by_alias, ...])

model_construct([_fields_set])

Creates a new instance of the Model class with validated data.

model_copy(*[, update, deep])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#model_copy

model_dump(*[, mode, include, exclude, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump

model_dump_json(*[, indent, include, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump_json

model_json_schema([by_alias, ref_template, ...])

Generates a JSON schema for a model class.

model_parametrized_name(params)

Compute the class name for parametrizations of generic classes.

model_post_init(_BaseModel__context)

Override this method to perform additional initialization after __init__ and model_construct.

model_rebuild(*[, force, raise_errors, ...])

Try to rebuild the pydantic-core schema for the model.

model_validate(obj, *[, strict, ...])

Validate a pydantic model instance.

model_validate_json(json_data, *[, strict, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/json/#json-parsing

model_validate_strings(obj, *[, strict, context])

Validate the given object with string data against the Pydantic model.

parse_file(path, *[, content_type, ...])

parse_obj(obj)

parse_raw(b, *[, content_type, encoding, ...])

schema([by_alias, ref_template])

schema_json(*[, by_alias, ref_template])

update_forward_refs(**localns)

validate(value)

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

model_computed_fields

model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_extra

Get extra fields set during validation.

model_fields

model_fields_set

Returns the set of fields that have been explicitly set on this model instance.

causality

The causality of the output variable.

variable_references

The list of variable references associated with the output variable.

agent_output_indexes

Index or range of indices of agent outputs that will be linked to this output signal.

name

Unique name for the port.

type

Data type as defined by FMI standard.

description

Short FMU variable description.

variability

Signal variability as defined by FMI.

start_value

Initial value of the signal at time step 1.

is_array

When dealing with an array signal, it is essential to specify the LENGTH parameter.

length

Defines the number of entries in the signal if the signal is array.

+
+
+
+causality: FmiCausality
+

The causality of the output variable.

+
+ +
+
+model_config: ClassVar[ConfigDict] = {'alias_generator': <function to_camel>, 'populate_by_name': True}
+

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

+
+ +
+
+variable_references: list[int]
+

The list of variable references associated with the output variable.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.FmiVariability.html b/_autosummary/mlfmu.types.fmu_component.FmiVariability.html new file mode 100644 index 0000000..d397242 --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.FmiVariability.html @@ -0,0 +1,595 @@ + + + + + + + + + FmiVariability - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

FmiVariability

+
+
+class mlfmu.types.fmu_component.FmiVariability(value, names=_not_given, *values, module=None, qualname=None, type=None, start=1, boundary=None)
+

Bases: str, Enum

+

Enum for signal variability.

+
+
+__init__(*args, **kwds)
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

encode([encoding, errors])

Encode the string using the codec registered for encoding.

replace(old, new[, count])

Return a copy with all occurrences of substring old replaced by new.

split([sep, maxsplit])

Return a list of the substrings in the string, using sep as the separator string.

rsplit([sep, maxsplit])

Return a list of the substrings in the string, using sep as the separator string.

join(iterable, /)

Concatenate any number of strings.

capitalize()

Return a capitalized version of the string.

casefold()

Return a version of the string suitable for caseless comparisons.

title()

Return a version of the string where each word is titlecased.

center(width[, fillchar])

Return a centered string of length width.

count(sub[, start[, end]])

Return the number of non-overlapping occurrences of substring sub in string S[start:end].

expandtabs([tabsize])

Return a copy where all tab characters are expanded using spaces.

find(sub[, start[, end]])

Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].

partition(sep, /)

Partition the string into three parts using the given separator.

index(sub[, start[, end]])

Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].

ljust(width[, fillchar])

Return a left-justified string of length width.

lower()

Return a copy of the string converted to lowercase.

lstrip([chars])

Return a copy of the string with leading whitespace removed.

rfind(sub[, start[, end]])

Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].

rindex(sub[, start[, end]])

Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].

rjust(width[, fillchar])

Return a right-justified string of length width.

rstrip([chars])

Return a copy of the string with trailing whitespace removed.

rpartition(sep, /)

Partition the string into three parts using the given separator.

splitlines([keepends])

Return a list of the lines in the string, breaking at line boundaries.

strip([chars])

Return a copy of the string with leading and trailing whitespace removed.

swapcase()

Convert uppercase characters to lowercase and lowercase characters to uppercase.

translate(table, /)

Replace each character in the string using the given translation table.

upper()

Return a copy of the string converted to uppercase.

startswith(prefix[, start[, end]])

Return True if S starts with the specified prefix, False otherwise.

endswith(suffix[, start[, end]])

Return True if S ends with the specified suffix, False otherwise.

removeprefix(prefix, /)

Return a str with the given prefix string removed if present.

removesuffix(suffix, /)

Return a str with the given suffix string removed if present.

isascii()

Return True if all characters in the string are ASCII, False otherwise.

islower()

Return True if the string is a lowercase string, False otherwise.

isupper()

Return True if the string is an uppercase string, False otherwise.

istitle()

Return True if the string is a title-cased string, False otherwise.

isspace()

Return True if the string is a whitespace string, False otherwise.

isdecimal()

Return True if the string is a decimal string, False otherwise.

isdigit()

Return True if the string is a digit string, False otherwise.

isnumeric()

Return True if the string is a numeric string, False otherwise.

isalpha()

Return True if the string is an alphabetic string, False otherwise.

isalnum()

Return True if the string is an alpha-numeric string, False otherwise.

isidentifier()

Return True if the string is a valid Python identifier, False otherwise.

isprintable()

Return True if the string is printable, False otherwise.

zfill(width, /)

Pad a numeric string with zeros on the left, to fill a field of the given width.

format(*args, **kwargs)

Return a formatted version of S, using substitutions from args and kwargs.

format_map(mapping)

Return a formatted version of S, using substitutions from mapping.

maketrans

Return a translation table usable for str.translate().

__init__(*args, **kwds)

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + +

CONSTANT

FIXED

TUNABLE

DISCRETE

CONTINUOUS

+
+
+
+CONSTANT = 'constant'
+
+ +
+
+CONTINUOUS = 'continuous'
+
+ +
+
+DISCRETE = 'discrete'
+
+ +
+
+FIXED = 'fixed'
+
+ +
+
+TUNABLE = 'tunable'
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.FmiVariable.html b/_autosummary/mlfmu.types.fmu_component.FmiVariable.html new file mode 100644 index 0000000..55d8398 --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.FmiVariable.html @@ -0,0 +1,479 @@ + + + + + + + + + FmiVariable - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

FmiVariable

+
+
+class mlfmu.types.fmu_component.FmiVariable(name: str = '', variable_reference: int = 0, type: FmiVariableType = FmiVariableType.REAL, start_value: bool | str | int | float = 0, causality: FmiCausality = FmiCausality.INPUT, description: str = '', variability: FmiVariability = FmiVariability.CONTINUOUS)
+

Bases: object

+

Data class representing a variable in an FMU component.

+
+
+__init__(name: str = '', variable_reference: int = 0, type: FmiVariableType = FmiVariableType.REAL, start_value: bool | str | int | float = 0, causality: FmiCausality = FmiCausality.INPUT, description: str = '', variability: FmiVariability = FmiVariability.CONTINUOUS) None
+
+ +

Methods

+
+ + + + + + +

__init__([name, variable_reference, type, ...])

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + +

causality

The causality of the variable.

description

The description of the variable.

name

The name of the variable.

start_value

The initial value of the variable.

type

The type of the variable.

variability

The variability of the variable.

variable_reference

The reference ID of the variable.

+
+
+
+causality: FmiCausality = 'input'
+

The causality of the variable.

+
+ +
+
+description: str = ''
+

The description of the variable.

+
+ +
+
+name: str = ''
+

The name of the variable.

+
+ +
+
+start_value: bool | str | int | float = 0
+

The initial value of the variable.

+
+ +
+
+type: FmiVariableType = 'real'
+

The type of the variable.

+
+ +
+
+variability: FmiVariability = 'continuous'
+

The variability of the variable.

+
+ +
+
+variable_reference: int = 0
+

The reference ID of the variable.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.FmiVariableType.html b/_autosummary/mlfmu.types.fmu_component.FmiVariableType.html new file mode 100644 index 0000000..a1ce91b --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.FmiVariableType.html @@ -0,0 +1,586 @@ + + + + + + + + + FmiVariableType - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

FmiVariableType

+
+
+class mlfmu.types.fmu_component.FmiVariableType(value, names=_not_given, *values, module=None, qualname=None, type=None, start=1, boundary=None)
+

Bases: str, Enum

+

Enum for variable type.

+
+
+__init__(*args, **kwds)
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

encode([encoding, errors])

Encode the string using the codec registered for encoding.

replace(old, new[, count])

Return a copy with all occurrences of substring old replaced by new.

split([sep, maxsplit])

Return a list of the substrings in the string, using sep as the separator string.

rsplit([sep, maxsplit])

Return a list of the substrings in the string, using sep as the separator string.

join(iterable, /)

Concatenate any number of strings.

capitalize()

Return a capitalized version of the string.

casefold()

Return a version of the string suitable for caseless comparisons.

title()

Return a version of the string where each word is titlecased.

center(width[, fillchar])

Return a centered string of length width.

count(sub[, start[, end]])

Return the number of non-overlapping occurrences of substring sub in string S[start:end].

expandtabs([tabsize])

Return a copy where all tab characters are expanded using spaces.

find(sub[, start[, end]])

Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].

partition(sep, /)

Partition the string into three parts using the given separator.

index(sub[, start[, end]])

Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].

ljust(width[, fillchar])

Return a left-justified string of length width.

lower()

Return a copy of the string converted to lowercase.

lstrip([chars])

Return a copy of the string with leading whitespace removed.

rfind(sub[, start[, end]])

Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].

rindex(sub[, start[, end]])

Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].

rjust(width[, fillchar])

Return a right-justified string of length width.

rstrip([chars])

Return a copy of the string with trailing whitespace removed.

rpartition(sep, /)

Partition the string into three parts using the given separator.

splitlines([keepends])

Return a list of the lines in the string, breaking at line boundaries.

strip([chars])

Return a copy of the string with leading and trailing whitespace removed.

swapcase()

Convert uppercase characters to lowercase and lowercase characters to uppercase.

translate(table, /)

Replace each character in the string using the given translation table.

upper()

Return a copy of the string converted to uppercase.

startswith(prefix[, start[, end]])

Return True if S starts with the specified prefix, False otherwise.

endswith(suffix[, start[, end]])

Return True if S ends with the specified suffix, False otherwise.

removeprefix(prefix, /)

Return a str with the given prefix string removed if present.

removesuffix(suffix, /)

Return a str with the given suffix string removed if present.

isascii()

Return True if all characters in the string are ASCII, False otherwise.

islower()

Return True if the string is a lowercase string, False otherwise.

isupper()

Return True if the string is an uppercase string, False otherwise.

istitle()

Return True if the string is a title-cased string, False otherwise.

isspace()

Return True if the string is a whitespace string, False otherwise.

isdecimal()

Return True if the string is a decimal string, False otherwise.

isdigit()

Return True if the string is a digit string, False otherwise.

isnumeric()

Return True if the string is a numeric string, False otherwise.

isalpha()

Return True if the string is an alphabetic string, False otherwise.

isalnum()

Return True if the string is an alpha-numeric string, False otherwise.

isidentifier()

Return True if the string is a valid Python identifier, False otherwise.

isprintable()

Return True if the string is printable, False otherwise.

zfill(width, /)

Pad a numeric string with zeros on the left, to fill a field of the given width.

format(*args, **kwargs)

Return a formatted version of S, using substitutions from args and kwargs.

format_map(mapping)

Return a formatted version of S, using substitutions from mapping.

maketrans

Return a translation table usable for str.translate().

__init__(*args, **kwds)

+
+

Attributes

+
+ + + + + + + + + + + + + + + +

REAL

INTEGER

STRING

BOOLEAN

+
+
+
+BOOLEAN = 'boolean'
+
+ +
+
+INTEGER = 'integer'
+
+ +
+
+REAL = 'real'
+
+ +
+
+STRING = 'string'
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.InputVariable.html b/_autosummary/mlfmu.types.fmu_component.InputVariable.html new file mode 100644 index 0000000..37f099a --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.InputVariable.html @@ -0,0 +1,539 @@ + + + + + + + + + InputVariable - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

InputVariable

+
+
+class mlfmu.types.fmu_component.InputVariable(*, name: str, type: ~mlfmu.types.fmu_component.FmiVariableType = FmiVariableType.REAL, description: str | None = None, variability: ~mlfmu.types.fmu_component.FmiVariability | None = None, startValue: float | str | bool | int | None = 0, isArray: bool = False, length: int | None = None, agentInputIndexes: list[~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=True, to_upper=True, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^(\d+|\d+:\d+)$)]] = [])
+

Bases: Variable

+

Represents an input variable for an FMU component.

+

Examples

+

An example of agent_input_indexes can be [“10”, “10:20”, “30”].

+
+
+__init__(**data: Any) None
+

Create a new model by parsing and validating input data from keyword arguments.

+

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be +validated to form a valid model.

+

self is explicitly positional-only to allow self as a field name.

+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(**data)

Create a new model by parsing and validating input data from keyword arguments.

construct([_fields_set])

copy(*[, include, exclude, update, deep])

Returns a copy of the model.

dict(*[, include, exclude, by_alias, ...])

from_orm(obj)

json(*[, include, exclude, by_alias, ...])

model_construct([_fields_set])

Creates a new instance of the Model class with validated data.

model_copy(*[, update, deep])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#model_copy

model_dump(*[, mode, include, exclude, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump

model_dump_json(*[, indent, include, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump_json

model_json_schema([by_alias, ref_template, ...])

Generates a JSON schema for a model class.

model_parametrized_name(params)

Compute the class name for parametrizations of generic classes.

model_post_init(_BaseModel__context)

Override this method to perform additional initialization after __init__ and model_construct.

model_rebuild(*[, force, raise_errors, ...])

Try to rebuild the pydantic-core schema for the model.

model_validate(obj, *[, strict, ...])

Validate a pydantic model instance.

model_validate_json(json_data, *[, strict, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/json/#json-parsing

model_validate_strings(obj, *[, strict, context])

Validate the given object with string data against the Pydantic model.

parse_file(path, *[, content_type, ...])

parse_obj(obj)

parse_raw(b, *[, content_type, encoding, ...])

schema([by_alias, ref_template])

schema_json(*[, by_alias, ref_template])

update_forward_refs(**localns)

validate(value)

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

model_computed_fields

model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_extra

Get extra fields set during validation.

model_fields

model_fields_set

Returns the set of fields that have been explicitly set on this model instance.

agent_input_indexes

Index or range of indices of ONNX (agent) inputs to which this FMU signal shall be linked to.

name

Unique name for the port.

type

Data type as defined by FMI standard.

description

Short FMU variable description.

variability

Signal variability as defined by FMI.

start_value

Initial value of the signal at time step 1.

is_array

When dealing with an array signal, it is essential to specify the LENGTH parameter.

length

Defines the number of entries in the signal if the signal is array.

+
+
+
+agent_input_indexes: list[Annotated[str, StringConstraints(strip_whitespace=True, to_upper=True, pattern='^(\\d+|\\d+:\\d+)$')]]
+

Index or range of indices of ONNX (agent) inputs to which this FMU signal shall be linked to. +Note: The FMU signal and the ONNX (agent) inputs need to have the same length. +Defaults to an empty list.

+
+ +
+
+model_config: ClassVar[ConfigDict] = {'alias_generator': <function to_camel>, 'populate_by_name': True}
+

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.InternalState.html b/_autosummary/mlfmu.types.fmu_component.InternalState.html new file mode 100644 index 0000000..648e605 --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.InternalState.html @@ -0,0 +1,589 @@ + + + + + + + + + InternalState - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

InternalState

+
+
+class mlfmu.types.fmu_component.InternalState(*, name: str | None = None, description: str | None = None, startValue: float | None = None, initializationVariable: str | None = None, agentOutputIndexes: list[~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=True, to_upper=True, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^(\d+|\d+:\d+)$)]] = [])
+

Bases: BaseModelConfig

+

Pydantic model representing an internal state of an FMU component.

+
+
+__init__(**data: Any) None
+

Create a new model by parsing and validating input data from keyword arguments.

+

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be +validated to form a valid model.

+

self is explicitly positional-only to allow self as a field name.

+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(**data)

Create a new model by parsing and validating input data from keyword arguments.

check_only_one_initialization()

Check if only one state initialization method is used at a time.

construct([_fields_set])

copy(*[, include, exclude, update, deep])

Returns a copy of the model.

dict(*[, include, exclude, by_alias, ...])

from_orm(obj)

json(*[, include, exclude, by_alias, ...])

model_construct([_fields_set])

Creates a new instance of the Model class with validated data.

model_copy(*[, update, deep])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#model_copy

model_dump(*[, mode, include, exclude, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump

model_dump_json(*[, indent, include, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump_json

model_json_schema([by_alias, ref_template, ...])

Generates a JSON schema for a model class.

model_parametrized_name(params)

Compute the class name for parametrizations of generic classes.

model_post_init(_BaseModel__context)

Override this method to perform additional initialization after __init__ and model_construct.

model_rebuild(*[, force, raise_errors, ...])

Try to rebuild the pydantic-core schema for the model.

model_validate(obj, *[, strict, ...])

Validate a pydantic model instance.

model_validate_json(json_data, *[, strict, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/json/#json-parsing

model_validate_strings(obj, *[, strict, context])

Validate the given object with string data against the Pydantic model.

parse_file(path, *[, content_type, ...])

parse_obj(obj)

parse_raw(b, *[, content_type, encoding, ...])

schema([by_alias, ref_template])

schema_json(*[, by_alias, ref_template])

update_forward_refs(**localns)

validate(value)

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

model_computed_fields

model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_extra

Get extra fields set during validation.

model_fields

model_fields_set

Returns the set of fields that have been explicitly set on this model instance.

name

Unique name for the state.

description

Short description of the FMU variable.

start_value

The default value of the parameter used for initialization.

initialization_variable

The name of an input or parameter in the same model interface that should be used to initialize this state.

agent_output_indexes

Index or range of indices of agent (ONNX model) outputs that will be stored as internal states and will be fed as inputs in the next time step.

+
+
+
+check_only_one_initialization() InternalState
+

Check if only one state initialization method is used at a time.

+

Raises a ValueError if multiple state initialization methods are used simultaneously.

+
+
Returns:
+

self

+
+
Return type:
+

The FMU component instance.

+
+
Raises:
+
    +
  • ValueError – If initialization_variable is set and either start_value or name is also set.:

  • +
  • ValueError – If name is set without start_value being set.:

  • +
  • ValueError – If start_value is set without name being set.:

  • +
+
+
+
+ +
+
+agent_output_indexes: list[Annotated[str, StringConstraints(strip_whitespace=True, to_upper=True, pattern='^(\\d+|\\d+:\\d+)$')]]
+

Index or range of indices of agent (ONNX model) outputs that will be stored as internal states +and will be fed as inputs in the next time step. +Note: the FMU signal and the ONNX (agent) outputs need to have the same length. +Defaults to an empty list.

+
+ +
+
+description: str | None
+

Short description of the FMU variable. +Optional.

+
+ +
+
+initialization_variable: str | None
+

The name of an input or parameter in the same model interface that should be used to initialize this state. +Optional.

+
+ +
+
+model_config: ClassVar[ConfigDict] = {'alias_generator': <function to_camel>, 'populate_by_name': True}
+

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

+
+ +
+
+name: str | None
+

Unique name for the state. Only needed if start_value is set (!= None). +Initialization FMU parameters will be generated using this name. +Optional.

+
+ +
+
+start_value: float | None
+

The default value of the parameter used for initialization. +If this field is set, parameters for initialization will be automatically generated for these states. +Optional.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.ModelComponent.html b/_autosummary/mlfmu.types.fmu_component.ModelComponent.html new file mode 100644 index 0000000..25d62c8 --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.ModelComponent.html @@ -0,0 +1,642 @@ + + + + + + + + + ModelComponent - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

ModelComponent

+
+
+class mlfmu.types.fmu_component.ModelComponent(*, name: str, version: str = '0.0.1', author: str | None = None, description: str | None = '', copyright: str | None = None, license: str | None = None, inputs: list[InputVariable] = [], outputs: list[OutputVariable] = [], parameters: list[InputVariable] = [], states: list[InternalState] = [], usesTime: bool | None = False, stateInitializationReuse: bool = False)
+

Bases: BaseModelConfig

+

Pydantic model representing a simulation model component.

+

Used to generate the JSON schema for the model interface. +Defines the structure of the FMU and how the inputs and outputs of the ONNX model +correspond to the FMU variables.

+
+
+__init__(**data: Any) None
+

Create a new model by parsing and validating input data from keyword arguments.

+

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be +validated to form a valid model.

+

self is explicitly positional-only to allow self as a field name.

+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(**data)

Create a new model by parsing and validating input data from keyword arguments.

construct([_fields_set])

copy(*[, include, exclude, update, deep])

Returns a copy of the model.

dict(*[, include, exclude, by_alias, ...])

from_orm(obj)

json(*[, include, exclude, by_alias, ...])

model_construct([_fields_set])

Creates a new instance of the Model class with validated data.

model_copy(*[, update, deep])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#model_copy

model_dump(*[, mode, include, exclude, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump

model_dump_json(*[, indent, include, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump_json

model_json_schema([by_alias, ref_template, ...])

Generates a JSON schema for a model class.

model_parametrized_name(params)

Compute the class name for parametrizations of generic classes.

model_post_init(_BaseModel__context)

Override this method to perform additional initialization after __init__ and model_construct.

model_rebuild(*[, force, raise_errors, ...])

Try to rebuild the pydantic-core schema for the model.

model_validate(obj, *[, strict, ...])

Validate a pydantic model instance.

model_validate_json(json_data, *[, strict, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/json/#json-parsing

model_validate_strings(obj, *[, strict, context])

Validate the given object with string data against the Pydantic model.

parse_file(path, *[, content_type, ...])

parse_obj(obj)

parse_raw(b, *[, content_type, encoding, ...])

schema([by_alias, ref_template])

schema_json(*[, by_alias, ref_template])

update_forward_refs(**localns)

validate(value)

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

model_computed_fields

model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_extra

Get extra fields set during validation.

model_fields

model_fields_set

Returns the set of fields that have been explicitly set on this model instance.

name

The name of the simulation model.

version

The version number of the model.

author

Name or email of the model's author.

description

Short description of the model.

copyright

Copyright line for use in full license text.

license

License text or file name (relative to source files).

inputs

List of input signals of the simulation model.

outputs

List of output signals of the simulation model.

parameters

List of parameter signals of the simulation model.

states

Internal states that will be stored in the simulation model's memory, these will be passed as inputs to the agent in the next time step.

uses_time

Whether the agent consumes time data from co-simulation algorithm.

state_initialization_reuse

Whether variables are allowed to be reused for state initialization when initialization_variable is used for state initialization.

+
+
+
+author: str | None
+

Name or email of the model’s author. +Optional.

+
+ +
+
+copyright: str | None
+

Copyright line for use in full license text. +Optional.

+
+ +
+
+description: str | None
+

Short description of the model. +Defaults to an empty string.

+
+ +
+
+inputs: list[InputVariable]
+

List of input signals of the simulation model. +Defaults to an empty list.

+
+ +
+
+license: str | None
+

License text or file name (relative to source files). +Optional.

+
+ +
+
+model_config: ClassVar[ConfigDict] = {'alias_generator': <function to_camel>, 'populate_by_name': True}
+

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

+
+ +
+
+name: str
+

The name of the simulation model.

+
+ +
+
+outputs: list[OutputVariable]
+

List of output signals of the simulation model. +Defaults to an empty list.

+
+ +
+
+parameters: list[InputVariable]
+

List of parameter signals of the simulation model. +Defaults to an empty list.

+
+ +
+
+state_initialization_reuse: bool
+

Whether variables are allowed to be reused for state initialization when +initialization_variable is used for state initialization. +If set to true the variable referred to in initialization_variable will be repeated +for the state initialization until the entire state is initialized. +Defaults to False.

+
+ +
+
+states: list[InternalState]
+

Internal states that will be stored in the simulation model’s memory, +these will be passed as inputs to the agent in the next time step. +Defaults to an empty list.

+
+ +
+
+uses_time: bool | None
+

Whether the agent consumes time data from co-simulation algorithm. +Defaults to False.

+
+ +
+
+version: str
+

The version number of the model. +Defaults to “0.0.1”.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.OutputVariable.html b/_autosummary/mlfmu.types.fmu_component.OutputVariable.html new file mode 100644 index 0000000..38cce7b --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.OutputVariable.html @@ -0,0 +1,539 @@ + + + + + + + + + OutputVariable - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

OutputVariable

+
+
+class mlfmu.types.fmu_component.OutputVariable(*, name: str, type: ~mlfmu.types.fmu_component.FmiVariableType = FmiVariableType.REAL, description: str | None = None, variability: ~mlfmu.types.fmu_component.FmiVariability | None = None, startValue: float | str | bool | int | None = 0, isArray: bool = False, length: int | None = None, agentOutputIndexes: list[~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=True, to_upper=True, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^(\d+|\d+:\d+)$)]] = [])
+

Bases: Variable

+

Represents an output variable in the FMU component.

+

Examples

+

An example of agent_output_indexes can be [“10”, “10:20”, “30”].

+
+
+__init__(**data: Any) None
+

Create a new model by parsing and validating input data from keyword arguments.

+

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be +validated to form a valid model.

+

self is explicitly positional-only to allow self as a field name.

+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(**data)

Create a new model by parsing and validating input data from keyword arguments.

construct([_fields_set])

copy(*[, include, exclude, update, deep])

Returns a copy of the model.

dict(*[, include, exclude, by_alias, ...])

from_orm(obj)

json(*[, include, exclude, by_alias, ...])

model_construct([_fields_set])

Creates a new instance of the Model class with validated data.

model_copy(*[, update, deep])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#model_copy

model_dump(*[, mode, include, exclude, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump

model_dump_json(*[, indent, include, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump_json

model_json_schema([by_alias, ref_template, ...])

Generates a JSON schema for a model class.

model_parametrized_name(params)

Compute the class name for parametrizations of generic classes.

model_post_init(_BaseModel__context)

Override this method to perform additional initialization after __init__ and model_construct.

model_rebuild(*[, force, raise_errors, ...])

Try to rebuild the pydantic-core schema for the model.

model_validate(obj, *[, strict, ...])

Validate a pydantic model instance.

model_validate_json(json_data, *[, strict, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/json/#json-parsing

model_validate_strings(obj, *[, strict, context])

Validate the given object with string data against the Pydantic model.

parse_file(path, *[, content_type, ...])

parse_obj(obj)

parse_raw(b, *[, content_type, encoding, ...])

schema([by_alias, ref_template])

schema_json(*[, by_alias, ref_template])

update_forward_refs(**localns)

validate(value)

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

model_computed_fields

model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_extra

Get extra fields set during validation.

model_fields

model_fields_set

Returns the set of fields that have been explicitly set on this model instance.

agent_output_indexes

Index or range of indices of agent outputs that will be linked to this output signal.

name

Unique name for the port.

type

Data type as defined by FMI standard.

description

Short FMU variable description.

variability

Signal variability as defined by FMI.

start_value

Initial value of the signal at time step 1.

is_array

When dealing with an array signal, it is essential to specify the LENGTH parameter.

length

Defines the number of entries in the signal if the signal is array.

+
+
+
+agent_output_indexes: list[Annotated[str, StringConstraints(strip_whitespace=True, to_upper=True, pattern='^(\\d+|\\d+:\\d+)$')]]
+

Index or range of indices of agent outputs that will be linked to this output signal. +Note: The FMU signal and the agent outputs need to have the same length. +Defaults to an empty list.

+
+ +
+
+model_config: ClassVar[ConfigDict] = {'alias_generator': <function to_camel>, 'populate_by_name': True}
+

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.Variable.html b/_autosummary/mlfmu.types.fmu_component.Variable.html new file mode 100644 index 0000000..096e6c1 --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.Variable.html @@ -0,0 +1,583 @@ + + + + + + + + + Variable - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Variable

+
+
+class mlfmu.types.fmu_component.Variable(*, name: str, type: FmiVariableType = FmiVariableType.REAL, description: str | None = None, variability: FmiVariability | None = None, startValue: float | str | bool | int | None = 0, isArray: bool = False, length: int | None = None)
+

Bases: BaseModelConfig

+

Pydantic model representing a variable in an FMU component.

+
+
+__init__(**data: Any) None
+

Create a new model by parsing and validating input data from keyword arguments.

+

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be +validated to form a valid model.

+

self is explicitly positional-only to allow self as a field name.

+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(**data)

Create a new model by parsing and validating input data from keyword arguments.

construct([_fields_set])

copy(*[, include, exclude, update, deep])

Returns a copy of the model.

dict(*[, include, exclude, by_alias, ...])

from_orm(obj)

json(*[, include, exclude, by_alias, ...])

model_construct([_fields_set])

Creates a new instance of the Model class with validated data.

model_copy(*[, update, deep])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#model_copy

model_dump(*[, mode, include, exclude, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump

model_dump_json(*[, indent, include, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/serialization/#modelmodel_dump_json

model_json_schema([by_alias, ref_template, ...])

Generates a JSON schema for a model class.

model_parametrized_name(params)

Compute the class name for parametrizations of generic classes.

model_post_init(_BaseModel__context)

Override this method to perform additional initialization after __init__ and model_construct.

model_rebuild(*[, force, raise_errors, ...])

Try to rebuild the pydantic-core schema for the model.

model_validate(obj, *[, strict, ...])

Validate a pydantic model instance.

model_validate_json(json_data, *[, strict, ...])

Usage docs: https://docs.pydantic.dev/2.10/concepts/json/#json-parsing

model_validate_strings(obj, *[, strict, context])

Validate the given object with string data against the Pydantic model.

parse_file(path, *[, content_type, ...])

parse_obj(obj)

parse_raw(b, *[, content_type, encoding, ...])

schema([by_alias, ref_template])

schema_json(*[, by_alias, ref_template])

update_forward_refs(**localns)

validate(value)

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

model_computed_fields

model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_extra

Get extra fields set during validation.

model_fields

model_fields_set

Returns the set of fields that have been explicitly set on this model instance.

name

Unique name for the port.

type

Data type as defined by FMI standard.

description

Short FMU variable description.

variability

Signal variability as defined by FMI.

start_value

Initial value of the signal at time step 1.

is_array

When dealing with an array signal, it is essential to specify the LENGTH parameter.

length

Defines the number of entries in the signal if the signal is array.

+
+
+
+description: str | None
+

Short FMU variable description. +Optional.

+
+ +
+
+is_array: bool
+

When dealing with an array signal, it is essential to specify the LENGTH parameter. +Arrays are indexed starting from 0, and FMU signals will be structured as +SIGNAL_NAME[0], SIGNAL_NAME[1], and so forth. +Defaults to False.

+
+ +
+
+length: int | None
+

Defines the number of entries in the signal if the signal is array. +Optional.

+
+ +
+
+model_config: ClassVar[ConfigDict] = {'alias_generator': <function to_camel>, 'populate_by_name': True}
+

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

+
+ +
+
+name: str
+

Unique name for the port.

+
+ +
+
+start_value: float | str | bool | int | None
+

Initial value of the signal at time step 1. +Type should match the variable type. +Defaults to 0.

+
+ +
+
+type: FmiVariableType
+

Data type as defined by FMI standard. +Defaults to Real.

+
+ +
+
+variability: FmiVariability | None
+

Signal variability as defined by FMI. +Optional.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.fmu_component.html b/_autosummary/mlfmu.types.fmu_component.html new file mode 100644 index 0000000..70b3283 --- /dev/null +++ b/_autosummary/mlfmu.types.fmu_component.html @@ -0,0 +1,404 @@ + + + + + + + + + mlfmu.types.fmu_component - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.types.fmu_component

+

Classes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

BaseModelConfig()

Enables the alias_generator for all cases.

FmiCausality(value[, names, module, ...])

Enum for variable causality.

FmiInputVariable(*, name, type, description, ...)

Data class representing an input variable in an FMI component.

FmiModel(model)

Represents an FMU model with its associated properties and variables.

FmiOutputVariable(*, name, type, ...)

Data class representing an output variable in an FMI component.

FmiVariability(value[, names, module, ...])

Enum for signal variability.

FmiVariable([name, variable_reference, ...])

Data class representing a variable in an FMU component.

FmiVariableType(value[, names, module, ...])

Enum for variable type.

InputVariable(*, name, type, description, ...)

Represents an input variable for an FMU component.

InternalState(*, name, description, ...)

Pydantic model representing an internal state of an FMU component.

ModelComponent(*, name[, version, author, ...])

Pydantic model representing a simulation model component.

OutputVariable(*, name, type, description, ...)

Represents an output variable in the FMU component.

Variable(*, name[, type, description, ...])

Pydantic model representing a variable in an FMU component.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.html b/_autosummary/mlfmu.types.html new file mode 100644 index 0000000..38d77d6 --- /dev/null +++ b/_autosummary/mlfmu.types.html @@ -0,0 +1,371 @@ + + + + + + + + + mlfmu.types - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.onnx_model.ONNXModel.html b/_autosummary/mlfmu.types.onnx_model.ONNXModel.html new file mode 100644 index 0000000..9befa81 --- /dev/null +++ b/_autosummary/mlfmu.types.onnx_model.ONNXModel.html @@ -0,0 +1,539 @@ + + + + + + + + + ONNXModel - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

ONNXModel

+
+
+class mlfmu.types.onnx_model.ONNXModel(onnx_path: str | PathLike[str], *, time_input: bool = False)
+

Bases: object

+

ONNX Metadata class.

+

Represents an ONNX model and provides methods to load inputs and outputs. +Allows to import the ONNX file and figure out the input/output sizes.

+
+
Raises:
+
    +
  • ValueError – If the ml model has 3 inputs, but the usesTime flag is set to false in the json interface.

  • +
  • ValueError – If the number of inputs to the ml model is larger than 3.

  • +
  • ValueError – If the number of outputs from the ml model is not exactly 1.

  • +
+
+
+
+
+__init__(onnx_path: str | PathLike[str], *, time_input: bool = False) None
+

Initialize the ONNXModel object by loading the ONNX file and assigning model parameters.

+
+
Parameters:
+
    +
  • onnx_path (Union[str, os.PathLike[str]]) – The path to the ONNX file.

  • +
  • time_input (bool, optional) – Flag indicating whether the model uses time input. Defaults to False.

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + +

__init__(onnx_path, *[, time_input])

Initialize the ONNXModel object by loading the ONNX file and assigning model parameters.

load_inputs()

Load the inputs from the ONNX file and assign the input name and size.

load_outputs()

Load the outputs from the ONNX file and assign the output name and size.

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

filename

The name of the ONNX file.

input_name

The name of the main input.

input_size

The size of the main input.

output_name

The name of the output.

output_size

The size of the output.

state_size

The size of the internal states input.

states_name

The name of the internal states input.

time_input

Flag indicating whether the model uses time input.

time_input_name

The name of the time input.

+
+
+
+load_inputs() None
+

Load the inputs from the ONNX file and assign the input name and size.

+
+ +
+
+load_outputs() None
+

Load the outputs from the ONNX file and assign the output name and size.

+
+ +
+
+filename: str = ''
+

The name of the ONNX file.

+
+ +
+
+input_name: str = ''
+

The name of the main input.

+
+ +
+
+input_size: int = 0
+

The size of the main input.

+
+ +
+
+output_name: str = ''
+

The name of the output.

+
+ +
+
+output_size: int = 0
+

The size of the output.

+
+ +
+
+state_size: int = 0
+

The size of the internal states input.

+
+ +
+
+states_name: str = ''
+

The name of the internal states input.

+
+ +
+
+time_input: bool = False
+

Flag indicating whether the model uses time input.

+
+ +
+
+time_input_name: str = ''
+

The name of the time input.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.types.onnx_model.html b/_autosummary/mlfmu.types.onnx_model.html new file mode 100644 index 0000000..0ac0c72 --- /dev/null +++ b/_autosummary/mlfmu.types.onnx_model.html @@ -0,0 +1,368 @@ + + + + + + + + + mlfmu.types.onnx_model - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.types.onnx_model

+

Classes

+
+ + + + + + +

ONNXModel(onnx_path, *[, time_input])

ONNX Metadata class.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.utils.builder.html b/_autosummary/mlfmu.utils.builder.html new file mode 100644 index 0000000..f65e6c6 --- /dev/null +++ b/_autosummary/mlfmu.utils.builder.html @@ -0,0 +1,567 @@ + + + + + + + + + mlfmu.utils.builder - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.utils.builder

+

Functions

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

build_fmu(fmu_src_path, fmu_build_path, ...)

Build the FMU.

create_files_from_templates(data, fmu_src)

Create and format all needed C++ files for FMU generation.

create_model_description(fmu, src_path)

Generate modelDescription.xml structure for FMU, and save it in a file.

format_template_data(onnx, fmi_model, ...)

Generate the key-value pairs needed to format the template files to valid C++.

format_template_file(template_path, ...)

Replace all the template strings with their corresponding values and save to a new file.

generate_fmu_files(fmu_src_path, onnx_path, ...)

Generate FMU files based on the FMU source, ONNX model, and interface specification.

make_fmu_dirs(src_path)

Create all the directories needed to put all the FMU files in.

validate_fmu_source_files(fmu_path)

Validate the FMU source files.

validate_interface_spec(spec)

Parse and validate JSON data from the interface file.

+
+
+
+mlfmu.utils.builder.build_fmu(fmu_src_path: PathLike[str], fmu_build_path: PathLike[str], fmu_save_path: PathLike[str]) None
+

Build the FMU.

+
+
Parameters:
+
    +
  • (os.PathLike[str]) (fmu_save_path)

  • +
  • (os.PathLike[str])

  • +
  • (os.PathLike[str])

  • +
+
+
Raises:
+

FileNotFoundError – If required files are missing in the FMU source directory.:

+
+
+
+ +
+
+mlfmu.utils.builder.create_files_from_templates(data: dict[str, str], fmu_src: Path) None
+

Create and format all needed C++ files for FMU generation.

+
+
Parameters:
+
    +
  • (dict[str (data)

  • +
  • str]) (The data containing the values to format the template files.)

  • +
  • (Path) (fmu_src)

  • +
+
+
+
+ +
+
+mlfmu.utils.builder.create_model_description(fmu: FmiModel, src_path: Path) None
+

Generate modelDescription.xml structure for FMU, and save it in a file.

+
+
Parameters:
+
    +
  • (FmiModel) (fmu)

  • +
  • (Path) (src_path)

  • +
+
+
+
+ +
+
+mlfmu.utils.builder.format_template_data(onnx: ONNXModel, fmi_model: FmiModel, model_component: ModelComponent) dict[str, str]
+

Generate the key-value pairs needed to format the template files to valid C++.

+
+
Parameters:
+
    +
  • (ONNXModel) (onnx)

  • +
  • (FmiModel) (fmi_model)

  • +
  • (ModelComponent) (model_component)

  • +
+
+
Returns:
+

dict[str, str]

+
+
Return type:
+

The formatted template data.

+
+
+
+ +
+
+mlfmu.utils.builder.format_template_file(template_path: Path, save_path: Path, data: dict[str, str]) None
+

Replace all the template strings with their corresponding values and save to a new file.

+
+
Parameters:
+
    +
  • (Path) (save_path)

  • +
  • (Path)

  • +
  • (dict[str (data)

  • +
  • str]) (The data containing the values to replace in the template.)

  • +
+
+
+
+ +
+
+mlfmu.utils.builder.generate_fmu_files(fmu_src_path: PathLike[str], onnx_path: PathLike[str], interface_spec_path: PathLike[str]) FmiModel
+

Generate FMU files based on the FMU source, ONNX model, and interface specification.

+
+
Parameters:
+
    +
  • (os.PathLike[str]) (interface_spec_path)

  • +
  • (os.PathLike[str])

  • +
  • (os.PathLike[str])

  • +
+
+
Returns:
+

FmiModel

+
+
Return type:
+

The FMI model.

+
+
+
+ +
+
+mlfmu.utils.builder.make_fmu_dirs(src_path: Path) None
+

Create all the directories needed to put all the FMU files in.

+
+
Parameters:
+

(Path) (src_path)

+
+
+
+ +
+
+mlfmu.utils.builder.validate_fmu_source_files(fmu_path: PathLike[str]) None
+

Validate the FMU source files.

+
+
Parameters:
+

(os.PathLike[str]) (fmu_path)

+
+
Raises:
+

FileNotFoundError – If required files are missing in the FMU source directory.:

+
+
+
+ +
+
+mlfmu.utils.builder.validate_interface_spec(spec: str) tuple[ValidationError | None, ModelComponent]
+

Parse and validate JSON data from the interface file.

+
+
Parameters:
+

(str) (spec)

+
+
Returns:
+

The validation error (if any) and the validated model component. +The pydantic model instance that contains all the interface information.

+
+
Return type:
+

tuple[Optional[ValidationError], ModelComponent]

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.utils.fmi_builder.html b/_autosummary/mlfmu.utils.fmi_builder.html new file mode 100644 index 0000000..0ffb09f --- /dev/null +++ b/_autosummary/mlfmu.utils.fmi_builder.html @@ -0,0 +1,419 @@ + + + + + + + + + mlfmu.utils.fmi_builder - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.utils.fmi_builder

+

Functions

+
+ + + + + + + + + +

generate_model_description(fmu_model)

Generate FMU modelDescription as XML.

requires_start(var)

Test if a variable requires a start attribute.

+
+
+
+mlfmu.utils.fmi_builder.generate_model_description(fmu_model: FmiModel) ElementTree
+

Generate FMU modelDescription as XML.

+
+
Parameters:
+

(FmiModel) (fmu_model)

+
+
Returns:
+

xml.etree.TreeElement.Element

+
+
Return type:
+

modelDescription XML representation.

+
+
+
+ +
+
+mlfmu.utils.fmi_builder.requires_start(var: FmiVariable) bool
+

Test if a variable requires a start attribute.

+
+
Return type:
+

True if successful, False otherwise

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.utils.html b/_autosummary/mlfmu.utils.html new file mode 100644 index 0000000..219bbf4 --- /dev/null +++ b/_autosummary/mlfmu.utils.html @@ -0,0 +1,387 @@ + + + + + + + + + mlfmu.utils - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.utils.interface.html b/_autosummary/mlfmu.utils.interface.html new file mode 100644 index 0000000..fb871cc --- /dev/null +++ b/_autosummary/mlfmu.utils.interface.html @@ -0,0 +1,442 @@ + + + + + + + + + mlfmu.utils.interface - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.utils.interface

+

Functions

+
+ + + + + + + + + + + + +

generate_interface_docs([schema_dir, docs_dir])

Generate HTML documentation for the JSON interface schema files in the schema directory.

generate_interface_schema(model[, schema_dir])

Generate a JSON interface schema file for the given model.

publish_interface_schema([schema_dir, docs_dir])

Publish the JSON schema and HTML documentation for the interface.

+
+
+
+mlfmu.utils.interface.generate_interface_docs(schema_dir: str | PathLike[str] | None = None, docs_dir: str | PathLike[str] | None = None) None
+

Generate HTML documentation for the JSON interface schema files in the schema directory.

+
+
Parameters:
+
    +
  • os.PathLike[str] (docs_dir (str |) – The directory where the schema files are located. Defaults to None.

  • +
  • optional) – The directory where the schema files are located. Defaults to None.

  • +
  • os.PathLike[str] – The directory where the documentation files will be saved. Defaults to None.

  • +
  • optional) – The directory where the documentation files will be saved. Defaults to None.

  • +
+
+
+
+ +
+
+mlfmu.utils.interface.generate_interface_schema(model: BaseModel | ModelMetaclass, schema_dir: str | PathLike[str] | None = None) None
+

Generate a JSON interface schema file for the given model.

+
+
Parameters:
+
    +
  • ModelMetaclass) (model (BaseModel |)

  • +
  • os.PathLike[str] (schema_dir (str |) – The directory where the schema file will be saved. Defaults to None.

  • +
  • optional) – The directory where the schema file will be saved. Defaults to None.

  • +
+
+
+
+ +
+
+mlfmu.utils.interface.publish_interface_schema(schema_dir: str | PathLike[str] | None = None, docs_dir: str | PathLike[str] | None = None) None
+

Publish the JSON schema and HTML documentation for the interface.

+
+
Parameters:
+
    +
  • os.PathLike[str] (docs_dir (str |) – The directory where the schema file will be saved. Defaults to None.

  • +
  • optional) – The directory where the schema file will be saved. Defaults to None.

  • +
  • os.PathLike[str] – The directory where the documentation files will be saved. Defaults to None.

  • +
  • optional) – The directory where the documentation files will be saved. Defaults to None.

  • +
+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.utils.logging.html b/_autosummary/mlfmu.utils.logging.html new file mode 100644 index 0000000..719f97a --- /dev/null +++ b/_autosummary/mlfmu.utils.logging.html @@ -0,0 +1,409 @@ + + + + + + + + + mlfmu.utils.logging - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.utils.logging

+

Functions to configure logging for the application.

+

Functions

+
+ + + + + + +

configure_logging([log_level_console, ...])

Configure logging for the application, allowing for both console and file logging.

+
+
+
+mlfmu.utils.logging.configure_logging(log_level_console: str = 'WARNING', log_file: Path | None = None, log_level_file: str = 'WARNING') None
+

Configure logging for the application, allowing for both console and file logging.

+

Sets the log levels and formats for the output, ensuring that logs are captured as specified.

+
+
Parameters:
+
    +
  • log_level_console (str) – The logging level for console output. Defaults to “WARNING”.

  • +
  • log_file (Path | None) – The path to the log file. If None, file logging is disabled. Defaults to None.

  • +
  • log_level_file (str) – The logging level for file output. Defaults to “WARNING”.

  • +
+
+
Raises:
+

TypeError – If the provided log levels are invalid.:

+
+
+

Examples

+

configure_logging(log_level_console=”INFO”, log_file=Path(“app.log”), log_level_file=”DEBUG”)

+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.utils.path.html b/_autosummary/mlfmu.utils.path.html new file mode 100644 index 0000000..478e213 --- /dev/null +++ b/_autosummary/mlfmu.utils.path.html @@ -0,0 +1,411 @@ + + + + + + + + + mlfmu.utils.path - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.utils.path

+

Functions

+
+ + + + + + +

find_default_file(folder, file_extension[, ...])

Return a file inside folder with the file extension that matches file_extension.

+
+
+
+mlfmu.utils.path.find_default_file(folder: Path, file_extension: str, default_name: str | None = None) Path | None
+

Return a file inside folder with the file extension that matches file_extension.

+

If there are multiple matches it uses the closest match to default_name if given. +Return None if there is no clear match.

+
+
Parameters:
+
    +
  • folder (Path) – the folder to search in

  • +
  • file_extension (str) – file extension to search for

  • +
  • default_name (str | None, optional) – file name used to determine “closest match” +in case multiple files match file_extension, by default None

  • +
+
+
Returns:
+

the path to the file if it is found, otherwise None

+
+
Return type:
+

Path | None

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.utils.signals.html b/_autosummary/mlfmu.utils.signals.html new file mode 100644 index 0000000..66ceff7 --- /dev/null +++ b/_autosummary/mlfmu.utils.signals.html @@ -0,0 +1,401 @@ + + + + + + + + + mlfmu.utils.signals - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.utils.signals

+

Functions

+
+ + + + + + +

range_list_expanded(list_of_ranges)

Expand ranges specified in interface.

+
+
+
+mlfmu.utils.signals.range_list_expanded(list_of_ranges: list[str]) list[int]
+

Expand ranges specified in interface. They should be formatted as [starts_index:end_index].

+
+
Parameters:
+

(List[str]) (list_of_ranges)

+
+
Return type:
+

A list of all indexes covered in ranges or individual indexes

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/mlfmu.utils.strings.html b/_autosummary/mlfmu.utils.strings.html new file mode 100644 index 0000000..ede8d32 --- /dev/null +++ b/_autosummary/mlfmu.utils.strings.html @@ -0,0 +1,393 @@ + + + + + + + + + mlfmu.utils.strings - mlfmu 1.0.2 + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

mlfmu.utils.strings

+

Functions

+
+ + + + + + +

to_camel(string)

Change casing of string to CamelCase.

+
+
+
+mlfmu.utils.strings.to_camel(string: str) str
+

Change casing of string to CamelCase.

+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_sources/ADVANCED.md.txt b/_sources/ADVANCED.md.txt new file mode 100644 index 0000000..82dfd45 --- /dev/null +++ b/_sources/ADVANCED.md.txt @@ -0,0 +1,2 @@ +```{include} ../../ADVANCED.md +``` diff --git a/_sources/CHANGELOG.md.txt b/_sources/CHANGELOG.md.txt new file mode 100644 index 0000000..b76750e --- /dev/null +++ b/_sources/CHANGELOG.md.txt @@ -0,0 +1,2 @@ +```{include} ../../CHANGELOG.md +``` \ No newline at end of file diff --git a/_sources/LICENSE.md.txt b/_sources/LICENSE.md.txt new file mode 100644 index 0000000..78f2a43 --- /dev/null +++ b/_sources/LICENSE.md.txt @@ -0,0 +1,3 @@ +# LICENSE +```{include} ../../LICENSE +``` \ No newline at end of file diff --git a/_sources/LICENSE_THIRD_PARTY.md.txt b/_sources/LICENSE_THIRD_PARTY.md.txt new file mode 100644 index 0000000..837f8a7 --- /dev/null +++ b/_sources/LICENSE_THIRD_PARTY.md.txt @@ -0,0 +1,4 @@ +# LICENSE THIRD PARTY + +```{include} ../../LICENSE_THIRD_PARTY +``` diff --git a/_sources/MLMODEL.md.txt b/_sources/MLMODEL.md.txt new file mode 100644 index 0000000..aeb96d6 --- /dev/null +++ b/_sources/MLMODEL.md.txt @@ -0,0 +1,2 @@ +```{include} ../../MLMODEL.md +``` diff --git a/_sources/README.md.txt b/_sources/README.md.txt new file mode 100644 index 0000000..16c6b76 --- /dev/null +++ b/_sources/README.md.txt @@ -0,0 +1,2 @@ +```{include} ../../README.md +``` \ No newline at end of file diff --git a/_sources/STYLEGUIDE.md.txt b/_sources/STYLEGUIDE.md.txt new file mode 100644 index 0000000..d5ac6e1 --- /dev/null +++ b/_sources/STYLEGUIDE.md.txt @@ -0,0 +1,2 @@ +```{include} ../../STYLEGUIDE.md +``` \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.api.MlFmuBuilder.rst.txt b/_sources/_autosummary/mlfmu.api.MlFmuBuilder.rst.txt new file mode 100644 index 0000000..54ac375 --- /dev/null +++ b/_sources/_autosummary/mlfmu.api.MlFmuBuilder.rst.txt @@ -0,0 +1,39 @@ +MlFmuBuilder +============ + +.. currentmodule:: mlfmu.api + +.. autoclass:: MlFmuBuilder + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~MlFmuBuilder.__init__ + ~MlFmuBuilder.build + ~MlFmuBuilder.compile + ~MlFmuBuilder.default_build_folder + ~MlFmuBuilder.default_build_source_folder + ~MlFmuBuilder.default_compile_source_folder + ~MlFmuBuilder.default_fmu_output_folder + ~MlFmuBuilder.default_generate_source_folder + ~MlFmuBuilder.default_interface_file + ~MlFmuBuilder.default_model_file + ~MlFmuBuilder.generate + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~MlFmuBuilder.temp_folder + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.api.MlFmuCommand.rst.txt b/_sources/_autosummary/mlfmu.api.MlFmuCommand.rst.txt new file mode 100644 index 0000000..baaee66 --- /dev/null +++ b/_sources/_autosummary/mlfmu.api.MlFmuCommand.rst.txt @@ -0,0 +1,31 @@ +MlFmuCommand +============ + +.. currentmodule:: mlfmu.api + +.. autoclass:: MlFmuCommand + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~MlFmuCommand.from_string + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~MlFmuCommand.BUILD + ~MlFmuCommand.GENERATE + ~MlFmuCommand.COMPILE + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.api.MlFmuProcess.rst.txt b/_sources/_autosummary/mlfmu.api.MlFmuProcess.rst.txt new file mode 100644 index 0000000..df42dbe --- /dev/null +++ b/_sources/_autosummary/mlfmu.api.MlFmuProcess.rst.txt @@ -0,0 +1,31 @@ +MlFmuProcess +============ + +.. currentmodule:: mlfmu.api + +.. autoclass:: MlFmuProcess + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~MlFmuProcess.__init__ + ~MlFmuProcess.run + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~MlFmuProcess.command + ~MlFmuProcess.builder + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.api.rst.txt b/_sources/_autosummary/mlfmu.api.rst.txt new file mode 100644 index 0000000..c4464da --- /dev/null +++ b/_sources/_autosummary/mlfmu.api.rst.txt @@ -0,0 +1,24 @@ +mlfmu.api +========= + +.. automodule:: mlfmu.api + :members: + :exclude-members: MlFmuBuilder,MlFmuCommand,MlFmuProcess, + + + + + .. rubric:: Functions + .. autosummary:: + + run + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + MlFmuBuilder + MlFmuCommand + MlFmuProcess + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.BaseModelConfig.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.BaseModelConfig.rst.txt new file mode 100644 index 0000000..051a375 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.BaseModelConfig.rst.txt @@ -0,0 +1,56 @@ +BaseModelConfig +=============== + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: BaseModelConfig + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~BaseModelConfig.__init__ + ~BaseModelConfig.construct + ~BaseModelConfig.copy + ~BaseModelConfig.dict + ~BaseModelConfig.from_orm + ~BaseModelConfig.json + ~BaseModelConfig.model_construct + ~BaseModelConfig.model_copy + ~BaseModelConfig.model_dump + ~BaseModelConfig.model_dump_json + ~BaseModelConfig.model_json_schema + ~BaseModelConfig.model_parametrized_name + ~BaseModelConfig.model_post_init + ~BaseModelConfig.model_rebuild + ~BaseModelConfig.model_validate + ~BaseModelConfig.model_validate_json + ~BaseModelConfig.model_validate_strings + ~BaseModelConfig.parse_file + ~BaseModelConfig.parse_obj + ~BaseModelConfig.parse_raw + ~BaseModelConfig.schema + ~BaseModelConfig.schema_json + ~BaseModelConfig.update_forward_refs + ~BaseModelConfig.validate + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~BaseModelConfig.model_computed_fields + ~BaseModelConfig.model_config + ~BaseModelConfig.model_extra + ~BaseModelConfig.model_fields + ~BaseModelConfig.model_fields_set + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.FmiCausality.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.FmiCausality.rst.txt new file mode 100644 index 0000000..a974b71 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.FmiCausality.rst.txt @@ -0,0 +1,78 @@ +FmiCausality +============ + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: FmiCausality + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~FmiCausality.encode + ~FmiCausality.replace + ~FmiCausality.split + ~FmiCausality.rsplit + ~FmiCausality.join + ~FmiCausality.capitalize + ~FmiCausality.casefold + ~FmiCausality.title + ~FmiCausality.center + ~FmiCausality.count + ~FmiCausality.expandtabs + ~FmiCausality.find + ~FmiCausality.partition + ~FmiCausality.index + ~FmiCausality.ljust + ~FmiCausality.lower + ~FmiCausality.lstrip + ~FmiCausality.rfind + ~FmiCausality.rindex + ~FmiCausality.rjust + ~FmiCausality.rstrip + ~FmiCausality.rpartition + ~FmiCausality.splitlines + ~FmiCausality.strip + ~FmiCausality.swapcase + ~FmiCausality.translate + ~FmiCausality.upper + ~FmiCausality.startswith + ~FmiCausality.endswith + ~FmiCausality.removeprefix + ~FmiCausality.removesuffix + ~FmiCausality.isascii + ~FmiCausality.islower + ~FmiCausality.isupper + ~FmiCausality.istitle + ~FmiCausality.isspace + ~FmiCausality.isdecimal + ~FmiCausality.isdigit + ~FmiCausality.isnumeric + ~FmiCausality.isalpha + ~FmiCausality.isalnum + ~FmiCausality.isidentifier + ~FmiCausality.isprintable + ~FmiCausality.zfill + ~FmiCausality.format + ~FmiCausality.format_map + ~FmiCausality.maketrans + ~FmiCausality.__init__ + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~FmiCausality.PARAMETER + ~FmiCausality.INPUT + ~FmiCausality.OUTPUT + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.FmiInputVariable.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.FmiInputVariable.rst.txt new file mode 100644 index 0000000..d3a9c7a --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.FmiInputVariable.rst.txt @@ -0,0 +1,67 @@ +FmiInputVariable +================ + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: FmiInputVariable + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~FmiInputVariable.__init__ + ~FmiInputVariable.construct + ~FmiInputVariable.copy + ~FmiInputVariable.dict + ~FmiInputVariable.from_orm + ~FmiInputVariable.json + ~FmiInputVariable.model_construct + ~FmiInputVariable.model_copy + ~FmiInputVariable.model_dump + ~FmiInputVariable.model_dump_json + ~FmiInputVariable.model_json_schema + ~FmiInputVariable.model_parametrized_name + ~FmiInputVariable.model_post_init + ~FmiInputVariable.model_rebuild + ~FmiInputVariable.model_validate + ~FmiInputVariable.model_validate_json + ~FmiInputVariable.model_validate_strings + ~FmiInputVariable.parse_file + ~FmiInputVariable.parse_obj + ~FmiInputVariable.parse_raw + ~FmiInputVariable.schema + ~FmiInputVariable.schema_json + ~FmiInputVariable.update_forward_refs + ~FmiInputVariable.validate + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~FmiInputVariable.model_computed_fields + ~FmiInputVariable.model_config + ~FmiInputVariable.model_extra + ~FmiInputVariable.model_fields + ~FmiInputVariable.model_fields_set + ~FmiInputVariable.causality + ~FmiInputVariable.variable_references + ~FmiInputVariable.agent_state_init_indexes + ~FmiInputVariable.agent_input_indexes + ~FmiInputVariable.name + ~FmiInputVariable.type + ~FmiInputVariable.description + ~FmiInputVariable.variability + ~FmiInputVariable.start_value + ~FmiInputVariable.is_array + ~FmiInputVariable.length + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.FmiModel.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.FmiModel.rst.txt new file mode 100644 index 0000000..a7ad433 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.FmiModel.rst.txt @@ -0,0 +1,44 @@ +FmiModel +======== + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: FmiModel + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~FmiModel.__init__ + ~FmiModel.add_state_initialization_parameters + ~FmiModel.add_variable_references + ~FmiModel.format_fmi_variable + ~FmiModel.get_fmi_model_variables + ~FmiModel.get_template_mapping + ~FmiModel.get_total_variable_number + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~FmiModel.name + ~FmiModel.guid + ~FmiModel.inputs + ~FmiModel.outputs + ~FmiModel.parameters + ~FmiModel.author + ~FmiModel.description + ~FmiModel.copyright + ~FmiModel.license + ~FmiModel.state_initialization_reuse + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.FmiOutputVariable.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.FmiOutputVariable.rst.txt new file mode 100644 index 0000000..ba23f20 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.FmiOutputVariable.rst.txt @@ -0,0 +1,66 @@ +FmiOutputVariable +================= + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: FmiOutputVariable + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~FmiOutputVariable.__init__ + ~FmiOutputVariable.construct + ~FmiOutputVariable.copy + ~FmiOutputVariable.dict + ~FmiOutputVariable.from_orm + ~FmiOutputVariable.json + ~FmiOutputVariable.model_construct + ~FmiOutputVariable.model_copy + ~FmiOutputVariable.model_dump + ~FmiOutputVariable.model_dump_json + ~FmiOutputVariable.model_json_schema + ~FmiOutputVariable.model_parametrized_name + ~FmiOutputVariable.model_post_init + ~FmiOutputVariable.model_rebuild + ~FmiOutputVariable.model_validate + ~FmiOutputVariable.model_validate_json + ~FmiOutputVariable.model_validate_strings + ~FmiOutputVariable.parse_file + ~FmiOutputVariable.parse_obj + ~FmiOutputVariable.parse_raw + ~FmiOutputVariable.schema + ~FmiOutputVariable.schema_json + ~FmiOutputVariable.update_forward_refs + ~FmiOutputVariable.validate + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~FmiOutputVariable.model_computed_fields + ~FmiOutputVariable.model_config + ~FmiOutputVariable.model_extra + ~FmiOutputVariable.model_fields + ~FmiOutputVariable.model_fields_set + ~FmiOutputVariable.causality + ~FmiOutputVariable.variable_references + ~FmiOutputVariable.agent_output_indexes + ~FmiOutputVariable.name + ~FmiOutputVariable.type + ~FmiOutputVariable.description + ~FmiOutputVariable.variability + ~FmiOutputVariable.start_value + ~FmiOutputVariable.is_array + ~FmiOutputVariable.length + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariability.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariability.rst.txt new file mode 100644 index 0000000..3c73b1c --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariability.rst.txt @@ -0,0 +1,80 @@ +FmiVariability +============== + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: FmiVariability + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~FmiVariability.encode + ~FmiVariability.replace + ~FmiVariability.split + ~FmiVariability.rsplit + ~FmiVariability.join + ~FmiVariability.capitalize + ~FmiVariability.casefold + ~FmiVariability.title + ~FmiVariability.center + ~FmiVariability.count + ~FmiVariability.expandtabs + ~FmiVariability.find + ~FmiVariability.partition + ~FmiVariability.index + ~FmiVariability.ljust + ~FmiVariability.lower + ~FmiVariability.lstrip + ~FmiVariability.rfind + ~FmiVariability.rindex + ~FmiVariability.rjust + ~FmiVariability.rstrip + ~FmiVariability.rpartition + ~FmiVariability.splitlines + ~FmiVariability.strip + ~FmiVariability.swapcase + ~FmiVariability.translate + ~FmiVariability.upper + ~FmiVariability.startswith + ~FmiVariability.endswith + ~FmiVariability.removeprefix + ~FmiVariability.removesuffix + ~FmiVariability.isascii + ~FmiVariability.islower + ~FmiVariability.isupper + ~FmiVariability.istitle + ~FmiVariability.isspace + ~FmiVariability.isdecimal + ~FmiVariability.isdigit + ~FmiVariability.isnumeric + ~FmiVariability.isalpha + ~FmiVariability.isalnum + ~FmiVariability.isidentifier + ~FmiVariability.isprintable + ~FmiVariability.zfill + ~FmiVariability.format + ~FmiVariability.format_map + ~FmiVariability.maketrans + ~FmiVariability.__init__ + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~FmiVariability.CONSTANT + ~FmiVariability.FIXED + ~FmiVariability.TUNABLE + ~FmiVariability.DISCRETE + ~FmiVariability.CONTINUOUS + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariable.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariable.rst.txt new file mode 100644 index 0000000..8719a2d --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariable.rst.txt @@ -0,0 +1,35 @@ +FmiVariable +=========== + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: FmiVariable + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~FmiVariable.__init__ + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~FmiVariable.causality + ~FmiVariable.description + ~FmiVariable.name + ~FmiVariable.start_value + ~FmiVariable.type + ~FmiVariable.variability + ~FmiVariable.variable_reference + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariableType.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariableType.rst.txt new file mode 100644 index 0000000..2abe433 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.FmiVariableType.rst.txt @@ -0,0 +1,79 @@ +FmiVariableType +=============== + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: FmiVariableType + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~FmiVariableType.encode + ~FmiVariableType.replace + ~FmiVariableType.split + ~FmiVariableType.rsplit + ~FmiVariableType.join + ~FmiVariableType.capitalize + ~FmiVariableType.casefold + ~FmiVariableType.title + ~FmiVariableType.center + ~FmiVariableType.count + ~FmiVariableType.expandtabs + ~FmiVariableType.find + ~FmiVariableType.partition + ~FmiVariableType.index + ~FmiVariableType.ljust + ~FmiVariableType.lower + ~FmiVariableType.lstrip + ~FmiVariableType.rfind + ~FmiVariableType.rindex + ~FmiVariableType.rjust + ~FmiVariableType.rstrip + ~FmiVariableType.rpartition + ~FmiVariableType.splitlines + ~FmiVariableType.strip + ~FmiVariableType.swapcase + ~FmiVariableType.translate + ~FmiVariableType.upper + ~FmiVariableType.startswith + ~FmiVariableType.endswith + ~FmiVariableType.removeprefix + ~FmiVariableType.removesuffix + ~FmiVariableType.isascii + ~FmiVariableType.islower + ~FmiVariableType.isupper + ~FmiVariableType.istitle + ~FmiVariableType.isspace + ~FmiVariableType.isdecimal + ~FmiVariableType.isdigit + ~FmiVariableType.isnumeric + ~FmiVariableType.isalpha + ~FmiVariableType.isalnum + ~FmiVariableType.isidentifier + ~FmiVariableType.isprintable + ~FmiVariableType.zfill + ~FmiVariableType.format + ~FmiVariableType.format_map + ~FmiVariableType.maketrans + ~FmiVariableType.__init__ + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~FmiVariableType.REAL + ~FmiVariableType.INTEGER + ~FmiVariableType.STRING + ~FmiVariableType.BOOLEAN + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.InputVariable.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.InputVariable.rst.txt new file mode 100644 index 0000000..b778161 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.InputVariable.rst.txt @@ -0,0 +1,64 @@ +InputVariable +============= + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: InputVariable + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~InputVariable.__init__ + ~InputVariable.construct + ~InputVariable.copy + ~InputVariable.dict + ~InputVariable.from_orm + ~InputVariable.json + ~InputVariable.model_construct + ~InputVariable.model_copy + ~InputVariable.model_dump + ~InputVariable.model_dump_json + ~InputVariable.model_json_schema + ~InputVariable.model_parametrized_name + ~InputVariable.model_post_init + ~InputVariable.model_rebuild + ~InputVariable.model_validate + ~InputVariable.model_validate_json + ~InputVariable.model_validate_strings + ~InputVariable.parse_file + ~InputVariable.parse_obj + ~InputVariable.parse_raw + ~InputVariable.schema + ~InputVariable.schema_json + ~InputVariable.update_forward_refs + ~InputVariable.validate + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~InputVariable.model_computed_fields + ~InputVariable.model_config + ~InputVariable.model_extra + ~InputVariable.model_fields + ~InputVariable.model_fields_set + ~InputVariable.agent_input_indexes + ~InputVariable.name + ~InputVariable.type + ~InputVariable.description + ~InputVariable.variability + ~InputVariable.start_value + ~InputVariable.is_array + ~InputVariable.length + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.InternalState.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.InternalState.rst.txt new file mode 100644 index 0000000..13c19b6 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.InternalState.rst.txt @@ -0,0 +1,62 @@ +InternalState +============= + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: InternalState + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~InternalState.__init__ + ~InternalState.check_only_one_initialization + ~InternalState.construct + ~InternalState.copy + ~InternalState.dict + ~InternalState.from_orm + ~InternalState.json + ~InternalState.model_construct + ~InternalState.model_copy + ~InternalState.model_dump + ~InternalState.model_dump_json + ~InternalState.model_json_schema + ~InternalState.model_parametrized_name + ~InternalState.model_post_init + ~InternalState.model_rebuild + ~InternalState.model_validate + ~InternalState.model_validate_json + ~InternalState.model_validate_strings + ~InternalState.parse_file + ~InternalState.parse_obj + ~InternalState.parse_raw + ~InternalState.schema + ~InternalState.schema_json + ~InternalState.update_forward_refs + ~InternalState.validate + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~InternalState.model_computed_fields + ~InternalState.model_config + ~InternalState.model_extra + ~InternalState.model_fields + ~InternalState.model_fields_set + ~InternalState.name + ~InternalState.description + ~InternalState.start_value + ~InternalState.initialization_variable + ~InternalState.agent_output_indexes + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.ModelComponent.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.ModelComponent.rst.txt new file mode 100644 index 0000000..e615016 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.ModelComponent.rst.txt @@ -0,0 +1,68 @@ +ModelComponent +============== + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: ModelComponent + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~ModelComponent.__init__ + ~ModelComponent.construct + ~ModelComponent.copy + ~ModelComponent.dict + ~ModelComponent.from_orm + ~ModelComponent.json + ~ModelComponent.model_construct + ~ModelComponent.model_copy + ~ModelComponent.model_dump + ~ModelComponent.model_dump_json + ~ModelComponent.model_json_schema + ~ModelComponent.model_parametrized_name + ~ModelComponent.model_post_init + ~ModelComponent.model_rebuild + ~ModelComponent.model_validate + ~ModelComponent.model_validate_json + ~ModelComponent.model_validate_strings + ~ModelComponent.parse_file + ~ModelComponent.parse_obj + ~ModelComponent.parse_raw + ~ModelComponent.schema + ~ModelComponent.schema_json + ~ModelComponent.update_forward_refs + ~ModelComponent.validate + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~ModelComponent.model_computed_fields + ~ModelComponent.model_config + ~ModelComponent.model_extra + ~ModelComponent.model_fields + ~ModelComponent.model_fields_set + ~ModelComponent.name + ~ModelComponent.version + ~ModelComponent.author + ~ModelComponent.description + ~ModelComponent.copyright + ~ModelComponent.license + ~ModelComponent.inputs + ~ModelComponent.outputs + ~ModelComponent.parameters + ~ModelComponent.states + ~ModelComponent.uses_time + ~ModelComponent.state_initialization_reuse + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.OutputVariable.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.OutputVariable.rst.txt new file mode 100644 index 0000000..8fa05b3 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.OutputVariable.rst.txt @@ -0,0 +1,64 @@ +OutputVariable +============== + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: OutputVariable + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~OutputVariable.__init__ + ~OutputVariable.construct + ~OutputVariable.copy + ~OutputVariable.dict + ~OutputVariable.from_orm + ~OutputVariable.json + ~OutputVariable.model_construct + ~OutputVariable.model_copy + ~OutputVariable.model_dump + ~OutputVariable.model_dump_json + ~OutputVariable.model_json_schema + ~OutputVariable.model_parametrized_name + ~OutputVariable.model_post_init + ~OutputVariable.model_rebuild + ~OutputVariable.model_validate + ~OutputVariable.model_validate_json + ~OutputVariable.model_validate_strings + ~OutputVariable.parse_file + ~OutputVariable.parse_obj + ~OutputVariable.parse_raw + ~OutputVariable.schema + ~OutputVariable.schema_json + ~OutputVariable.update_forward_refs + ~OutputVariable.validate + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~OutputVariable.model_computed_fields + ~OutputVariable.model_config + ~OutputVariable.model_extra + ~OutputVariable.model_fields + ~OutputVariable.model_fields_set + ~OutputVariable.agent_output_indexes + ~OutputVariable.name + ~OutputVariable.type + ~OutputVariable.description + ~OutputVariable.variability + ~OutputVariable.start_value + ~OutputVariable.is_array + ~OutputVariable.length + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.Variable.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.Variable.rst.txt new file mode 100644 index 0000000..e7c4ee1 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.Variable.rst.txt @@ -0,0 +1,63 @@ +Variable +======== + +.. currentmodule:: mlfmu.types.fmu_component + +.. autoclass:: Variable + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~Variable.__init__ + ~Variable.construct + ~Variable.copy + ~Variable.dict + ~Variable.from_orm + ~Variable.json + ~Variable.model_construct + ~Variable.model_copy + ~Variable.model_dump + ~Variable.model_dump_json + ~Variable.model_json_schema + ~Variable.model_parametrized_name + ~Variable.model_post_init + ~Variable.model_rebuild + ~Variable.model_validate + ~Variable.model_validate_json + ~Variable.model_validate_strings + ~Variable.parse_file + ~Variable.parse_obj + ~Variable.parse_raw + ~Variable.schema + ~Variable.schema_json + ~Variable.update_forward_refs + ~Variable.validate + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~Variable.model_computed_fields + ~Variable.model_config + ~Variable.model_extra + ~Variable.model_fields + ~Variable.model_fields_set + ~Variable.name + ~Variable.type + ~Variable.description + ~Variable.variability + ~Variable.start_value + ~Variable.is_array + ~Variable.length + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.fmu_component.rst.txt b/_sources/_autosummary/mlfmu.types.fmu_component.rst.txt new file mode 100644 index 0000000..c34e198 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.fmu_component.rst.txt @@ -0,0 +1,29 @@ +mlfmu.types.fmu\_component +========================== + +.. automodule:: mlfmu.types.fmu_component + :members: + :exclude-members: BaseModelConfig,FmiCausality,FmiInputVariable,FmiModel,FmiOutputVariable,FmiVariability,FmiVariable,FmiVariableType,InputVariable,InternalState,ModelComponent,OutputVariable,Variable, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + BaseModelConfig + FmiCausality + FmiInputVariable + FmiModel + FmiOutputVariable + FmiVariability + FmiVariable + FmiVariableType + InputVariable + InternalState + ModelComponent + OutputVariable + Variable + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.onnx_model.ONNXModel.rst.txt b/_sources/_autosummary/mlfmu.types.onnx_model.ONNXModel.rst.txt new file mode 100644 index 0000000..33752df --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.onnx_model.ONNXModel.rst.txt @@ -0,0 +1,39 @@ +ONNXModel +========= + +.. currentmodule:: mlfmu.types.onnx_model + +.. autoclass:: ONNXModel + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~ONNXModel.__init__ + ~ONNXModel.load_inputs + ~ONNXModel.load_outputs + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~ONNXModel.filename + ~ONNXModel.input_name + ~ONNXModel.input_size + ~ONNXModel.output_name + ~ONNXModel.output_size + ~ONNXModel.state_size + ~ONNXModel.states_name + ~ONNXModel.time_input + ~ONNXModel.time_input_name + + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.onnx_model.rst.txt b/_sources/_autosummary/mlfmu.types.onnx_model.rst.txt new file mode 100644 index 0000000..fa0bff3 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.onnx_model.rst.txt @@ -0,0 +1,17 @@ +mlfmu.types.onnx\_model +======================= + +.. automodule:: mlfmu.types.onnx_model + :members: + :exclude-members: ONNXModel, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + ONNXModel + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.types.rst.txt b/_sources/_autosummary/mlfmu.types.rst.txt new file mode 100644 index 0000000..1804589 --- /dev/null +++ b/_sources/_autosummary/mlfmu.types.rst.txt @@ -0,0 +1,16 @@ +mlfmu.types +=========== + +.. automodule:: mlfmu.types + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + fmu_component + onnx_model diff --git a/_sources/_autosummary/mlfmu.utils.builder.rst.txt b/_sources/_autosummary/mlfmu.utils.builder.rst.txt new file mode 100644 index 0000000..72acd74 --- /dev/null +++ b/_sources/_autosummary/mlfmu.utils.builder.rst.txt @@ -0,0 +1,21 @@ +mlfmu.utils.builder +=================== + +.. automodule:: mlfmu.utils.builder + :members: + + + + .. rubric:: Functions + .. autosummary:: + + build_fmu + create_files_from_templates + create_model_description + format_template_data + format_template_file + generate_fmu_files + make_fmu_dirs + validate_fmu_source_files + validate_interface_spec + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.utils.fmi_builder.rst.txt b/_sources/_autosummary/mlfmu.utils.fmi_builder.rst.txt new file mode 100644 index 0000000..17b5112 --- /dev/null +++ b/_sources/_autosummary/mlfmu.utils.fmi_builder.rst.txt @@ -0,0 +1,14 @@ +mlfmu.utils.fmi\_builder +======================== + +.. automodule:: mlfmu.utils.fmi_builder + :members: + + + + .. rubric:: Functions + .. autosummary:: + + generate_model_description + requires_start + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.utils.interface.rst.txt b/_sources/_autosummary/mlfmu.utils.interface.rst.txt new file mode 100644 index 0000000..949998b --- /dev/null +++ b/_sources/_autosummary/mlfmu.utils.interface.rst.txt @@ -0,0 +1,15 @@ +mlfmu.utils.interface +===================== + +.. automodule:: mlfmu.utils.interface + :members: + + + + .. rubric:: Functions + .. autosummary:: + + generate_interface_docs + generate_interface_schema + publish_interface_schema + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.utils.logging.rst.txt b/_sources/_autosummary/mlfmu.utils.logging.rst.txt new file mode 100644 index 0000000..8eb5eb1 --- /dev/null +++ b/_sources/_autosummary/mlfmu.utils.logging.rst.txt @@ -0,0 +1,13 @@ +mlfmu.utils.logging +=================== + +.. automodule:: mlfmu.utils.logging + :members: + + + + .. rubric:: Functions + .. autosummary:: + + configure_logging + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.utils.path.rst.txt b/_sources/_autosummary/mlfmu.utils.path.rst.txt new file mode 100644 index 0000000..1ebdab4 --- /dev/null +++ b/_sources/_autosummary/mlfmu.utils.path.rst.txt @@ -0,0 +1,13 @@ +mlfmu.utils.path +================ + +.. automodule:: mlfmu.utils.path + :members: + + + + .. rubric:: Functions + .. autosummary:: + + find_default_file + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.utils.rst.txt b/_sources/_autosummary/mlfmu.utils.rst.txt new file mode 100644 index 0000000..f979f6f --- /dev/null +++ b/_sources/_autosummary/mlfmu.utils.rst.txt @@ -0,0 +1,21 @@ +mlfmu.utils +=========== + +.. automodule:: mlfmu.utils + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + builder + fmi_builder + interface + logging + path + signals + strings diff --git a/_sources/_autosummary/mlfmu.utils.signals.rst.txt b/_sources/_autosummary/mlfmu.utils.signals.rst.txt new file mode 100644 index 0000000..26844cf --- /dev/null +++ b/_sources/_autosummary/mlfmu.utils.signals.rst.txt @@ -0,0 +1,13 @@ +mlfmu.utils.signals +=================== + +.. automodule:: mlfmu.utils.signals + :members: + + + + .. rubric:: Functions + .. autosummary:: + + range_list_expanded + \ No newline at end of file diff --git a/_sources/_autosummary/mlfmu.utils.strings.rst.txt b/_sources/_autosummary/mlfmu.utils.strings.rst.txt new file mode 100644 index 0000000..8e987de --- /dev/null +++ b/_sources/_autosummary/mlfmu.utils.strings.rst.txt @@ -0,0 +1,13 @@ +mlfmu.utils.strings +=================== + +.. automodule:: mlfmu.utils.strings + :members: + + + + .. rubric:: Functions + .. autosummary:: + + to_camel + \ No newline at end of file diff --git a/_sources/api.rst.txt b/_sources/api.rst.txt new file mode 100644 index 0000000..08f3363 --- /dev/null +++ b/_sources/api.rst.txt @@ -0,0 +1,11 @@ +API Reference +============= + +.. autosummary:: + :toctree: _autosummary + :template: custom-module.rst + :recursive: + + mlfmu.api + mlfmu.types + mlfmu.utils diff --git a/_sources/cli.mlfmu.rst.txt b/_sources/cli.mlfmu.rst.txt new file mode 100644 index 0000000..7aab188 --- /dev/null +++ b/_sources/cli.mlfmu.rst.txt @@ -0,0 +1,3 @@ +.. sphinx_argparse_cli:: + :module: mlfmu.cli.mlfmu + :func: _argparser diff --git a/_sources/cli.rst.txt b/_sources/cli.rst.txt new file mode 100644 index 0000000..f5cd05f --- /dev/null +++ b/_sources/cli.rst.txt @@ -0,0 +1,7 @@ +CLI Documentation +================= + +.. toctree:: + :maxdepth: 2 + + cli.mlfmu diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 0000000..f007f4d --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,28 @@ +.. mlfmu documentation master file, created by + sphinx-quickstart on Wed Jul 6 21:16:21 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +mlfmu: Example Python Package +========================================= + +.. toctree:: + :maxdepth: 3 + :caption: Contents: + + README + MLMODEL + ADVANCED + cli + api + CHANGELOG + STYLEGUIDE + LICENSE + LICENSE_THIRD_PARTY + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 0000000..7ebbd6d --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,914 @@ +/* + * Sphinx stylesheet -- basic theme. + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin-top: 10px; +} + +ul.search li { + padding: 5px 0; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/debug.css b/_static/debug.css new file mode 100644 index 0000000..74d4aec --- /dev/null +++ b/_static/debug.css @@ -0,0 +1,69 @@ +/* + This CSS file should be overridden by the theme authors. It's + meant for debugging and developing the skeleton that this theme provides. +*/ +body { + font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji"; + background: lavender; +} +.sb-announcement { + background: rgb(131, 131, 131); +} +.sb-announcement__inner { + background: black; + color: white; +} +.sb-header { + background: lightskyblue; +} +.sb-header__inner { + background: royalblue; + color: white; +} +.sb-header-secondary { + background: lightcyan; +} +.sb-header-secondary__inner { + background: cornflowerblue; + color: white; +} +.sb-sidebar-primary { + background: lightgreen; +} +.sb-main { + background: blanchedalmond; +} +.sb-main__inner { + background: antiquewhite; +} +.sb-header-article { + background: lightsteelblue; +} +.sb-article-container { + background: snow; +} +.sb-article-main { + background: white; +} +.sb-footer-article { + background: lightpink; +} +.sb-sidebar-secondary { + background: lightgoldenrodyellow; +} +.sb-footer-content { + background: plum; +} +.sb-footer-content__inner { + background: palevioletred; +} +.sb-footer { + background: pink; +} +.sb-footer__inner { + background: salmon; +} +.sb-article { + background: white; +} diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 0000000..0398ebb --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,149 @@ +/* + * Base JavaScript utilities for all Sphinx HTML documentation. + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 0000000..e15aace --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '1.0.2', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 0000000..c7fe6c6 --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,192 @@ +/* + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..d96755fdaf8bb2214971e0db9c1fd3077d7c419d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu=nj kDsEF_5m^0CR;1wuP-*O&G^0G}KYk!hp00i_>zopr08q^qX#fBK literal 0 HcmV?d00001 diff --git a/_static/mlfmu_logo_v1.svg b/_static/mlfmu_logo_v1.svg new file mode 100644 index 0000000..e41b5dc --- /dev/null +++ b/_static/mlfmu_logo_v1.svg @@ -0,0 +1 @@ +MLFMU \ No newline at end of file diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..7107cec93a979b9a5f64843235a16651d563ce2d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu>-2 m3q%Vub%g%s<8sJhVPMczOq}xhg9DJoz~JfX=d#Wzp$Pyb1r*Kz literal 0 HcmV?d00001 diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 0000000..02b4b12 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,258 @@ +.highlight pre { line-height: 125%; } +.highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #8f5902; font-style: italic } /* Comment */ +.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ +.highlight .g { color: #000000 } /* Generic */ +.highlight .k { color: #204a87; font-weight: bold } /* Keyword */ +.highlight .l { color: #000000 } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */ +.highlight .x { color: #000000 } /* Other */ +.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ +.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ +.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #a40000 } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .ges { color: #000000; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #ef2929 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #000000; font-style: italic } /* Generic.Output */ +.highlight .gp { color: #8f5902 } /* Generic.Prompt */ +.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000000 } /* Literal.Date */ +.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #4e9a06 } /* Literal.String */ +.highlight .na { color: #c4a000 } /* Name.Attribute */ +.highlight .nb { color: #204a87 } /* Name.Builtin */ +.highlight .nc { color: #000000 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #ce5c00 } /* Name.Entity */ +.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #f57900 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ +.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */ +.highlight .w { color: #f8f8f8 } /* Text.Whitespace */ +.highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */ +.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ +.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ +.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ +.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ +.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ +.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ +.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ +.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #000000 } /* Name.Function.Magic */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .vm { color: #000000 } /* Name.Variable.Magic */ +.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ +@media not print { +body[data-theme="dark"] .highlight pre { line-height: 125%; } +body[data-theme="dark"] .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight .hll { background-color: #404040 } +body[data-theme="dark"] .highlight { background: #202020; color: #d0d0d0 } +body[data-theme="dark"] .highlight .c { color: #ababab; font-style: italic } /* Comment */ +body[data-theme="dark"] .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +body[data-theme="dark"] .highlight .esc { color: #d0d0d0 } /* Escape */ +body[data-theme="dark"] .highlight .g { color: #d0d0d0 } /* Generic */ +body[data-theme="dark"] .highlight .k { color: #6ebf26; font-weight: bold } /* Keyword */ +body[data-theme="dark"] .highlight .l { color: #d0d0d0 } /* Literal */ +body[data-theme="dark"] .highlight .n { color: #d0d0d0 } /* Name */ +body[data-theme="dark"] .highlight .o { color: #d0d0d0 } /* Operator */ +body[data-theme="dark"] .highlight .x { color: #d0d0d0 } /* Other */ +body[data-theme="dark"] .highlight .p { color: #d0d0d0 } /* Punctuation */ +body[data-theme="dark"] .highlight .ch { color: #ababab; font-style: italic } /* Comment.Hashbang */ +body[data-theme="dark"] .highlight .cm { color: #ababab; font-style: italic } /* Comment.Multiline */ +body[data-theme="dark"] .highlight .cp { color: #ff3a3a; font-weight: bold } /* Comment.Preproc */ +body[data-theme="dark"] .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */ +body[data-theme="dark"] .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */ +body[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +body[data-theme="dark"] .highlight .gd { color: #ff3a3a } /* Generic.Deleted */ +body[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +body[data-theme="dark"] .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body[data-theme="dark"] .highlight .gr { color: #ff3a3a } /* Generic.Error */ +body[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +body[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */ +body[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */ +body[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */ +body[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ +body[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ +body[data-theme="dark"] .highlight .gt { color: #ff3a3a } /* Generic.Traceback */ +body[data-theme="dark"] .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */ +body[data-theme="dark"] .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */ +body[data-theme="dark"] .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */ +body[data-theme="dark"] .highlight .kp { color: #6ebf26 } /* Keyword.Pseudo */ +body[data-theme="dark"] .highlight .kr { color: #6ebf26; font-weight: bold } /* Keyword.Reserved */ +body[data-theme="dark"] .highlight .kt { color: #6ebf26; font-weight: bold } /* Keyword.Type */ +body[data-theme="dark"] .highlight .ld { color: #d0d0d0 } /* Literal.Date */ +body[data-theme="dark"] .highlight .m { color: #51b2fd } /* Literal.Number */ +body[data-theme="dark"] .highlight .s { color: #ed9d13 } /* Literal.String */ +body[data-theme="dark"] .highlight .na { color: #bbbbbb } /* Name.Attribute */ +body[data-theme="dark"] .highlight .nb { color: #2fbccd } /* Name.Builtin */ +body[data-theme="dark"] .highlight .nc { color: #71adff; text-decoration: underline } /* Name.Class */ +body[data-theme="dark"] .highlight .no { color: #40ffff } /* Name.Constant */ +body[data-theme="dark"] .highlight .nd { color: #ffa500 } /* Name.Decorator */ +body[data-theme="dark"] .highlight .ni { color: #d0d0d0 } /* Name.Entity */ +body[data-theme="dark"] .highlight .ne { color: #bbbbbb } /* Name.Exception */ +body[data-theme="dark"] .highlight .nf { color: #71adff } /* Name.Function */ +body[data-theme="dark"] .highlight .nl { color: #d0d0d0 } /* Name.Label */ +body[data-theme="dark"] .highlight .nn { color: #71adff; text-decoration: underline } /* Name.Namespace */ +body[data-theme="dark"] .highlight .nx { color: #d0d0d0 } /* Name.Other */ +body[data-theme="dark"] .highlight .py { color: #d0d0d0 } /* Name.Property */ +body[data-theme="dark"] .highlight .nt { color: #6ebf26; font-weight: bold } /* Name.Tag */ +body[data-theme="dark"] .highlight .nv { color: #40ffff } /* Name.Variable */ +body[data-theme="dark"] .highlight .ow { color: #6ebf26; font-weight: bold } /* Operator.Word */ +body[data-theme="dark"] .highlight .pm { color: #d0d0d0 } /* Punctuation.Marker */ +body[data-theme="dark"] .highlight .w { color: #666666 } /* Text.Whitespace */ +body[data-theme="dark"] .highlight .mb { color: #51b2fd } /* Literal.Number.Bin */ +body[data-theme="dark"] .highlight .mf { color: #51b2fd } /* Literal.Number.Float */ +body[data-theme="dark"] .highlight .mh { color: #51b2fd } /* Literal.Number.Hex */ +body[data-theme="dark"] .highlight .mi { color: #51b2fd } /* Literal.Number.Integer */ +body[data-theme="dark"] .highlight .mo { color: #51b2fd } /* Literal.Number.Oct */ +body[data-theme="dark"] .highlight .sa { color: #ed9d13 } /* Literal.String.Affix */ +body[data-theme="dark"] .highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */ +body[data-theme="dark"] .highlight .sc { color: #ed9d13 } /* Literal.String.Char */ +body[data-theme="dark"] .highlight .dl { color: #ed9d13 } /* Literal.String.Delimiter */ +body[data-theme="dark"] .highlight .sd { color: #ed9d13 } /* Literal.String.Doc */ +body[data-theme="dark"] .highlight .s2 { color: #ed9d13 } /* Literal.String.Double */ +body[data-theme="dark"] .highlight .se { color: #ed9d13 } /* Literal.String.Escape */ +body[data-theme="dark"] .highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */ +body[data-theme="dark"] .highlight .si { color: #ed9d13 } /* Literal.String.Interpol */ +body[data-theme="dark"] .highlight .sx { color: #ffa500 } /* Literal.String.Other */ +body[data-theme="dark"] .highlight .sr { color: #ed9d13 } /* Literal.String.Regex */ +body[data-theme="dark"] .highlight .s1 { color: #ed9d13 } /* Literal.String.Single */ +body[data-theme="dark"] .highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */ +body[data-theme="dark"] .highlight .bp { color: #2fbccd } /* Name.Builtin.Pseudo */ +body[data-theme="dark"] .highlight .fm { color: #71adff } /* Name.Function.Magic */ +body[data-theme="dark"] .highlight .vc { color: #40ffff } /* Name.Variable.Class */ +body[data-theme="dark"] .highlight .vg { color: #40ffff } /* Name.Variable.Global */ +body[data-theme="dark"] .highlight .vi { color: #40ffff } /* Name.Variable.Instance */ +body[data-theme="dark"] .highlight .vm { color: #40ffff } /* Name.Variable.Magic */ +body[data-theme="dark"] .highlight .il { color: #51b2fd } /* Literal.Number.Integer.Long */ +@media (prefers-color-scheme: dark) { +body:not([data-theme="light"]) .highlight pre { line-height: 125%; } +body:not([data-theme="light"]) .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight .hll { background-color: #404040 } +body:not([data-theme="light"]) .highlight { background: #202020; color: #d0d0d0 } +body:not([data-theme="light"]) .highlight .c { color: #ababab; font-style: italic } /* Comment */ +body:not([data-theme="light"]) .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +body:not([data-theme="light"]) .highlight .esc { color: #d0d0d0 } /* Escape */ +body:not([data-theme="light"]) .highlight .g { color: #d0d0d0 } /* Generic */ +body:not([data-theme="light"]) .highlight .k { color: #6ebf26; font-weight: bold } /* Keyword */ +body:not([data-theme="light"]) .highlight .l { color: #d0d0d0 } /* Literal */ +body:not([data-theme="light"]) .highlight .n { color: #d0d0d0 } /* Name */ +body:not([data-theme="light"]) .highlight .o { color: #d0d0d0 } /* Operator */ +body:not([data-theme="light"]) .highlight .x { color: #d0d0d0 } /* Other */ +body:not([data-theme="light"]) .highlight .p { color: #d0d0d0 } /* Punctuation */ +body:not([data-theme="light"]) .highlight .ch { color: #ababab; font-style: italic } /* Comment.Hashbang */ +body:not([data-theme="light"]) .highlight .cm { color: #ababab; font-style: italic } /* Comment.Multiline */ +body:not([data-theme="light"]) .highlight .cp { color: #ff3a3a; font-weight: bold } /* Comment.Preproc */ +body:not([data-theme="light"]) .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */ +body:not([data-theme="light"]) .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */ +body:not([data-theme="light"]) .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +body:not([data-theme="light"]) .highlight .gd { color: #ff3a3a } /* Generic.Deleted */ +body:not([data-theme="light"]) .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +body:not([data-theme="light"]) .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body:not([data-theme="light"]) .highlight .gr { color: #ff3a3a } /* Generic.Error */ +body:not([data-theme="light"]) .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +body:not([data-theme="light"]) .highlight .gi { color: #589819 } /* Generic.Inserted */ +body:not([data-theme="light"]) .highlight .go { color: #cccccc } /* Generic.Output */ +body:not([data-theme="light"]) .highlight .gp { color: #aaaaaa } /* Generic.Prompt */ +body:not([data-theme="light"]) .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ +body:not([data-theme="light"]) .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ +body:not([data-theme="light"]) .highlight .gt { color: #ff3a3a } /* Generic.Traceback */ +body:not([data-theme="light"]) .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */ +body:not([data-theme="light"]) .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */ +body:not([data-theme="light"]) .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */ +body:not([data-theme="light"]) .highlight .kp { color: #6ebf26 } /* Keyword.Pseudo */ +body:not([data-theme="light"]) .highlight .kr { color: #6ebf26; font-weight: bold } /* Keyword.Reserved */ +body:not([data-theme="light"]) .highlight .kt { color: #6ebf26; font-weight: bold } /* Keyword.Type */ +body:not([data-theme="light"]) .highlight .ld { color: #d0d0d0 } /* Literal.Date */ +body:not([data-theme="light"]) .highlight .m { color: #51b2fd } /* Literal.Number */ +body:not([data-theme="light"]) .highlight .s { color: #ed9d13 } /* Literal.String */ +body:not([data-theme="light"]) .highlight .na { color: #bbbbbb } /* Name.Attribute */ +body:not([data-theme="light"]) .highlight .nb { color: #2fbccd } /* Name.Builtin */ +body:not([data-theme="light"]) .highlight .nc { color: #71adff; text-decoration: underline } /* Name.Class */ +body:not([data-theme="light"]) .highlight .no { color: #40ffff } /* Name.Constant */ +body:not([data-theme="light"]) .highlight .nd { color: #ffa500 } /* Name.Decorator */ +body:not([data-theme="light"]) .highlight .ni { color: #d0d0d0 } /* Name.Entity */ +body:not([data-theme="light"]) .highlight .ne { color: #bbbbbb } /* Name.Exception */ +body:not([data-theme="light"]) .highlight .nf { color: #71adff } /* Name.Function */ +body:not([data-theme="light"]) .highlight .nl { color: #d0d0d0 } /* Name.Label */ +body:not([data-theme="light"]) .highlight .nn { color: #71adff; text-decoration: underline } /* Name.Namespace */ +body:not([data-theme="light"]) .highlight .nx { color: #d0d0d0 } /* Name.Other */ +body:not([data-theme="light"]) .highlight .py { color: #d0d0d0 } /* Name.Property */ +body:not([data-theme="light"]) .highlight .nt { color: #6ebf26; font-weight: bold } /* Name.Tag */ +body:not([data-theme="light"]) .highlight .nv { color: #40ffff } /* Name.Variable */ +body:not([data-theme="light"]) .highlight .ow { color: #6ebf26; font-weight: bold } /* Operator.Word */ +body:not([data-theme="light"]) .highlight .pm { color: #d0d0d0 } /* Punctuation.Marker */ +body:not([data-theme="light"]) .highlight .w { color: #666666 } /* Text.Whitespace */ +body:not([data-theme="light"]) .highlight .mb { color: #51b2fd } /* Literal.Number.Bin */ +body:not([data-theme="light"]) .highlight .mf { color: #51b2fd } /* Literal.Number.Float */ +body:not([data-theme="light"]) .highlight .mh { color: #51b2fd } /* Literal.Number.Hex */ +body:not([data-theme="light"]) .highlight .mi { color: #51b2fd } /* Literal.Number.Integer */ +body:not([data-theme="light"]) .highlight .mo { color: #51b2fd } /* Literal.Number.Oct */ +body:not([data-theme="light"]) .highlight .sa { color: #ed9d13 } /* Literal.String.Affix */ +body:not([data-theme="light"]) .highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */ +body:not([data-theme="light"]) .highlight .sc { color: #ed9d13 } /* Literal.String.Char */ +body:not([data-theme="light"]) .highlight .dl { color: #ed9d13 } /* Literal.String.Delimiter */ +body:not([data-theme="light"]) .highlight .sd { color: #ed9d13 } /* Literal.String.Doc */ +body:not([data-theme="light"]) .highlight .s2 { color: #ed9d13 } /* Literal.String.Double */ +body:not([data-theme="light"]) .highlight .se { color: #ed9d13 } /* Literal.String.Escape */ +body:not([data-theme="light"]) .highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */ +body:not([data-theme="light"]) .highlight .si { color: #ed9d13 } /* Literal.String.Interpol */ +body:not([data-theme="light"]) .highlight .sx { color: #ffa500 } /* Literal.String.Other */ +body:not([data-theme="light"]) .highlight .sr { color: #ed9d13 } /* Literal.String.Regex */ +body:not([data-theme="light"]) .highlight .s1 { color: #ed9d13 } /* Literal.String.Single */ +body:not([data-theme="light"]) .highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */ +body:not([data-theme="light"]) .highlight .bp { color: #2fbccd } /* Name.Builtin.Pseudo */ +body:not([data-theme="light"]) .highlight .fm { color: #71adff } /* Name.Function.Magic */ +body:not([data-theme="light"]) .highlight .vc { color: #40ffff } /* Name.Variable.Class */ +body:not([data-theme="light"]) .highlight .vg { color: #40ffff } /* Name.Variable.Global */ +body:not([data-theme="light"]) .highlight .vi { color: #40ffff } /* Name.Variable.Instance */ +body:not([data-theme="light"]) .highlight .vm { color: #40ffff } /* Name.Variable.Magic */ +body:not([data-theme="light"]) .highlight .il { color: #51b2fd } /* Literal.Number.Integer.Long */ +} +} \ No newline at end of file diff --git a/_static/scripts/furo-extensions.js b/_static/scripts/furo-extensions.js new file mode 100644 index 0000000..e69de29 diff --git a/_static/scripts/furo.js b/_static/scripts/furo.js new file mode 100644 index 0000000..0abb2af --- /dev/null +++ b/_static/scripts/furo.js @@ -0,0 +1,3 @@ +/*! For license information please see furo.js.LICENSE.txt */ +(()=>{var t={856:function(t,e,n){var o,r;r=void 0!==n.g?n.g:"undefined"!=typeof window?window:this,o=function(){return function(t){"use strict";var e={navClass:"active",contentClass:"active",nested:!1,nestedClass:"active",offset:0,reflow:!1,events:!0},n=function(t,e,n){if(n.settings.events){var o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n});e.dispatchEvent(o)}},o=function(t){var e=0;if(t.offsetParent)for(;t;)e+=t.offsetTop,t=t.offsetParent;return e>=0?e:0},r=function(t){t&&t.sort((function(t,e){return o(t.content)=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},l=function(t,e){var n=t[t.length-1];if(function(t,e){return!(!s()||!c(t.content,e,!0))}(n,e))return n;for(var o=t.length-1;o>=0;o--)if(c(t[o].content,e))return t[o]},a=function(t,e){if(e.nested&&t.parentNode){var n=t.parentNode.closest("li");n&&(n.classList.remove(e.nestedClass),a(n,e))}},i=function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.remove(e.navClass),t.content.classList.remove(e.contentClass),a(o,e),n("gumshoeDeactivate",o,{link:t.nav,content:t.content,settings:e}))}},u=function(t,e){if(e.nested){var n=t.parentNode.closest("li");n&&(n.classList.add(e.nestedClass),u(n,e))}};return function(o,c){var s,a,d,f,m,v={setup:function(){s=document.querySelectorAll(o),a=[],Array.prototype.forEach.call(s,(function(t){var e=document.getElementById(decodeURIComponent(t.hash.substr(1)));e&&a.push({nav:t,content:e})})),r(a)},detect:function(){var t=l(a,m);t?d&&t.content===d.content||(i(d,m),function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.add(e.navClass),t.content.classList.add(e.contentClass),u(o,e),n("gumshoeActivate",o,{link:t.nav,content:t.content,settings:e}))}}(t,m),d=t):d&&(i(d,m),d=null)}},h=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame(v.detect)},g=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame((function(){r(a),v.detect()}))};return v.destroy=function(){d&&i(d,m),t.removeEventListener("scroll",h,!1),m.reflow&&t.removeEventListener("resize",g,!1),a=null,s=null,d=null,f=null,m=null},m=function(){var t={};return Array.prototype.forEach.call(arguments,(function(e){for(var n in e){if(!e.hasOwnProperty(n))return;t[n]=e[n]}})),t}(e,c||{}),v.setup(),v.detect(),t.addEventListener("scroll",h,!1),m.reflow&&t.addEventListener("resize",g,!1),v}}(r)}.apply(e,[]),void 0===o||(t.exports=o)}},e={};function n(o){var r=e[o];if(void 0!==r)return r.exports;var c=e[o]={exports:{}};return t[o].call(c.exports,c,c.exports,n),c.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{"use strict";var t=n(856),e=n.n(t),o=null,r=null,c=document.documentElement.scrollTop;const s=64;function l(){const t=localStorage.getItem("theme")||"auto";var e;"light"!==(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"auto"===t?"light":"light"==t?"dark":"auto":"auto"===t?"dark":"dark"==t?"light":"auto")&&"dark"!==e&&"auto"!==e&&(console.error(`Got invalid theme mode: ${e}. Resetting to auto.`),e="auto"),document.body.dataset.theme=e,localStorage.setItem("theme",e),console.log(`Changed to ${e} mode.`)}function a(){!function(){const t=document.getElementsByClassName("theme-toggle");Array.from(t).forEach((t=>{t.addEventListener("click",l)}))}(),function(){let t=0,e=!1;window.addEventListener("scroll",(function(n){t=window.scrollY,e||(window.requestAnimationFrame((function(){var n;(function(t){const e=Math.floor(r.getBoundingClientRect().top);console.log(`headerTop: ${e}`),0==e&&t!=e?r.classList.add("scrolled"):r.classList.remove("scrolled")})(n=t),function(t){tc&&document.documentElement.classList.remove("show-back-to-top"),c=t}(n),function(t){null!==o&&(0==t?o.scrollTo(0,0):Math.ceil(t)>=Math.floor(document.documentElement.scrollHeight-window.innerHeight)?o.scrollTo(0,o.scrollHeight):document.querySelector(".scroll-current"))}(n),e=!1})),e=!0)})),window.scroll()}(),null!==o&&new(e())(".toc-tree a",{reflow:!0,recursive:!0,navClass:"scroll-current",offset:()=>{let t=parseFloat(getComputedStyle(document.documentElement).fontSize);return r.getBoundingClientRect().height+2.5*t+1}})}document.addEventListener("DOMContentLoaded",(function(){document.body.parentNode.classList.remove("no-js"),r=document.querySelector("header"),o=document.querySelector(".toc-scroll"),a()}))})()})(); +//# sourceMappingURL=furo.js.map \ No newline at end of file diff --git a/_static/scripts/furo.js.LICENSE.txt b/_static/scripts/furo.js.LICENSE.txt new file mode 100644 index 0000000..1632189 --- /dev/null +++ b/_static/scripts/furo.js.LICENSE.txt @@ -0,0 +1,7 @@ +/*! + * gumshoejs v5.1.2 (patched by @pradyunsg) + * A simple, framework-agnostic scrollspy script. + * (c) 2019 Chris Ferdinandi + * MIT License + * http://github.com/cferdinandi/gumshoe + */ diff --git a/_static/scripts/furo.js.map b/_static/scripts/furo.js.map new file mode 100644 index 0000000..80ea12b --- /dev/null +++ b/_static/scripts/furo.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scripts/furo.js","mappings":";iCAAA,MAQWA,SAWS,IAAX,EAAAC,EACH,EAAAA,EACkB,oBAAXC,OACLA,OACAC,KAbO,EAAF,WACP,OAaJ,SAAUD,GACR,aAMA,IAAIE,EAAW,CAEbC,SAAU,SACVC,aAAc,SAGdC,QAAQ,EACRC,YAAa,SAGbC,OAAQ,EACRC,QAAQ,EAGRC,QAAQ,GA6BNC,EAAY,SAAUC,EAAMC,EAAMC,GAEpC,GAAKA,EAAOC,SAASL,OAArB,CAGA,IAAIM,EAAQ,IAAIC,YAAYL,EAAM,CAChCM,SAAS,EACTC,YAAY,EACZL,OAAQA,IAIVD,EAAKO,cAAcJ,EAVgB,CAWrC,EAOIK,EAAe,SAAUR,GAC3B,IAAIS,EAAW,EACf,GAAIT,EAAKU,aACP,KAAOV,GACLS,GAAYT,EAAKW,UACjBX,EAAOA,EAAKU,aAGhB,OAAOD,GAAY,EAAIA,EAAW,CACpC,EAMIG,EAAe,SAAUC,GACvBA,GACFA,EAASC,MAAK,SAAUC,EAAOC,GAG7B,OAFcR,EAAaO,EAAME,SACnBT,EAAaQ,EAAMC,UACF,EACxB,CACT,GAEJ,EAwCIC,EAAW,SAAUlB,EAAME,EAAUiB,GACvC,IAAIC,EAASpB,EAAKqB,wBACd1B,EAnCU,SAAUO,GAExB,MAA+B,mBAApBA,EAASP,OACX2B,WAAWpB,EAASP,UAItB2B,WAAWpB,EAASP,OAC7B,CA2Be4B,CAAUrB,GACvB,OAAIiB,EAEAK,SAASJ,EAAOD,OAAQ,KACvB/B,EAAOqC,aAAeC,SAASC,gBAAgBC,cAG7CJ,SAASJ,EAAOS,IAAK,KAAOlC,CACrC,EAMImC,EAAa,WACf,OACEC,KAAKC,KAAK5C,EAAOqC,YAAcrC,EAAO6C,cAnCjCF,KAAKG,IACVR,SAASS,KAAKC,aACdV,SAASC,gBAAgBS,aACzBV,SAASS,KAAKE,aACdX,SAASC,gBAAgBU,aACzBX,SAASS,KAAKP,aACdF,SAASC,gBAAgBC,aAkC7B,EAmBIU,EAAY,SAAUzB,EAAUX,GAClC,IAAIqC,EAAO1B,EAASA,EAAS2B,OAAS,GACtC,GAbgB,SAAUC,EAAMvC,GAChC,SAAI4B,MAAgBZ,EAASuB,EAAKxB,QAASf,GAAU,GAEvD,CAUMwC,CAAYH,EAAMrC,GAAW,OAAOqC,EACxC,IAAK,IAAII,EAAI9B,EAAS2B,OAAS,EAAGG,GAAK,EAAGA,IACxC,GAAIzB,EAASL,EAAS8B,GAAG1B,QAASf,GAAW,OAAOW,EAAS8B,EAEjE,EAOIC,EAAmB,SAAUC,EAAK3C,GAEpC,GAAKA,EAAST,QAAWoD,EAAIC,WAA7B,CAGA,IAAIC,EAAKF,EAAIC,WAAWE,QAAQ,MAC3BD,IAGLA,EAAGE,UAAUC,OAAOhD,EAASR,aAG7BkD,EAAiBG,EAAI7C,GAV0B,CAWjD,EAOIiD,EAAa,SAAUC,EAAOlD,GAEhC,GAAKkD,EAAL,CAGA,IAAIL,EAAKK,EAAMP,IAAIG,QAAQ,MACtBD,IAGLA,EAAGE,UAAUC,OAAOhD,EAASX,UAC7B6D,EAAMnC,QAAQgC,UAAUC,OAAOhD,EAASV,cAGxCoD,EAAiBG,EAAI7C,GAGrBJ,EAAU,oBAAqBiD,EAAI,CACjCM,KAAMD,EAAMP,IACZ5B,QAASmC,EAAMnC,QACff,SAAUA,IAjBM,CAmBpB,EAOIoD,EAAiB,SAAUT,EAAK3C,GAElC,GAAKA,EAAST,OAAd,CAGA,IAAIsD,EAAKF,EAAIC,WAAWE,QAAQ,MAC3BD,IAGLA,EAAGE,UAAUM,IAAIrD,EAASR,aAG1B4D,EAAeP,EAAI7C,GAVS,CAW9B,EA6LA,OA1JkB,SAAUsD,EAAUC,GAKpC,IACIC,EAAU7C,EAAU8C,EAASC,EAAS1D,EADtC2D,EAAa,CAUjBA,MAAmB,WAEjBH,EAAWhC,SAASoC,iBAAiBN,GAGrC3C,EAAW,GAGXkD,MAAMC,UAAUC,QAAQC,KAAKR,GAAU,SAAUjB,GAE/C,IAAIxB,EAAUS,SAASyC,eACrBC,mBAAmB3B,EAAK4B,KAAKC,OAAO,KAEjCrD,GAGLJ,EAAS0D,KAAK,CACZ1B,IAAKJ,EACLxB,QAASA,GAEb,IAGAL,EAAaC,EACf,EAKAgD,OAAoB,WAElB,IAAIW,EAASlC,EAAUzB,EAAUX,GAG5BsE,EASDb,GAAWa,EAAOvD,UAAY0C,EAAQ1C,UAG1CkC,EAAWQ,EAASzD,GAzFT,SAAUkD,EAAOlD,GAE9B,GAAKkD,EAAL,CAGA,IAAIL,EAAKK,EAAMP,IAAIG,QAAQ,MACtBD,IAGLA,EAAGE,UAAUM,IAAIrD,EAASX,UAC1B6D,EAAMnC,QAAQgC,UAAUM,IAAIrD,EAASV,cAGrC8D,EAAeP,EAAI7C,GAGnBJ,EAAU,kBAAmBiD,EAAI,CAC/BM,KAAMD,EAAMP,IACZ5B,QAASmC,EAAMnC,QACff,SAAUA,IAjBM,CAmBpB,CAqEIuE,CAASD,EAAQtE,GAGjByD,EAAUa,GAfJb,IACFR,EAAWQ,EAASzD,GACpByD,EAAU,KAchB,GAMIe,EAAgB,SAAUvE,GAExByD,GACFxE,EAAOuF,qBAAqBf,GAI9BA,EAAUxE,EAAOwF,sBAAsBf,EAAWgB,OACpD,EAMIC,EAAgB,SAAU3E,GAExByD,GACFxE,EAAOuF,qBAAqBf,GAI9BA,EAAUxE,EAAOwF,uBAAsB,WACrChE,EAAaC,GACbgD,EAAWgB,QACb,GACF,EAkDA,OA7CAhB,EAAWkB,QAAU,WAEfpB,GACFR,EAAWQ,EAASzD,GAItBd,EAAO4F,oBAAoB,SAAUN,GAAe,GAChDxE,EAASN,QACXR,EAAO4F,oBAAoB,SAAUF,GAAe,GAItDjE,EAAW,KACX6C,EAAW,KACXC,EAAU,KACVC,EAAU,KACV1D,EAAW,IACb,EAOEA,EA3XS,WACX,IAAI+E,EAAS,CAAC,EAOd,OANAlB,MAAMC,UAAUC,QAAQC,KAAKgB,WAAW,SAAUC,GAChD,IAAK,IAAIC,KAAOD,EAAK,CACnB,IAAKA,EAAIE,eAAeD,GAAM,OAC9BH,EAAOG,GAAOD,EAAIC,EACpB,CACF,IACOH,CACT,CAkXeK,CAAOhG,EAAUmE,GAAW,CAAC,GAGxCI,EAAW0B,QAGX1B,EAAWgB,SAGXzF,EAAOoG,iBAAiB,SAAUd,GAAe,GAC7CxE,EAASN,QACXR,EAAOoG,iBAAiB,SAAUV,GAAe,GAS9CjB,CACT,CAOF,CArcW4B,CAAQvG,EAChB,UAFM,SAEN,uBCXDwG,EAA2B,CAAC,EAGhC,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBE,IAAjBD,EACH,OAAOA,EAAaE,QAGrB,IAAIC,EAASN,EAAyBE,GAAY,CAGjDG,QAAS,CAAC,GAOX,OAHAE,EAAoBL,GAAU1B,KAAK8B,EAAOD,QAASC,EAAQA,EAAOD,QAASJ,GAGpEK,EAAOD,OACf,CCrBAJ,EAAoBO,EAAKF,IACxB,IAAIG,EAASH,GAAUA,EAAOI,WAC7B,IAAOJ,EAAiB,QACxB,IAAM,EAEP,OADAL,EAAoBU,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,CAAM,ECLdR,EAAoBU,EAAI,CAACN,EAASQ,KACjC,IAAI,IAAInB,KAAOmB,EACXZ,EAAoBa,EAAED,EAAYnB,KAASO,EAAoBa,EAAET,EAASX,IAC5EqB,OAAOC,eAAeX,EAASX,EAAK,CAAEuB,YAAY,EAAMC,IAAKL,EAAWnB,IAE1E,ECNDO,EAAoBxG,EAAI,WACvB,GAA0B,iBAAf0H,WAAyB,OAAOA,WAC3C,IACC,OAAOxH,MAAQ,IAAIyH,SAAS,cAAb,EAChB,CAAE,MAAOC,GACR,GAAsB,iBAAX3H,OAAqB,OAAOA,MACxC,CACA,CAPuB,GCAxBuG,EAAoBa,EAAI,CAACrB,EAAK6B,IAAUP,OAAOzC,UAAUqB,eAAenB,KAAKiB,EAAK6B,4CCK9EC,EAAY,KACZC,EAAS,KACTC,EAAgBzF,SAASC,gBAAgByF,UAC7C,MAAMC,EAAmB,GA8EzB,SAASC,IACP,MAAMC,EAAeC,aAAaC,QAAQ,UAAY,OAZxD,IAAkBC,EACH,WADGA,EAaItI,OAAOuI,WAAW,gCAAgCC,QAI/C,SAAjBL,EACO,QACgB,SAAhBA,EACA,OAEA,OAIU,SAAjBA,EACO,OACgB,QAAhBA,EACA,QAEA,SA9BoB,SAATG,GAA4B,SAATA,IACzCG,QAAQC,MAAM,2BAA2BJ,yBACzCA,EAAO,QAGThG,SAASS,KAAK4F,QAAQC,MAAQN,EAC9BF,aAAaS,QAAQ,QAASP,GAC9BG,QAAQK,IAAI,cAAcR,UA0B5B,CAkDA,SAASnC,KART,WAEE,MAAM4C,EAAUzG,SAAS0G,uBAAuB,gBAChDrE,MAAMsE,KAAKF,GAASlE,SAASqE,IAC3BA,EAAI9C,iBAAiB,QAAS8B,EAAe,GAEjD,CAGEiB,GA9CF,WAEE,IAAIC,EAA6B,EAC7BC,GAAU,EAEdrJ,OAAOoG,iBAAiB,UAAU,SAAUuB,GAC1CyB,EAA6BpJ,OAAOsJ,QAE/BD,IACHrJ,OAAOwF,uBAAsB,WAzDnC,IAAuB+D,GAxDvB,SAAgCA,GAC9B,MAAMC,EAAY7G,KAAK8G,MAAM3B,EAAO7F,wBAAwBQ,KAE5DgG,QAAQK,IAAI,cAAcU,KACT,GAAbA,GAAkBD,GAAaC,EACjC1B,EAAOjE,UAAUM,IAAI,YAErB2D,EAAOjE,UAAUC,OAAO,WAE5B,EAgDE4F,CADqBH,EA0DDH,GAvGtB,SAAmCG,GAC7BA,EAAYtB,EACd3F,SAASC,gBAAgBsB,UAAUC,OAAO,oBAEtCyF,EAAYxB,EACdzF,SAASC,gBAAgBsB,UAAUM,IAAI,oBAC9BoF,EAAYxB,GACrBzF,SAASC,gBAAgBsB,UAAUC,OAAO,oBAG9CiE,EAAgBwB,CAClB,CAoCEI,CAA0BJ,GAlC5B,SAA6BA,GACT,OAAd1B,IAKa,GAAb0B,EACF1B,EAAU+B,SAAS,EAAG,GAGtBjH,KAAKC,KAAK2G,IACV5G,KAAK8G,MAAMnH,SAASC,gBAAgBS,aAAehD,OAAOqC,aAE1DwF,EAAU+B,SAAS,EAAG/B,EAAU7E,cAGhBV,SAASuH,cAAc,mBAc3C,CAKEC,CAAoBP,GAwDdF,GAAU,CACZ,IAEAA,GAAU,EAEd,IACArJ,OAAO+J,QACT,CA6BEC,GA1BkB,OAAdnC,GAKJ,IAAI,IAAJ,CAAY,cAAe,CACzBrH,QAAQ,EACRyJ,WAAW,EACX9J,SAAU,iBACVI,OAAQ,KACN,IAAI2J,EAAMhI,WAAWiI,iBAAiB7H,SAASC,iBAAiB6H,UAChE,OAAOtC,EAAO7F,wBAAwBoI,OAAS,IAAMH,EAAM,CAAC,GAiBlE,CAcA5H,SAAS8D,iBAAiB,oBAT1B,WACE9D,SAASS,KAAKW,WAAWG,UAAUC,OAAO,SAE1CgE,EAASxF,SAASuH,cAAc,UAChChC,EAAYvF,SAASuH,cAAc,eAEnC1D,GACF","sources":["webpack:///./src/furo/assets/scripts/gumshoe-patched.js","webpack:///webpack/bootstrap","webpack:///webpack/runtime/compat get default export","webpack:///webpack/runtime/define property getters","webpack:///webpack/runtime/global","webpack:///webpack/runtime/hasOwnProperty shorthand","webpack:///./src/furo/assets/scripts/furo.js"],"sourcesContent":["/*!\n * gumshoejs v5.1.2 (patched by @pradyunsg)\n * A simple, framework-agnostic scrollspy script.\n * (c) 2019 Chris Ferdinandi\n * MIT License\n * http://github.com/cferdinandi/gumshoe\n */\n\n(function (root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define([], function () {\n return factory(root);\n });\n } else if (typeof exports === \"object\") {\n module.exports = factory(root);\n } else {\n root.Gumshoe = factory(root);\n }\n})(\n typeof global !== \"undefined\"\n ? global\n : typeof window !== \"undefined\"\n ? window\n : this,\n function (window) {\n \"use strict\";\n\n //\n // Defaults\n //\n\n var defaults = {\n // Active classes\n navClass: \"active\",\n contentClass: \"active\",\n\n // Nested navigation\n nested: false,\n nestedClass: \"active\",\n\n // Offset & reflow\n offset: 0,\n reflow: false,\n\n // Event support\n events: true,\n };\n\n //\n // Methods\n //\n\n /**\n * Merge two or more objects together.\n * @param {Object} objects The objects to merge together\n * @returns {Object} Merged values of defaults and options\n */\n var extend = function () {\n var merged = {};\n Array.prototype.forEach.call(arguments, function (obj) {\n for (var key in obj) {\n if (!obj.hasOwnProperty(key)) return;\n merged[key] = obj[key];\n }\n });\n return merged;\n };\n\n /**\n * Emit a custom event\n * @param {String} type The event type\n * @param {Node} elem The element to attach the event to\n * @param {Object} detail Any details to pass along with the event\n */\n var emitEvent = function (type, elem, detail) {\n // Make sure events are enabled\n if (!detail.settings.events) return;\n\n // Create a new event\n var event = new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n detail: detail,\n });\n\n // Dispatch the event\n elem.dispatchEvent(event);\n };\n\n /**\n * Get an element's distance from the top of the Document.\n * @param {Node} elem The element\n * @return {Number} Distance from the top in pixels\n */\n var getOffsetTop = function (elem) {\n var location = 0;\n if (elem.offsetParent) {\n while (elem) {\n location += elem.offsetTop;\n elem = elem.offsetParent;\n }\n }\n return location >= 0 ? location : 0;\n };\n\n /**\n * Sort content from first to last in the DOM\n * @param {Array} contents The content areas\n */\n var sortContents = function (contents) {\n if (contents) {\n contents.sort(function (item1, item2) {\n var offset1 = getOffsetTop(item1.content);\n var offset2 = getOffsetTop(item2.content);\n if (offset1 < offset2) return -1;\n return 1;\n });\n }\n };\n\n /**\n * Get the offset to use for calculating position\n * @param {Object} settings The settings for this instantiation\n * @return {Float} The number of pixels to offset the calculations\n */\n var getOffset = function (settings) {\n // if the offset is a function run it\n if (typeof settings.offset === \"function\") {\n return parseFloat(settings.offset());\n }\n\n // Otherwise, return it as-is\n return parseFloat(settings.offset);\n };\n\n /**\n * Get the document element's height\n * @private\n * @returns {Number}\n */\n var getDocumentHeight = function () {\n return Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight,\n document.body.offsetHeight,\n document.documentElement.offsetHeight,\n document.body.clientHeight,\n document.documentElement.clientHeight,\n );\n };\n\n /**\n * Determine if an element is in view\n * @param {Node} elem The element\n * @param {Object} settings The settings for this instantiation\n * @param {Boolean} bottom If true, check if element is above bottom of viewport instead\n * @return {Boolean} Returns true if element is in the viewport\n */\n var isInView = function (elem, settings, bottom) {\n var bounds = elem.getBoundingClientRect();\n var offset = getOffset(settings);\n if (bottom) {\n return (\n parseInt(bounds.bottom, 10) <\n (window.innerHeight || document.documentElement.clientHeight)\n );\n }\n return parseInt(bounds.top, 10) <= offset;\n };\n\n /**\n * Check if at the bottom of the viewport\n * @return {Boolean} If true, page is at the bottom of the viewport\n */\n var isAtBottom = function () {\n if (\n Math.ceil(window.innerHeight + window.pageYOffset) >=\n getDocumentHeight()\n )\n return true;\n return false;\n };\n\n /**\n * Check if the last item should be used (even if not at the top of the page)\n * @param {Object} item The last item\n * @param {Object} settings The settings for this instantiation\n * @return {Boolean} If true, use the last item\n */\n var useLastItem = function (item, settings) {\n if (isAtBottom() && isInView(item.content, settings, true)) return true;\n return false;\n };\n\n /**\n * Get the active content\n * @param {Array} contents The content areas\n * @param {Object} settings The settings for this instantiation\n * @return {Object} The content area and matching navigation link\n */\n var getActive = function (contents, settings) {\n var last = contents[contents.length - 1];\n if (useLastItem(last, settings)) return last;\n for (var i = contents.length - 1; i >= 0; i--) {\n if (isInView(contents[i].content, settings)) return contents[i];\n }\n };\n\n /**\n * Deactivate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var deactivateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested || !nav.parentNode) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Remove the active class\n li.classList.remove(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n deactivateNested(li, settings);\n };\n\n /**\n * Deactivate a nav and content area\n * @param {Object} items The nav item and content to deactivate\n * @param {Object} settings The settings for this instantiation\n */\n var deactivate = function (items, settings) {\n // Make sure there are items to deactivate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Remove the active class from the nav and content\n li.classList.remove(settings.navClass);\n items.content.classList.remove(settings.contentClass);\n\n // Deactivate any parent navs in a nested navigation\n deactivateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeDeactivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Activate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var activateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Add the active class\n li.classList.add(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n activateNested(li, settings);\n };\n\n /**\n * Activate a nav and content area\n * @param {Object} items The nav item and content to activate\n * @param {Object} settings The settings for this instantiation\n */\n var activate = function (items, settings) {\n // Make sure there are items to activate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Add the active class to the nav and content\n li.classList.add(settings.navClass);\n items.content.classList.add(settings.contentClass);\n\n // Activate any parent navs in a nested navigation\n activateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeActivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Create the Constructor object\n * @param {String} selector The selector to use for navigation items\n * @param {Object} options User options and settings\n */\n var Constructor = function (selector, options) {\n //\n // Variables\n //\n\n var publicAPIs = {};\n var navItems, contents, current, timeout, settings;\n\n //\n // Methods\n //\n\n /**\n * Set variables from DOM elements\n */\n publicAPIs.setup = function () {\n // Get all nav items\n navItems = document.querySelectorAll(selector);\n\n // Create contents array\n contents = [];\n\n // Loop through each item, get it's matching content, and push to the array\n Array.prototype.forEach.call(navItems, function (item) {\n // Get the content for the nav item\n var content = document.getElementById(\n decodeURIComponent(item.hash.substr(1)),\n );\n if (!content) return;\n\n // Push to the contents array\n contents.push({\n nav: item,\n content: content,\n });\n });\n\n // Sort contents by the order they appear in the DOM\n sortContents(contents);\n };\n\n /**\n * Detect which content is currently active\n */\n publicAPIs.detect = function () {\n // Get the active content\n var active = getActive(contents, settings);\n\n // if there's no active content, deactivate and bail\n if (!active) {\n if (current) {\n deactivate(current, settings);\n current = null;\n }\n return;\n }\n\n // If the active content is the one currently active, do nothing\n if (current && active.content === current.content) return;\n\n // Deactivate the current content and activate the new content\n deactivate(current, settings);\n activate(active, settings);\n\n // Update the currently active content\n current = active;\n };\n\n /**\n * Detect the active content on scroll\n * Debounced for performance\n */\n var scrollHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(publicAPIs.detect);\n };\n\n /**\n * Update content sorting on resize\n * Debounced for performance\n */\n var resizeHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(function () {\n sortContents(contents);\n publicAPIs.detect();\n });\n };\n\n /**\n * Destroy the current instantiation\n */\n publicAPIs.destroy = function () {\n // Undo DOM changes\n if (current) {\n deactivate(current, settings);\n }\n\n // Remove event listeners\n window.removeEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.removeEventListener(\"resize\", resizeHandler, false);\n }\n\n // Reset variables\n contents = null;\n navItems = null;\n current = null;\n timeout = null;\n settings = null;\n };\n\n /**\n * Initialize the current instantiation\n */\n var init = function () {\n // Merge user options into defaults\n settings = extend(defaults, options || {});\n\n // Setup variables based on the current DOM\n publicAPIs.setup();\n\n // Find the currently active content\n publicAPIs.detect();\n\n // Setup event listeners\n window.addEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.addEventListener(\"resize\", resizeHandler, false);\n }\n };\n\n //\n // Initialize and return the public APIs\n //\n\n init();\n return publicAPIs;\n };\n\n //\n // Return the Constructor\n //\n\n return Constructor;\n },\n);\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import Gumshoe from \"./gumshoe-patched.js\";\n\n////////////////////////////////////////////////////////////////////////////////\n// Scroll Handling\n////////////////////////////////////////////////////////////////////////////////\nvar tocScroll = null;\nvar header = null;\nvar lastScrollTop = document.documentElement.scrollTop;\nconst GO_TO_TOP_OFFSET = 64;\n\nfunction scrollHandlerForHeader(positionY) {\n const headerTop = Math.floor(header.getBoundingClientRect().top);\n\n console.log(`headerTop: ${headerTop}`);\n if (headerTop == 0 && positionY != headerTop) {\n header.classList.add(\"scrolled\");\n } else {\n header.classList.remove(\"scrolled\");\n }\n}\n\nfunction scrollHandlerForBackToTop(positionY) {\n if (positionY < GO_TO_TOP_OFFSET) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n } else {\n if (positionY < lastScrollTop) {\n document.documentElement.classList.add(\"show-back-to-top\");\n } else if (positionY > lastScrollTop) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n }\n }\n lastScrollTop = positionY;\n}\n\nfunction scrollHandlerForTOC(positionY) {\n if (tocScroll === null) {\n return;\n }\n\n // top of page.\n if (positionY == 0) {\n tocScroll.scrollTo(0, 0);\n } else if (\n // bottom of page.\n Math.ceil(positionY) >=\n Math.floor(document.documentElement.scrollHeight - window.innerHeight)\n ) {\n tocScroll.scrollTo(0, tocScroll.scrollHeight);\n } else {\n // somewhere in the middle.\n const current = document.querySelector(\".scroll-current\");\n if (current == null) {\n return;\n }\n\n // https://github.com/pypa/pip/issues/9159 This breaks scroll behaviours.\n // // scroll the currently \"active\" heading in toc, into view.\n // const rect = current.getBoundingClientRect();\n // if (0 > rect.top) {\n // current.scrollIntoView(true); // the argument is \"alignTop\"\n // } else if (rect.bottom > window.innerHeight) {\n // current.scrollIntoView(false);\n // }\n }\n}\n\nfunction scrollHandler(positionY) {\n scrollHandlerForHeader(positionY);\n scrollHandlerForBackToTop(positionY);\n scrollHandlerForTOC(positionY);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Theme Toggle\n////////////////////////////////////////////////////////////////////////////////\nfunction setTheme(mode) {\n if (mode !== \"light\" && mode !== \"dark\" && mode !== \"auto\") {\n console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`);\n mode = \"auto\";\n }\n\n document.body.dataset.theme = mode;\n localStorage.setItem(\"theme\", mode);\n console.log(`Changed to ${mode} mode.`);\n}\n\nfunction cycleThemeOnce() {\n const currentTheme = localStorage.getItem(\"theme\") || \"auto\";\n const prefersDark = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n\n if (prefersDark) {\n // Auto (dark) -> Light -> Dark\n if (currentTheme === \"auto\") {\n setTheme(\"light\");\n } else if (currentTheme == \"light\") {\n setTheme(\"dark\");\n } else {\n setTheme(\"auto\");\n }\n } else {\n // Auto (light) -> Dark -> Light\n if (currentTheme === \"auto\") {\n setTheme(\"dark\");\n } else if (currentTheme == \"dark\") {\n setTheme(\"light\");\n } else {\n setTheme(\"auto\");\n }\n }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Setup\n////////////////////////////////////////////////////////////////////////////////\nfunction setupScrollHandler() {\n // Taken from https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event\n let last_known_scroll_position = 0;\n let ticking = false;\n\n window.addEventListener(\"scroll\", function (e) {\n last_known_scroll_position = window.scrollY;\n\n if (!ticking) {\n window.requestAnimationFrame(function () {\n scrollHandler(last_known_scroll_position);\n ticking = false;\n });\n\n ticking = true;\n }\n });\n window.scroll();\n}\n\nfunction setupScrollSpy() {\n if (tocScroll === null) {\n return;\n }\n\n // Scrollspy -- highlight table on contents, based on scroll\n new Gumshoe(\".toc-tree a\", {\n reflow: true,\n recursive: true,\n navClass: \"scroll-current\",\n offset: () => {\n let rem = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return header.getBoundingClientRect().height + 2.5 * rem + 1;\n },\n });\n}\n\nfunction setupTheme() {\n // Attach event handlers for toggling themes\n const buttons = document.getElementsByClassName(\"theme-toggle\");\n Array.from(buttons).forEach((btn) => {\n btn.addEventListener(\"click\", cycleThemeOnce);\n });\n}\n\nfunction setup() {\n setupTheme();\n setupScrollHandler();\n setupScrollSpy();\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Main entrypoint\n////////////////////////////////////////////////////////////////////////////////\nfunction main() {\n document.body.parentNode.classList.remove(\"no-js\");\n\n header = document.querySelector(\"header\");\n tocScroll = document.querySelector(\".toc-scroll\");\n\n setup();\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", main);\n"],"names":["root","g","window","this","defaults","navClass","contentClass","nested","nestedClass","offset","reflow","events","emitEvent","type","elem","detail","settings","event","CustomEvent","bubbles","cancelable","dispatchEvent","getOffsetTop","location","offsetParent","offsetTop","sortContents","contents","sort","item1","item2","content","isInView","bottom","bounds","getBoundingClientRect","parseFloat","getOffset","parseInt","innerHeight","document","documentElement","clientHeight","top","isAtBottom","Math","ceil","pageYOffset","max","body","scrollHeight","offsetHeight","getActive","last","length","item","useLastItem","i","deactivateNested","nav","parentNode","li","closest","classList","remove","deactivate","items","link","activateNested","add","selector","options","navItems","current","timeout","publicAPIs","querySelectorAll","Array","prototype","forEach","call","getElementById","decodeURIComponent","hash","substr","push","active","activate","scrollHandler","cancelAnimationFrame","requestAnimationFrame","detect","resizeHandler","destroy","removeEventListener","merged","arguments","obj","key","hasOwnProperty","extend","setup","addEventListener","factory","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","n","getter","__esModule","d","a","definition","o","Object","defineProperty","enumerable","get","globalThis","Function","e","prop","tocScroll","header","lastScrollTop","scrollTop","GO_TO_TOP_OFFSET","cycleThemeOnce","currentTheme","localStorage","getItem","mode","matchMedia","matches","console","error","dataset","theme","setItem","log","buttons","getElementsByClassName","from","btn","setupTheme","last_known_scroll_position","ticking","scrollY","positionY","headerTop","floor","scrollHandlerForHeader","scrollHandlerForBackToTop","scrollTo","querySelector","scrollHandlerForTOC","scroll","setupScrollHandler","recursive","rem","getComputedStyle","fontSize","height"],"sourceRoot":""} \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 0000000..2c774d1 --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,632 @@ +/* + * Sphinx JavaScript utilities for the full-text search. + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename, kind] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename, kind] = item; + + let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + SearchResultKind.title, + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + SearchResultKind.object, + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + SearchResultKind.text, + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/skeleton.css b/_static/skeleton.css new file mode 100644 index 0000000..467c878 --- /dev/null +++ b/_static/skeleton.css @@ -0,0 +1,296 @@ +/* Some sane resets. */ +html { + height: 100%; +} + +body { + margin: 0; + min-height: 100%; +} + +/* All the flexbox magic! */ +body, +.sb-announcement, +.sb-content, +.sb-main, +.sb-container, +.sb-container__inner, +.sb-article-container, +.sb-footer-content, +.sb-header, +.sb-header-secondary, +.sb-footer { + display: flex; +} + +/* These order things vertically */ +body, +.sb-main, +.sb-article-container { + flex-direction: column; +} + +/* Put elements in the center */ +.sb-header, +.sb-header-secondary, +.sb-container, +.sb-content, +.sb-footer, +.sb-footer-content { + justify-content: center; +} +/* Put elements at the ends */ +.sb-article-container { + justify-content: space-between; +} + +/* These elements grow. */ +.sb-main, +.sb-content, +.sb-container, +article { + flex-grow: 1; +} + +/* Because padding making this wider is not fun */ +article { + box-sizing: border-box; +} + +/* The announcements element should never be wider than the page. */ +.sb-announcement { + max-width: 100%; +} + +.sb-sidebar-primary, +.sb-sidebar-secondary { + flex-shrink: 0; + width: 17rem; +} + +.sb-announcement__inner { + justify-content: center; + + box-sizing: border-box; + height: 3rem; + + overflow-x: auto; + white-space: nowrap; +} + +/* Sidebars, with checkbox-based toggle */ +.sb-sidebar-primary, +.sb-sidebar-secondary { + position: fixed; + height: 100%; + top: 0; +} + +.sb-sidebar-primary { + left: -17rem; + transition: left 250ms ease-in-out; +} +.sb-sidebar-secondary { + right: -17rem; + transition: right 250ms ease-in-out; +} + +.sb-sidebar-toggle { + display: none; +} +.sb-sidebar-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + + transition: width 0ms ease 250ms, height 0ms ease 250ms, opacity 250ms ease; + + opacity: 0; + background-color: rgba(0, 0, 0, 0.54); +} + +#sb-sidebar-toggle--primary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--primary"], +#sb-sidebar-toggle--secondary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--secondary"] { + width: 100%; + height: 100%; + opacity: 1; + transition: width 0ms ease, height 0ms ease, opacity 250ms ease; +} + +#sb-sidebar-toggle--primary:checked ~ .sb-container .sb-sidebar-primary { + left: 0; +} +#sb-sidebar-toggle--secondary:checked ~ .sb-container .sb-sidebar-secondary { + right: 0; +} + +/* Full-width mode */ +.drop-secondary-sidebar-for-full-width-content + .hide-when-secondary-sidebar-shown { + display: none !important; +} +.drop-secondary-sidebar-for-full-width-content .sb-sidebar-secondary { + display: none !important; +} + +/* Mobile views */ +.sb-page-width { + width: 100%; +} + +.sb-article-container, +.sb-footer-content__inner, +.drop-secondary-sidebar-for-full-width-content .sb-article, +.drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 100vw; +} + +.sb-article, +.match-content-width { + padding: 0 1rem; + box-sizing: border-box; +} + +@media (min-width: 32rem) { + .sb-article, + .match-content-width { + padding: 0 2rem; + } +} + +/* Tablet views */ +@media (min-width: 42rem) { + .sb-article-container { + width: auto; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 42rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 46rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 46rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 50rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 50rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Tablet views */ +@media (min-width: 59rem) { + .sb-sidebar-secondary { + position: static; + } + .hide-when-secondary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 63rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 67rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Desktop views */ +@media (min-width: 76rem) { + .sb-sidebar-primary { + position: static; + } + .hide-when-primary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} + +/* Full desktop views */ +@media (min-width: 80rem) { + .sb-article, + .match-content-width { + width: 46rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } +} + +@media (min-width: 84rem) { + .sb-article, + .match-content-width { + width: 50rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } +} + +@media (min-width: 88rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-page-width { + width: 88rem; + } +} diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/_static/styles/furo-extensions.css b/_static/styles/furo-extensions.css new file mode 100644 index 0000000..8229587 --- /dev/null +++ b/_static/styles/furo-extensions.css @@ -0,0 +1,2 @@ +#furo-sidebar-ad-placement{padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)}#furo-sidebar-ad-placement .ethical-sidebar{background:var(--color-background-secondary);border:none;box-shadow:none}#furo-sidebar-ad-placement .ethical-sidebar:hover{background:var(--color-background-hover)}#furo-sidebar-ad-placement .ethical-sidebar a{color:var(--color-foreground-primary)}#furo-sidebar-ad-placement .ethical-callout a{color:var(--color-foreground-secondary)!important}#furo-readthedocs-versions{background:transparent;display:block;position:static;width:100%}#furo-readthedocs-versions .rst-versions{background:#1a1c1e}#furo-readthedocs-versions .rst-current-version{background:var(--color-sidebar-item-background);cursor:unset}#furo-readthedocs-versions .rst-current-version:hover{background:var(--color-sidebar-item-background)}#furo-readthedocs-versions .rst-current-version .fa-book{color:var(--color-foreground-primary)}#furo-readthedocs-versions>.rst-other-versions{padding:0}#furo-readthedocs-versions>.rst-other-versions small{opacity:1}#furo-readthedocs-versions .injected .rst-versions{position:unset}#furo-readthedocs-versions:focus-within,#furo-readthedocs-versions:hover{box-shadow:0 0 0 1px var(--color-sidebar-background-border)}#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:hover .rst-current-version{background:#1a1c1e;font-size:inherit;height:auto;line-height:inherit;padding:12px;text-align:right}#furo-readthedocs-versions:focus-within .rst-current-version .fa-book,#furo-readthedocs-versions:hover .rst-current-version .fa-book{color:#fff;float:left}#furo-readthedocs-versions:focus-within .fa-caret-down,#furo-readthedocs-versions:hover .fa-caret-down{display:none}#furo-readthedocs-versions:focus-within .injected,#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:focus-within .rst-other-versions,#furo-readthedocs-versions:hover .injected,#furo-readthedocs-versions:hover .rst-current-version,#furo-readthedocs-versions:hover .rst-other-versions{display:block}#furo-readthedocs-versions:focus-within>.rst-current-version,#furo-readthedocs-versions:hover>.rst-current-version{display:none}.highlight:hover button.copybtn{color:var(--color-code-foreground)}.highlight button.copybtn{align-items:center;background-color:var(--color-code-background);border:none;color:var(--color-background-item);cursor:pointer;height:1.25em;right:.5rem;top:.625rem;transition:color .3s,opacity .3s;width:1.25em}.highlight button.copybtn:hover{background-color:var(--color-code-background);color:var(--color-brand-content)}.highlight button.copybtn:after{background-color:transparent;color:var(--color-code-foreground);display:none}.highlight button.copybtn.success{color:#22863a;transition:color 0ms}.highlight button.copybtn.success:after{display:block}.highlight button.copybtn svg{padding:0}body{--sd-color-primary:var(--color-brand-primary);--sd-color-primary-highlight:var(--color-brand-content);--sd-color-primary-text:var(--color-background-primary);--sd-color-shadow:rgba(0,0,0,.05);--sd-color-card-border:var(--color-card-border);--sd-color-card-border-hover:var(--color-brand-content);--sd-color-card-background:var(--color-card-background);--sd-color-card-text:var(--color-foreground-primary);--sd-color-card-header:var(--color-card-marginals-background);--sd-color-card-footer:var(--color-card-marginals-background);--sd-color-tabs-label-active:var(--color-brand-content);--sd-color-tabs-label-hover:var(--color-foreground-muted);--sd-color-tabs-label-inactive:var(--color-foreground-muted);--sd-color-tabs-underline-active:var(--color-brand-content);--sd-color-tabs-underline-hover:var(--color-foreground-border);--sd-color-tabs-underline-inactive:var(--color-background-border);--sd-color-tabs-overline:var(--color-background-border);--sd-color-tabs-underline:var(--color-background-border)}.sd-tab-content{box-shadow:0 -2px var(--sd-color-tabs-overline),0 1px var(--sd-color-tabs-underline)}.sd-card{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)}.sd-shadow-sm{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-md{box-shadow:0 .3rem .75rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-lg{box-shadow:0 .6rem 1.5rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-card-hover:hover{transform:none}.sd-cards-carousel{gap:.25rem;padding:.25rem}body{--tabs--label-text:var(--color-foreground-muted);--tabs--label-text--hover:var(--color-foreground-muted);--tabs--label-text--active:var(--color-brand-content);--tabs--label-text--active--hover:var(--color-brand-content);--tabs--label-background:transparent;--tabs--label-background--hover:transparent;--tabs--label-background--active:transparent;--tabs--label-background--active--hover:transparent;--tabs--padding-x:0.25em;--tabs--margin-x:1em;--tabs--border:var(--color-background-border);--tabs--label-border:transparent;--tabs--label-border--hover:var(--color-foreground-muted);--tabs--label-border--active:var(--color-brand-content);--tabs--label-border--active--hover:var(--color-brand-content)}[role=main] .container{max-width:none;padding-left:0;padding-right:0}.shadow.docutils{border:none;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)!important}.sphinx-bs .card{background-color:var(--color-background-secondary);color:var(--color-foreground)} +/*# sourceMappingURL=furo-extensions.css.map*/ \ No newline at end of file diff --git a/_static/styles/furo-extensions.css.map b/_static/styles/furo-extensions.css.map new file mode 100644 index 0000000..c26eac7 --- /dev/null +++ b/_static/styles/furo-extensions.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo-extensions.css","mappings":"AAGA,2BACE,oFACA,4CAKE,6CAHA,YACA,eAEA,CACA,kDACE,yCAEF,8CACE,sCAEJ,8CACE,kDAEJ,2BAGE,uBACA,cAHA,gBACA,UAEA,CAGA,yCACE,mBAEF,gDAEE,gDADA,YACA,CACA,sDACE,gDACF,yDACE,sCAEJ,+CACE,UACA,qDACE,UAGF,mDACE,eAEJ,yEAEE,4DAEA,mHASE,mBAPA,kBAEA,YADA,oBAGA,aADA,gBAIA,CAEA,qIAEE,WADA,UACA,CAEJ,uGACE,aAEF,iUAGE,cAEF,mHACE,aC1EJ,gCACE,mCAEF,0BAEE,mBAUA,8CACA,YAFA,mCAKA,eAZA,cAIA,YADA,YAYA,iCAdA,YAcA,CAEA,gCAEE,8CADA,gCACA,CAEF,gCAGE,6BADA,mCADA,YAEA,CAEF,kCAEE,cADA,oBACA,CACA,wCACE,cAEJ,8BACE,UCzCN,KAEE,6CAA8C,CAC9C,uDAAwD,CACxD,uDAAwD,CAGxD,iCAAsC,CAGtC,+CAAgD,CAChD,uDAAwD,CACxD,uDAAwD,CACxD,oDAAqD,CACrD,6DAA8D,CAC9D,6DAA8D,CAG9D,uDAAwD,CACxD,yDAA0D,CAC1D,4DAA6D,CAC7D,2DAA4D,CAC5D,8DAA+D,CAC/D,iEAAkE,CAClE,uDAAwD,CACxD,wDAAyD,CAG3D,gBACE,qFAGF,SACE,6EAEF,cACE,uFAEF,cACE,uFAEF,cACE,uFAGF,qBACE,eAEF,mBACE,WACA,eChDF,KACE,gDAAiD,CACjD,uDAAwD,CACxD,qDAAsD,CACtD,4DAA6D,CAC7D,oCAAqC,CACrC,2CAA4C,CAC5C,4CAA6C,CAC7C,mDAAoD,CACpD,wBAAyB,CACzB,oBAAqB,CACrB,6CAA8C,CAC9C,gCAAiC,CACjC,yDAA0D,CAC1D,uDAAwD,CACxD,8DAA+D,CCbjE,uBACE,eACA,eACA,gBAGF,iBACE,YACA,+EAGF,iBACE,mDACA","sources":["webpack:///./src/furo/assets/styles/extensions/_readthedocs.sass","webpack:///./src/furo/assets/styles/extensions/_copybutton.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-design.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-inline-tabs.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-panels.sass"],"sourcesContent":["// This file contains the styles used for tweaking how ReadTheDoc's embedded\n// contents would show up inside the theme.\n\n#furo-sidebar-ad-placement\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n .ethical-sidebar\n // Remove the border and box-shadow.\n border: none\n box-shadow: none\n // Manage the background colors.\n background: var(--color-background-secondary)\n &:hover\n background: var(--color-background-hover)\n // Ensure the text is legible.\n a\n color: var(--color-foreground-primary)\n\n .ethical-callout a\n color: var(--color-foreground-secondary) !important\n\n#furo-readthedocs-versions\n position: static\n width: 100%\n background: transparent\n display: block\n\n // Make the background color fit with the theme's aesthetic.\n .rst-versions\n background: rgb(26, 28, 30)\n\n .rst-current-version\n cursor: unset\n background: var(--color-sidebar-item-background)\n &:hover\n background: var(--color-sidebar-item-background)\n .fa-book\n color: var(--color-foreground-primary)\n\n > .rst-other-versions\n padding: 0\n small\n opacity: 1\n\n .injected\n .rst-versions\n position: unset\n\n &:hover,\n &:focus-within\n box-shadow: 0 0 0 1px var(--color-sidebar-background-border)\n\n .rst-current-version\n // Undo the tweaks done in RTD's CSS\n font-size: inherit\n line-height: inherit\n height: auto\n text-align: right\n padding: 12px\n\n // Match the rest of the body\n background: #1a1c1e\n\n .fa-book\n float: left\n color: white\n\n .fa-caret-down\n display: none\n\n .rst-current-version,\n .rst-other-versions,\n .injected\n display: block\n\n > .rst-current-version\n display: none\n",".highlight\n &:hover button.copybtn\n color: var(--color-code-foreground)\n\n button.copybtn\n // Align things correctly\n align-items: center\n\n height: 1.25em\n width: 1.25em\n\n top: 0.625rem // $code-spacing-vertical\n right: 0.5rem\n\n // Make it look better\n color: var(--color-background-item)\n background-color: var(--color-code-background)\n border: none\n\n // Change to cursor to make it obvious that you can click on it\n cursor: pointer\n\n // Transition smoothly, for aesthetics\n transition: color 300ms, opacity 300ms\n\n &:hover\n color: var(--color-brand-content)\n background-color: var(--color-code-background)\n\n &::after\n display: none\n color: var(--color-code-foreground)\n background-color: transparent\n\n &.success\n transition: color 0ms\n color: #22863a\n &::after\n display: block\n\n svg\n padding: 0\n","body\n // Colors\n --sd-color-primary: var(--color-brand-primary)\n --sd-color-primary-highlight: var(--color-brand-content)\n --sd-color-primary-text: var(--color-background-primary)\n\n // Shadows\n --sd-color-shadow: rgba(0, 0, 0, 0.05)\n\n // Cards\n --sd-color-card-border: var(--color-card-border)\n --sd-color-card-border-hover: var(--color-brand-content)\n --sd-color-card-background: var(--color-card-background)\n --sd-color-card-text: var(--color-foreground-primary)\n --sd-color-card-header: var(--color-card-marginals-background)\n --sd-color-card-footer: var(--color-card-marginals-background)\n\n // Tabs\n --sd-color-tabs-label-active: var(--color-brand-content)\n --sd-color-tabs-label-hover: var(--color-foreground-muted)\n --sd-color-tabs-label-inactive: var(--color-foreground-muted)\n --sd-color-tabs-underline-active: var(--color-brand-content)\n --sd-color-tabs-underline-hover: var(--color-foreground-border)\n --sd-color-tabs-underline-inactive: var(--color-background-border)\n --sd-color-tabs-overline: var(--color-background-border)\n --sd-color-tabs-underline: var(--color-background-border)\n\n// Tabs\n.sd-tab-content\n box-shadow: 0 -2px var(--sd-color-tabs-overline), 0 1px var(--sd-color-tabs-underline)\n\n// Shadows\n.sd-card // Have a shadow by default\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n.sd-shadow-sm\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-md\n box-shadow: 0 0.3rem 0.75rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-lg\n box-shadow: 0 0.6rem 1.5rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Cards\n.sd-card-hover:hover // Don't change scale on hover\n transform: none\n\n.sd-cards-carousel // Have a bit of gap in the carousel by default\n gap: 0.25rem\n padding: 0.25rem\n","// This file contains styles to tweak sphinx-inline-tabs to work well with Furo.\n\nbody\n --tabs--label-text: var(--color-foreground-muted)\n --tabs--label-text--hover: var(--color-foreground-muted)\n --tabs--label-text--active: var(--color-brand-content)\n --tabs--label-text--active--hover: var(--color-brand-content)\n --tabs--label-background: transparent\n --tabs--label-background--hover: transparent\n --tabs--label-background--active: transparent\n --tabs--label-background--active--hover: transparent\n --tabs--padding-x: 0.25em\n --tabs--margin-x: 1em\n --tabs--border: var(--color-background-border)\n --tabs--label-border: transparent\n --tabs--label-border--hover: var(--color-foreground-muted)\n --tabs--label-border--active: var(--color-brand-content)\n --tabs--label-border--active--hover: var(--color-brand-content)\n","// This file contains styles to tweak sphinx-panels to work well with Furo.\n\n// sphinx-panels includes Bootstrap 4, which uses .container which can conflict\n// with docutils' `.. container::` directive.\n[role=\"main\"] .container\n max-width: initial\n padding-left: initial\n padding-right: initial\n\n// Make the panels look nicer!\n.shadow.docutils\n border: none\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Make panel colors respond to dark mode\n.sphinx-bs .card\n background-color: var(--color-background-secondary)\n color: var(--color-foreground)\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/_static/styles/furo.css b/_static/styles/furo.css new file mode 100644 index 0000000..05a56b1 --- /dev/null +++ b/_static/styles/furo.css @@ -0,0 +1,2 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}@media print{.content-icon-container,.headerlink,.mobile-header,.related-pages{display:none!important}.highlight{border:.1pt solid var(--color-foreground-border)}a,blockquote,dl,ol,p,pre,table,ul{page-break-inside:avoid}caption,figure,h1,h2,h3,h4,h5,h6,img{page-break-after:avoid;page-break-inside:avoid}dl,ol,ul{page-break-before:avoid}}.visually-hidden{height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;clip:rect(0,0,0,0)!important;background:var(--color-background-primary);border:0!important;color:var(--color-foreground-primary);white-space:nowrap!important}:-moz-focusring{outline:auto}body{--font-stack:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;--font-stack--monospace:"SFMono-Regular",Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;--font-stack--headings:var(--font-stack);--font-size--normal:100%;--font-size--small:87.5%;--font-size--small--2:81.25%;--font-size--small--3:75%;--font-size--small--4:62.5%;--sidebar-caption-font-size:var(--font-size--small--2);--sidebar-item-font-size:var(--font-size--small);--sidebar-search-input-font-size:var(--font-size--small);--toc-font-size:var(--font-size--small--3);--toc-font-size--mobile:var(--font-size--normal);--toc-title-font-size:var(--font-size--small--4);--admonition-font-size:0.8125rem;--admonition-title-font-size:0.8125rem;--code-font-size:var(--font-size--small--2);--api-font-size:var(--font-size--small);--header-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*4);--header-padding:0.5rem;--sidebar-tree-space-above:1.5rem;--sidebar-caption-space-above:1rem;--sidebar-item-line-height:1rem;--sidebar-item-spacing-vertical:0.5rem;--sidebar-item-spacing-horizontal:1rem;--sidebar-item-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*2);--sidebar-expander-width:var(--sidebar-item-height);--sidebar-search-space-above:0.5rem;--sidebar-search-input-spacing-vertical:0.5rem;--sidebar-search-input-spacing-horizontal:0.5rem;--sidebar-search-input-height:1rem;--sidebar-search-icon-size:var(--sidebar-search-input-height);--toc-title-padding:0.25rem 0;--toc-spacing-vertical:1.5rem;--toc-spacing-horizontal:1.5rem;--toc-item-spacing-vertical:0.4rem;--toc-item-spacing-horizontal:1rem;--icon-search:url('data:image/svg+xml;charset=utf-8,');--icon-pencil:url('data:image/svg+xml;charset=utf-8,');--icon-abstract:url('data:image/svg+xml;charset=utf-8,');--icon-info:url('data:image/svg+xml;charset=utf-8,');--icon-flame:url('data:image/svg+xml;charset=utf-8,');--icon-question:url('data:image/svg+xml;charset=utf-8,');--icon-warning:url('data:image/svg+xml;charset=utf-8,');--icon-failure:url('data:image/svg+xml;charset=utf-8,');--icon-spark:url('data:image/svg+xml;charset=utf-8,');--color-admonition-title--caution:#ff9100;--color-admonition-title-background--caution:rgba(255,145,0,.2);--color-admonition-title--warning:#ff9100;--color-admonition-title-background--warning:rgba(255,145,0,.2);--color-admonition-title--danger:#ff5252;--color-admonition-title-background--danger:rgba(255,82,82,.2);--color-admonition-title--attention:#ff5252;--color-admonition-title-background--attention:rgba(255,82,82,.2);--color-admonition-title--error:#ff5252;--color-admonition-title-background--error:rgba(255,82,82,.2);--color-admonition-title--hint:#00c852;--color-admonition-title-background--hint:rgba(0,200,82,.2);--color-admonition-title--tip:#00c852;--color-admonition-title-background--tip:rgba(0,200,82,.2);--color-admonition-title--important:#00bfa5;--color-admonition-title-background--important:rgba(0,191,165,.2);--color-admonition-title--note:#00b0ff;--color-admonition-title-background--note:rgba(0,176,255,.2);--color-admonition-title--seealso:#448aff;--color-admonition-title-background--seealso:rgba(68,138,255,.2);--color-admonition-title--admonition-todo:grey;--color-admonition-title-background--admonition-todo:hsla(0,0%,50%,.2);--color-admonition-title:#651fff;--color-admonition-title-background:rgba(101,31,255,.2);--icon-admonition-default:var(--icon-abstract);--color-topic-title:#14b8a6;--color-topic-title-background:rgba(20,184,166,.2);--icon-topic-default:var(--icon-pencil);--color-problematic:#b30000;--color-foreground-primary:#000;--color-foreground-secondary:#5a5c63;--color-foreground-muted:#6b6f76;--color-foreground-border:#878787;--color-background-primary:#fff;--color-background-secondary:#f8f9fb;--color-background-hover:#efeff4;--color-background-hover--transparent:#efeff400;--color-background-border:#eeebee;--color-background-item:#ccc;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#0a4bff;--color-brand-content:#2757dd;--color-brand-visited:#872ee0;--color-api-background:var(--color-background-hover--transparent);--color-api-background-hover:var(--color-background-hover);--color-api-overall:var(--color-foreground-secondary);--color-api-name:var(--color-problematic);--color-api-pre-name:var(--color-problematic);--color-api-paren:var(--color-foreground-secondary);--color-api-keyword:var(--color-foreground-primary);--color-api-added:#21632c;--color-api-added-border:#38a84d;--color-api-changed:#046172;--color-api-changed-border:#06a1bc;--color-api-deprecated:#605706;--color-api-deprecated-border:#f0d90f;--color-api-removed:#b30000;--color-api-removed-border:#ff5c5c;--color-highlight-on-target:#ffc;--color-inline-code-background:var(--color-background-secondary);--color-highlighted-background:#def;--color-highlighted-text:var(--color-foreground-primary);--color-guilabel-background:#ddeeff80;--color-guilabel-border:#bedaf580;--color-guilabel-text:var(--color-foreground-primary);--color-admonition-background:transparent;--color-table-header-background:var(--color-background-secondary);--color-table-border:var(--color-background-border);--color-card-border:var(--color-background-secondary);--color-card-background:transparent;--color-card-marginals-background:var(--color-background-secondary);--color-header-background:var(--color-background-primary);--color-header-border:var(--color-background-border);--color-header-text:var(--color-foreground-primary);--color-sidebar-background:var(--color-background-secondary);--color-sidebar-background-border:var(--color-background-border);--color-sidebar-brand-text:var(--color-foreground-primary);--color-sidebar-caption-text:var(--color-foreground-muted);--color-sidebar-link-text:var(--color-foreground-secondary);--color-sidebar-link-text--top-level:var(--color-brand-primary);--color-sidebar-item-background:var(--color-sidebar-background);--color-sidebar-item-background--current:var( --color-sidebar-item-background );--color-sidebar-item-background--hover:linear-gradient(90deg,var(--color-background-hover--transparent) 0%,var(--color-background-hover) var(--sidebar-item-spacing-horizontal),var(--color-background-hover) 100%);--color-sidebar-item-expander-background:transparent;--color-sidebar-item-expander-background--hover:var( --color-background-hover );--color-sidebar-search-text:var(--color-foreground-primary);--color-sidebar-search-background:var(--color-background-secondary);--color-sidebar-search-background--focus:var(--color-background-primary);--color-sidebar-search-border:var(--color-background-border);--color-sidebar-search-icon:var(--color-foreground-muted);--color-toc-background:var(--color-background-primary);--color-toc-title-text:var(--color-foreground-muted);--color-toc-item-text:var(--color-foreground-secondary);--color-toc-item-text--hover:var(--color-foreground-primary);--color-toc-item-text--active:var(--color-brand-primary);--color-content-foreground:var(--color-foreground-primary);--color-content-background:transparent;--color-link:var(--color-brand-content);--color-link-underline:var(--color-background-border);--color-link--hover:var(--color-brand-content);--color-link-underline--hover:var(--color-foreground-border);--color-link--visited:var(--color-brand-visited);--color-link-underline--visited:var(--color-background-border);--color-link--visited--hover:var(--color-brand-visited);--color-link-underline--visited--hover:var(--color-foreground-border)}.only-light{display:block!important}html body .only-dark{display:none!important}@media not print{body[data-theme=dark]{--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body[data-theme=dark] .only-light{display:none!important}body[data-theme=dark] .only-dark{display:block!important}@media(prefers-color-scheme:dark){body:not([data-theme=light]){--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body:not([data-theme=light]) .only-light{display:none!important}body:not([data-theme=light]) .only-dark{display:block!important}}}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:block}@media(prefers-color-scheme:dark){body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-dark{display:block}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:none}}body[data-theme=dark] .theme-toggle svg.theme-icon-when-dark,body[data-theme=light] .theme-toggle svg.theme-icon-when-light{display:block}body{font-family:var(--font-stack)}code,kbd,pre,samp{font-family:var(--font-stack--monospace)}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}article{line-height:1.5}h1,h2,h3,h4,h5,h6{border-radius:.5rem;font-family:var(--font-stack--headings);font-weight:700;line-height:1.25;margin:.5rem -.5rem;padding-left:.5rem;padding-right:.5rem}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p{margin-top:0}h1{font-size:2.5em;margin-bottom:1rem}h1,h2{margin-top:1.75rem}h2{font-size:2em}h3{font-size:1.5em}h4{font-size:1.25em}h5{font-size:1.125em}h6{font-size:1em}small{font-size:80%;opacity:75%}p{margin-bottom:.75rem;margin-top:.5rem}hr.docutils{background-color:var(--color-background-border);border:0;height:1px;margin:2rem 0;padding:0}.centered{text-align:center}a{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}a:visited{color:var(--color-link--visited);text-decoration-color:var(--color-link-underline--visited)}a:visited:hover{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}a:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link{color:inherit}a.muted-link:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link:hover:visited{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}html{overflow-x:hidden;overflow-y:scroll;scroll-behavior:smooth}.sidebar-scroll,.toc-scroll,article[role=main] *{scrollbar-color:var(--color-foreground-border) transparent;scrollbar-width:thin}.sidebar-scroll::-webkit-scrollbar,.toc-scroll::-webkit-scrollbar,article[role=main] ::-webkit-scrollbar{height:.25rem;width:.25rem}.sidebar-scroll::-webkit-scrollbar-thumb,.toc-scroll::-webkit-scrollbar-thumb,article[role=main] ::-webkit-scrollbar-thumb{background-color:var(--color-foreground-border);border-radius:.125rem}body,html{height:100%}.skip-to-content,body,html{background:var(--color-background-primary);color:var(--color-foreground-primary)}.skip-to-content{border-radius:1rem;left:.25rem;padding:1rem;position:fixed;top:.25rem;transform:translateY(-200%);transition:transform .3s ease-in-out;z-index:40}.skip-to-content:focus-within{transform:translateY(0)}article{background:var(--color-content-background);color:var(--color-content-foreground);overflow-wrap:break-word}.page{display:flex;min-height:100%}.mobile-header{background-color:var(--color-header-background);border-bottom:1px solid var(--color-header-border);color:var(--color-header-text);display:none;height:var(--header-height);width:100%;z-index:10}.mobile-header.scrolled{border-bottom:none;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2)}.mobile-header .header-center a{color:var(--color-header-text);text-decoration:none}.main{display:flex;flex:1}.sidebar-drawer{background:var(--color-sidebar-background);border-right:1px solid var(--color-sidebar-background-border);box-sizing:border-box;display:flex;justify-content:flex-end;min-width:15em;width:calc(50% - 26em)}.sidebar-container,.toc-drawer{box-sizing:border-box;width:15em}.toc-drawer{background:var(--color-toc-background);padding-right:1rem}.sidebar-sticky,.toc-sticky{display:flex;flex-direction:column;height:min(100%,100vh);height:100vh;position:sticky;top:0}.sidebar-scroll,.toc-scroll{flex-grow:1;flex-shrink:1;overflow:auto;scroll-behavior:smooth}.content{display:flex;flex-direction:column;justify-content:space-between;padding:0 3em;width:46em}.icon{display:inline-block;height:1rem;width:1rem}.icon svg{height:100%;width:100%}.announcement{align-items:center;background-color:var(--color-announcement-background);color:var(--color-announcement-text);display:flex;height:var(--header-height);overflow-x:auto}.announcement+.page{min-height:calc(100% - var(--header-height))}.announcement-content{box-sizing:border-box;min-width:100%;padding:.5rem;text-align:center;white-space:nowrap}.announcement-content a{color:var(--color-announcement-text);text-decoration-color:var(--color-announcement-text)}.announcement-content a:hover{color:var(--color-announcement-text);text-decoration-color:var(--color-link--hover)}.no-js .theme-toggle-container{display:none}.theme-toggle-container{display:flex}.theme-toggle{background:transparent;border:none;cursor:pointer;display:flex;padding:0}.theme-toggle svg{color:var(--color-foreground-primary);display:none;height:1.25rem;width:1.25rem}.theme-toggle-header{align-items:center;display:flex;justify-content:center}.nav-overlay-icon,.toc-overlay-icon{cursor:pointer;display:none}.nav-overlay-icon .icon,.toc-overlay-icon .icon{color:var(--color-foreground-secondary);height:1.5rem;width:1.5rem}.nav-overlay-icon,.toc-header-icon{align-items:center;justify-content:center}.toc-content-icon{height:1.5rem;width:1.5rem}.content-icon-container{display:flex;float:right;gap:.5rem;margin-bottom:1rem;margin-left:1rem;margin-top:1.5rem}.content-icon-container .edit-this-page svg,.content-icon-container .view-this-page svg{color:inherit;height:1.25rem;width:1.25rem}.sidebar-toggle{display:none;position:absolute}.sidebar-toggle[name=__toc]{left:20px}.sidebar-toggle:checked{left:40px}.overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms,height 0ms,opacity .25s ease-out;width:0}.sidebar-overlay{z-index:20}.toc-overlay{z-index:40}.sidebar-drawer{transition:left .25s ease-in-out;z-index:30}.toc-drawer{transition:right .25s ease-in-out;z-index:50}#__navigation:checked~.sidebar-overlay{height:100%;opacity:1;width:100%}#__navigation:checked~.page .sidebar-drawer{left:0;top:0}#__toc:checked~.toc-overlay{height:100%;opacity:1;width:100%}#__toc:checked~.page .toc-drawer{right:0;top:0}.back-to-top{background:var(--color-background-primary);border-radius:1rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 1px 0 hsla(220,9%,46%,.502);display:none;font-size:.8125rem;left:0;margin-left:50%;padding:.5rem .75rem .5rem .5rem;position:fixed;text-decoration:none;top:1rem;transform:translateX(-50%);z-index:10}.back-to-top svg{height:1rem;width:1rem;fill:currentColor;display:inline-block}.back-to-top span{margin-left:.25rem}.show-back-to-top .back-to-top{align-items:center;display:flex}@media(min-width:97em){html{font-size:110%}}@media(max-width:82em){.toc-content-icon{display:flex}.toc-drawer{border-left:1px solid var(--color-background-muted);height:100vh;position:fixed;right:-15em;top:0}.toc-tree{border-left:none;font-size:var(--toc-font-size--mobile)}.sidebar-drawer{width:calc(50% - 18.5em)}}@media(max-width:67em){.content{margin-left:auto;margin-right:auto;padding:0 1em}}@media(max-width:63em){.nav-overlay-icon{display:flex}.sidebar-drawer{height:100vh;left:-15em;position:fixed;top:0;width:15em}.theme-toggle-header,.toc-header-icon{display:flex}.theme-toggle-content,.toc-content-icon{display:none}.mobile-header{align-items:center;display:flex;justify-content:space-between;position:sticky;top:0}.mobile-header .header-left,.mobile-header .header-right{display:flex;height:var(--header-height);padding:0 var(--header-padding)}.mobile-header .header-left label,.mobile-header .header-right label{height:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.nav-overlay-icon .icon,.theme-toggle svg{height:1.5rem;width:1.5rem}:target{scroll-margin-top:calc(var(--header-height) + 2.5rem)}.back-to-top{top:calc(var(--header-height) + .5rem)}.page{flex-direction:column;justify-content:center}}@media(max-width:48em){.content{overflow-x:auto;width:100%}}@media(max-width:46em){article[role=main] aside.sidebar{float:none;margin:1rem 0;width:100%}}.admonition,.topic{background:var(--color-admonition-background);border-radius:.2rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);font-size:var(--admonition-font-size);margin:1rem auto;overflow:hidden;padding:0 .5rem .5rem;page-break-inside:avoid}.admonition>:nth-child(2),.topic>:nth-child(2){margin-top:0}.admonition>:last-child,.topic>:last-child{margin-bottom:0}.admonition p.admonition-title,p.topic-title{font-size:var(--admonition-title-font-size);font-weight:500;line-height:1.3;margin:0 -.5rem .5rem;padding:.4rem .5rem .4rem 2rem;position:relative}.admonition p.admonition-title:before,p.topic-title:before{content:"";height:1rem;left:.5rem;position:absolute;width:1rem}p.admonition-title{background-color:var(--color-admonition-title-background)}p.admonition-title:before{background-color:var(--color-admonition-title);-webkit-mask-image:var(--icon-admonition-default);mask-image:var(--icon-admonition-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}p.topic-title{background-color:var(--color-topic-title-background)}p.topic-title:before{background-color:var(--color-topic-title);-webkit-mask-image:var(--icon-topic-default);mask-image:var(--icon-topic-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.admonition{border-left:.2rem solid var(--color-admonition-title)}.admonition.caution{border-left-color:var(--color-admonition-title--caution)}.admonition.caution>.admonition-title{background-color:var(--color-admonition-title-background--caution)}.admonition.caution>.admonition-title:before{background-color:var(--color-admonition-title--caution);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.warning{border-left-color:var(--color-admonition-title--warning)}.admonition.warning>.admonition-title{background-color:var(--color-admonition-title-background--warning)}.admonition.warning>.admonition-title:before{background-color:var(--color-admonition-title--warning);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.danger{border-left-color:var(--color-admonition-title--danger)}.admonition.danger>.admonition-title{background-color:var(--color-admonition-title-background--danger)}.admonition.danger>.admonition-title:before{background-color:var(--color-admonition-title--danger);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.attention{border-left-color:var(--color-admonition-title--attention)}.admonition.attention>.admonition-title{background-color:var(--color-admonition-title-background--attention)}.admonition.attention>.admonition-title:before{background-color:var(--color-admonition-title--attention);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.error{border-left-color:var(--color-admonition-title--error)}.admonition.error>.admonition-title{background-color:var(--color-admonition-title-background--error)}.admonition.error>.admonition-title:before{background-color:var(--color-admonition-title--error);-webkit-mask-image:var(--icon-failure);mask-image:var(--icon-failure)}.admonition.hint{border-left-color:var(--color-admonition-title--hint)}.admonition.hint>.admonition-title{background-color:var(--color-admonition-title-background--hint)}.admonition.hint>.admonition-title:before{background-color:var(--color-admonition-title--hint);-webkit-mask-image:var(--icon-question);mask-image:var(--icon-question)}.admonition.tip{border-left-color:var(--color-admonition-title--tip)}.admonition.tip>.admonition-title{background-color:var(--color-admonition-title-background--tip)}.admonition.tip>.admonition-title:before{background-color:var(--color-admonition-title--tip);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.important{border-left-color:var(--color-admonition-title--important)}.admonition.important>.admonition-title{background-color:var(--color-admonition-title-background--important)}.admonition.important>.admonition-title:before{background-color:var(--color-admonition-title--important);-webkit-mask-image:var(--icon-flame);mask-image:var(--icon-flame)}.admonition.note{border-left-color:var(--color-admonition-title--note)}.admonition.note>.admonition-title{background-color:var(--color-admonition-title-background--note)}.admonition.note>.admonition-title:before{background-color:var(--color-admonition-title--note);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition.seealso{border-left-color:var(--color-admonition-title--seealso)}.admonition.seealso>.admonition-title{background-color:var(--color-admonition-title-background--seealso)}.admonition.seealso>.admonition-title:before{background-color:var(--color-admonition-title--seealso);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.admonition-todo{border-left-color:var(--color-admonition-title--admonition-todo)}.admonition.admonition-todo>.admonition-title{background-color:var(--color-admonition-title-background--admonition-todo)}.admonition.admonition-todo>.admonition-title:before{background-color:var(--color-admonition-title--admonition-todo);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition-todo>.admonition-title{text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd{margin-left:2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:first-child{margin-top:.125rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list,dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:last-child{margin-bottom:.75rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list>dt{font-size:var(--font-size--small);text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd:empty{margin-bottom:.5rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul{margin-left:-1.2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p:nth-child(2){margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p+p:last-child:empty{margin-bottom:0;margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{color:var(--color-api-overall)}.sig:not(.sig-inline){background:var(--color-api-background);border-radius:.25rem;font-family:var(--font-stack--monospace);font-size:var(--api-font-size);font-weight:700;margin-left:-.25rem;margin-right:-.25rem;padding:.25rem .5rem .25rem 3em;text-indent:-2.5em;transition:background .1s ease-out}.sig:not(.sig-inline):hover{background:var(--color-api-background-hover)}.sig:not(.sig-inline) a.reference .viewcode-link{font-weight:400;width:4.25rem}em.property{font-style:normal}em.property:first-child{color:var(--color-api-keyword)}.sig-name{color:var(--color-api-name)}.sig-prename{color:var(--color-api-pre-name);font-weight:400}.sig-paren{color:var(--color-api-paren)}.sig-param{font-style:normal}div.deprecated,div.versionadded,div.versionchanged,div.versionremoved{border-left:.1875rem solid;border-radius:.125rem;padding-left:.75rem}div.deprecated p,div.versionadded p,div.versionchanged p,div.versionremoved p{margin-bottom:.125rem;margin-top:.125rem}div.versionadded{border-color:var(--color-api-added-border)}div.versionadded .versionmodified{color:var(--color-api-added)}div.versionchanged{border-color:var(--color-api-changed-border)}div.versionchanged .versionmodified{color:var(--color-api-changed)}div.deprecated{border-color:var(--color-api-deprecated-border)}div.deprecated .versionmodified{color:var(--color-api-deprecated)}div.versionremoved{border-color:var(--color-api-removed-border)}div.versionremoved .versionmodified{color:var(--color-api-removed)}.viewcode-back,.viewcode-link{float:right;text-align:right}.line-block{margin-bottom:.75rem;margin-top:.5rem}.line-block .line-block{margin-bottom:0;margin-top:0;padding-left:1rem}.code-block-caption,article p.caption,table>caption{font-size:var(--font-size--small);text-align:center}.toctree-wrapper.compound .caption,.toctree-wrapper.compound :not(.caption)>.caption-text{font-size:var(--font-size--small);margin-bottom:0;text-align:initial;text-transform:uppercase}.toctree-wrapper.compound>ul{margin-bottom:0;margin-top:0}.sig-inline,code.literal{background:var(--color-inline-code-background);border-radius:.2em;font-size:var(--font-size--small--2);padding:.1em .2em}pre.literal-block .sig-inline,pre.literal-block code.literal{font-size:inherit;padding:0}p .sig-inline,p code.literal{border:1px solid var(--color-background-border)}.sig-inline{font-family:var(--font-stack--monospace)}div[class*=" highlight-"],div[class^=highlight-]{display:flex;margin:1em 0}div[class*=" highlight-"] .table-wrapper,div[class^=highlight-] .table-wrapper,pre{margin:0;padding:0}pre{overflow:auto}article[role=main] .highlight pre{line-height:1.5}.highlight pre,pre.literal-block{font-size:var(--code-font-size);padding:.625rem .875rem}pre.literal-block{background-color:var(--color-code-background);border-radius:.2rem;color:var(--color-code-foreground);margin-bottom:1rem;margin-top:1rem}.highlight{border-radius:.2rem;width:100%}.highlight .gp,.highlight span.linenos{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.highlight .hll{display:block;margin-left:-.875rem;margin-right:-.875rem;padding-left:.875rem;padding-right:.875rem}.code-block-caption{background-color:var(--color-code-background);border-bottom:1px solid;border-radius:.25rem;border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:var(--color-background-border);color:var(--color-code-foreground);display:flex;font-weight:300;padding:.625rem .875rem}.code-block-caption+div[class]{margin-top:0}.code-block-caption+div[class] pre{border-top-left-radius:0;border-top-right-radius:0}.highlighttable{display:block;width:100%}.highlighttable tbody{display:block}.highlighttable tr{display:flex}.highlighttable td.linenos{background-color:var(--color-code-background);border-bottom-left-radius:.2rem;border-top-left-radius:.2rem;color:var(--color-code-foreground);padding:.625rem 0 .625rem .875rem}.highlighttable .linenodiv{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;font-size:var(--code-font-size);padding-right:.875rem}.highlighttable td.code{display:block;flex:1;overflow:hidden;padding:0}.highlighttable td.code .highlight{border-bottom-left-radius:0;border-top-left-radius:0}.highlight span.linenos{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;display:inline-block;margin-right:.875rem;padding-left:0;padding-right:.875rem}.footnote-reference{font-size:var(--font-size--small--4);vertical-align:super}dl.footnote.brackets{color:var(--color-foreground-secondary);display:grid;font-size:var(--font-size--small);grid-template-columns:max-content auto}dl.footnote.brackets dt{margin:0}dl.footnote.brackets dt>.fn-backref{margin-left:.25rem}dl.footnote.brackets dt:after{content:":"}dl.footnote.brackets dt .brackets:before{content:"["}dl.footnote.brackets dt .brackets:after{content:"]"}dl.footnote.brackets dd{margin:0;padding:0 1rem}aside.footnote{color:var(--color-foreground-secondary);font-size:var(--font-size--small)}aside.footnote>span,div.citation>span{float:left;font-weight:500;padding-right:.25rem}aside.footnote>:not(span),div.citation>p{margin-left:2rem}img{box-sizing:border-box;height:auto;max-width:100%}article .figure,article figure{border-radius:.2rem;margin:0}article .figure :last-child,article figure :last-child{margin-bottom:0}article .align-left{clear:left;float:left;margin:0 1rem 1rem}article .align-right{clear:right;float:right;margin:0 1rem 1rem}article .align-center,article .align-default{display:block;margin-left:auto;margin-right:auto;text-align:center}article table.align-default{display:table;text-align:initial}.domainindex-jumpbox,.genindex-jumpbox{border-bottom:1px solid var(--color-background-border);border-top:1px solid var(--color-background-border);padding:.25rem}.domainindex-section h2,.genindex-section h2{margin-bottom:.5rem;margin-top:.75rem}.domainindex-section ul,.genindex-section ul{margin-bottom:0;margin-top:0}ol,ul{margin-bottom:1rem;margin-top:1rem;padding-left:1.2rem}ol li>p:first-child,ul li>p:first-child{margin-bottom:.25rem;margin-top:.25rem}ol li>p:last-child,ul li>p:last-child{margin-top:.25rem}ol li>ol,ol li>ul,ul li>ol,ul li>ul{margin-bottom:.5rem;margin-top:.5rem}ol.arabic{list-style:decimal}ol.loweralpha{list-style:lower-alpha}ol.upperalpha{list-style:upper-alpha}ol.lowerroman{list-style:lower-roman}ol.upperroman{list-style:upper-roman}.simple li>ol,.simple li>ul,.toctree-wrapper li>ol,.toctree-wrapper li>ul{margin-bottom:0;margin-top:0}.field-list dt,.option-list dt,dl.footnote dt,dl.glossary dt,dl.simple dt,dl:not([class]) dt{font-weight:500;margin-top:.25rem}.field-list dt+dt,.option-list dt+dt,dl.footnote dt+dt,dl.glossary dt+dt,dl.simple dt+dt,dl:not([class]) dt+dt{margin-top:0}.field-list dt .classifier:before,.option-list dt .classifier:before,dl.footnote dt .classifier:before,dl.glossary dt .classifier:before,dl.simple dt .classifier:before,dl:not([class]) dt .classifier:before{content:":";margin-left:.2rem;margin-right:.2rem}.field-list dd ul,.field-list dd>p:first-child,.option-list dd ul,.option-list dd>p:first-child,dl.footnote dd ul,dl.footnote dd>p:first-child,dl.glossary dd ul,dl.glossary dd>p:first-child,dl.simple dd ul,dl.simple dd>p:first-child,dl:not([class]) dd ul,dl:not([class]) dd>p:first-child{margin-top:.125rem}.field-list dd ul,.option-list dd ul,dl.footnote dd ul,dl.glossary dd ul,dl.simple dd ul,dl:not([class]) dd ul{margin-bottom:.125rem}.math-wrapper{overflow-x:auto;width:100%}div.math{position:relative;text-align:center}div.math .headerlink,div.math:focus .headerlink{display:none}div.math:hover .headerlink{display:inline-block}div.math span.eqno{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);z-index:1}abbr[title]{cursor:help}.problematic{color:var(--color-problematic)}kbd:not(.compound){background-color:var(--color-background-secondary);border:1px solid var(--color-foreground-border);border-radius:.2rem;box-shadow:0 .0625rem 0 rgba(0,0,0,.2),inset 0 0 0 .125rem var(--color-background-primary);color:var(--color-foreground-primary);display:inline-block;font-size:var(--font-size--small--3);margin:0 .2rem;padding:0 .2rem;vertical-align:text-bottom}blockquote{background:var(--color-background-secondary);border-left:4px solid var(--color-background-border);margin-left:0;margin-right:0;padding:.5rem 1rem}blockquote .attribution{font-weight:600;text-align:right}blockquote.highlights,blockquote.pull-quote{font-size:1.25em}blockquote.epigraph,blockquote.pull-quote{border-left-width:0;border-radius:.5rem}blockquote.highlights{background:transparent;border-left-width:0}p .reference img{vertical-align:middle}p.rubric{font-size:1.125em;font-weight:700;line-height:1.25}dd p.rubric{font-size:var(--font-size--small);font-weight:inherit;line-height:inherit;text-transform:uppercase}article .sidebar{background-color:var(--color-background-secondary);border:1px solid var(--color-background-border);border-radius:.2rem;clear:right;float:right;margin-left:1rem;margin-right:0;width:30%}article .sidebar>*{padding-left:1rem;padding-right:1rem}article .sidebar>ol,article .sidebar>ul{padding-left:2.2rem}article .sidebar .sidebar-title{border-bottom:1px solid var(--color-background-border);font-weight:500;margin:0;padding:.5rem 1rem}[role=main] .table-wrapper.container{margin-bottom:.5rem;margin-top:1rem;overflow-x:auto;padding:.2rem .2rem .75rem;width:100%}table.docutils{border-collapse:collapse;border-radius:.2rem;border-spacing:0;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)}table.docutils th{background:var(--color-table-header-background)}table.docutils td,table.docutils th{border-bottom:1px solid var(--color-table-border);border-left:1px solid var(--color-table-border);border-right:1px solid var(--color-table-border);padding:0 .25rem}table.docutils td p,table.docutils th p{margin:.25rem}table.docutils td:first-child,table.docutils th:first-child{border-left:none}table.docutils td:last-child,table.docutils th:last-child{border-right:none}table.docutils td.text-left,table.docutils th.text-left{text-align:left}table.docutils td.text-right,table.docutils th.text-right{text-align:right}table.docutils td.text-center,table.docutils th.text-center{text-align:center}:target{scroll-margin-top:2.5rem}@media(max-width:67em){:target{scroll-margin-top:calc(2.5rem + var(--header-height))}section>span:target{scroll-margin-top:calc(2.8rem + var(--header-height))}}.headerlink{font-weight:100;-webkit-user-select:none;-moz-user-select:none;user-select:none}.code-block-caption>.headerlink,dl dt>.headerlink,figcaption p>.headerlink,h1>.headerlink,h2>.headerlink,h3>.headerlink,h4>.headerlink,h5>.headerlink,h6>.headerlink,p.caption>.headerlink,table>caption>.headerlink{margin-left:.5rem;visibility:hidden}.code-block-caption:hover>.headerlink,dl dt:hover>.headerlink,figcaption p:hover>.headerlink,h1:hover>.headerlink,h2:hover>.headerlink,h3:hover>.headerlink,h4:hover>.headerlink,h5:hover>.headerlink,h6:hover>.headerlink,p.caption:hover>.headerlink,table>caption:hover>.headerlink{visibility:visible}.code-block-caption>.toc-backref,dl dt>.toc-backref,figcaption p>.toc-backref,h1>.toc-backref,h2>.toc-backref,h3>.toc-backref,h4>.toc-backref,h5>.toc-backref,h6>.toc-backref,p.caption>.toc-backref,table>caption>.toc-backref{color:inherit;text-decoration-line:none}figure:hover>figcaption>p>.headerlink,table:hover>caption>.headerlink{visibility:visible}:target>h1:first-of-type,:target>h2:first-of-type,:target>h3:first-of-type,:target>h4:first-of-type,:target>h5:first-of-type,:target>h6:first-of-type,span:target~h1:first-of-type,span:target~h2:first-of-type,span:target~h3:first-of-type,span:target~h4:first-of-type,span:target~h5:first-of-type,span:target~h6:first-of-type{background-color:var(--color-highlight-on-target)}:target>h1:first-of-type code.literal,:target>h2:first-of-type code.literal,:target>h3:first-of-type code.literal,:target>h4:first-of-type code.literal,:target>h5:first-of-type code.literal,:target>h6:first-of-type code.literal,span:target~h1:first-of-type code.literal,span:target~h2:first-of-type code.literal,span:target~h3:first-of-type code.literal,span:target~h4:first-of-type code.literal,span:target~h5:first-of-type code.literal,span:target~h6:first-of-type code.literal{background-color:transparent}.literal-block-wrapper:target .code-block-caption,.this-will-duplicate-information-and-it-is-still-useful-here li :target,figure:target,table:target>caption{background-color:var(--color-highlight-on-target)}dt:target{background-color:var(--color-highlight-on-target)!important}.footnote-reference:target,.footnote>dt:target+dd{background-color:var(--color-highlight-on-target)}.guilabel{background-color:var(--color-guilabel-background);border:1px solid var(--color-guilabel-border);border-radius:.5em;color:var(--color-guilabel-text);font-size:.9em;padding:0 .3em}footer{display:flex;flex-direction:column;font-size:var(--font-size--small);margin-top:2rem}.bottom-of-page{align-items:center;border-top:1px solid var(--color-background-border);color:var(--color-foreground-secondary);display:flex;justify-content:space-between;line-height:1.5;margin-top:1rem;padding-bottom:1rem;padding-top:1rem}@media(max-width:46em){.bottom-of-page{flex-direction:column-reverse;gap:.25rem;text-align:center}}.bottom-of-page .left-details{font-size:var(--font-size--small)}.bottom-of-page .right-details{display:flex;flex-direction:column;gap:.25rem;text-align:right}.bottom-of-page .icons{display:flex;font-size:1rem;gap:.25rem;justify-content:flex-end}.bottom-of-page .icons a{text-decoration:none}.bottom-of-page .icons img,.bottom-of-page .icons svg{font-size:1.125rem;height:1em;width:1em}.related-pages a{align-items:center;display:flex;text-decoration:none}.related-pages a:hover .page-info .title{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}.related-pages a svg.furo-related-icon,.related-pages a svg.furo-related-icon>use{color:var(--color-foreground-border);flex-shrink:0;height:.75rem;margin:0 .5rem;width:.75rem}.related-pages a.next-page{clear:right;float:right;max-width:50%;text-align:right}.related-pages a.prev-page{clear:left;float:left;max-width:50%}.related-pages a.prev-page svg{transform:rotate(180deg)}.page-info{display:flex;flex-direction:column;overflow-wrap:anywhere}.next-page .page-info{align-items:flex-end}.page-info .context{align-items:center;color:var(--color-foreground-muted);display:flex;font-size:var(--font-size--small);padding-bottom:.1rem;text-decoration:none}ul.search{list-style:none;padding-left:0}ul.search li{border-bottom:1px solid var(--color-background-border);padding:1rem 0}[role=main] .highlighted{background-color:var(--color-highlighted-background);color:var(--color-highlighted-text)}.sidebar-brand{display:flex;flex-direction:column;flex-shrink:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none}.sidebar-brand-text{color:var(--color-sidebar-brand-text);font-size:1.5rem;overflow-wrap:break-word}.sidebar-brand-text,.sidebar-logo-container{margin:var(--sidebar-item-spacing-vertical) 0}.sidebar-logo{display:block;margin:0 auto;max-width:100%}.sidebar-search-container{align-items:center;background:var(--color-sidebar-search-background);display:flex;margin-top:var(--sidebar-search-space-above);position:relative}.sidebar-search-container:focus-within,.sidebar-search-container:hover{background:var(--color-sidebar-search-background--focus)}.sidebar-search-container:before{background-color:var(--color-sidebar-search-icon);content:"";height:var(--sidebar-search-icon-size);left:var(--sidebar-item-spacing-horizontal);-webkit-mask-image:var(--icon-search);mask-image:var(--icon-search);position:absolute;width:var(--sidebar-search-icon-size)}.sidebar-search{background:transparent;border:none;border-bottom:1px solid var(--color-sidebar-search-border);border-top:1px solid var(--color-sidebar-search-border);box-sizing:border-box;color:var(--color-sidebar-search-foreground);padding:var(--sidebar-search-input-spacing-vertical) var(--sidebar-search-input-spacing-horizontal) var(--sidebar-search-input-spacing-vertical) calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size));width:100%;z-index:10}.sidebar-search:focus{outline:none}.sidebar-search::-moz-placeholder{font-size:var(--sidebar-search-input-font-size)}.sidebar-search::placeholder{font-size:var(--sidebar-search-input-font-size)}#searchbox .highlight-link{margin:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0;text-align:center}#searchbox .highlight-link a{color:var(--color-sidebar-search-icon);font-size:var(--font-size--small--2)}.sidebar-tree{font-size:var(--sidebar-item-font-size);margin-bottom:var(--sidebar-item-spacing-vertical);margin-top:var(--sidebar-tree-space-above)}.sidebar-tree ul{display:flex;flex-direction:column;list-style:none;margin-bottom:0;margin-top:0;padding:0}.sidebar-tree li{margin:0;position:relative}.sidebar-tree li>ul{margin-left:var(--sidebar-item-spacing-horizontal)}.sidebar-tree .icon,.sidebar-tree .reference{color:var(--color-sidebar-link-text)}.sidebar-tree .reference{box-sizing:border-box;display:inline-block;height:100%;line-height:var(--sidebar-item-line-height);overflow-wrap:anywhere;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none;width:100%}.sidebar-tree .reference:hover{background:var(--color-sidebar-item-background--hover);color:var(--color-sidebar-link-text)}.sidebar-tree .reference.external:after{color:var(--color-sidebar-link-text);content:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23607D8B' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' viewBox='0 0 24 24'%3E%3Cpath stroke='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M11 7H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-5M10 14 20 4M15 4h5v5'/%3E%3C/svg%3E");margin:0 .25rem;vertical-align:middle}.sidebar-tree .current-page>.reference{font-weight:700}.sidebar-tree label{align-items:center;cursor:pointer;display:flex;height:var(--sidebar-item-height);justify-content:center;position:absolute;right:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--sidebar-expander-width)}.sidebar-tree .caption,.sidebar-tree :not(.caption)>.caption-text{color:var(--color-sidebar-caption-text);font-size:var(--sidebar-caption-font-size);font-weight:700;margin:var(--sidebar-caption-space-above) 0 0 0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-transform:uppercase}.sidebar-tree li.has-children>.reference{padding-right:var(--sidebar-expander-width)}.sidebar-tree .toctree-l1>.reference,.sidebar-tree .toctree-l1>label .icon{color:var(--color-sidebar-link-text--top-level)}.sidebar-tree label{background:var(--color-sidebar-item-expander-background)}.sidebar-tree label:hover{background:var(--color-sidebar-item-expander-background--hover)}.sidebar-tree .current>.reference{background:var(--color-sidebar-item-background--current)}.sidebar-tree .current>.reference:hover{background:var(--color-sidebar-item-background--hover)}.toctree-checkbox{display:none;position:absolute}.toctree-checkbox~ul{display:none}.toctree-checkbox~label .icon svg{transform:rotate(90deg)}.toctree-checkbox:checked~ul{display:block}.toctree-checkbox:checked~label .icon svg{transform:rotate(-90deg)}.toc-title-container{padding:var(--toc-title-padding);padding-top:var(--toc-spacing-vertical)}.toc-title{color:var(--color-toc-title-text);font-size:var(--toc-title-font-size);padding-left:var(--toc-spacing-horizontal);text-transform:uppercase}.no-toc{display:none}.toc-tree-container{padding-bottom:var(--toc-spacing-vertical)}.toc-tree{border-left:1px solid var(--color-background-border);font-size:var(--toc-font-size);line-height:1.3;padding-left:calc(var(--toc-spacing-horizontal) - var(--toc-item-spacing-horizontal))}.toc-tree>ul>li:first-child{padding-top:0}.toc-tree>ul>li:first-child>ul{padding-left:0}.toc-tree>ul>li:first-child>a{display:none}.toc-tree ul{list-style-type:none;margin-bottom:0;margin-top:0;padding-left:var(--toc-item-spacing-horizontal)}.toc-tree li{padding-top:var(--toc-item-spacing-vertical)}.toc-tree li.scroll-current>.reference{color:var(--color-toc-item-text--active);font-weight:700}.toc-tree a.reference{color:var(--color-toc-item-text);overflow-wrap:anywhere;text-decoration:none}.toc-scroll{max-height:100vh;overflow-y:scroll}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here){background:rgba(255,0,0,.25);color:var(--color-problematic)}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here):before{content:"ERROR: Adding a table of contents in Furo-based documentation is unnecessary, and does not work well with existing styling. Add a 'this-will-duplicate-information-and-it-is-still-useful-here' class, if you want an escape hatch."}.text-align\:left>p{text-align:left}.text-align\:center>p{text-align:center}.text-align\:right>p{text-align:right} +/*# sourceMappingURL=furo.css.map*/ \ No newline at end of file diff --git a/_static/styles/furo.css.map b/_static/styles/furo.css.map new file mode 100644 index 0000000..3ecc371 --- /dev/null +++ b/_static/styles/furo.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo.css","mappings":"AAAA,2EAA2E,CAU3E,KACE,gBAAiB,CACjB,6BACF,CASA,KACE,QACF,CAMA,KACE,aACF,CAOA,GACE,aAAc,CACd,cACF,CAUA,GACE,sBAAuB,CACvB,QAAS,CACT,gBACF,CAOA,IACE,+BAAiC,CACjC,aACF,CASA,EACE,4BACF,CAOA,YACE,kBAAmB,CACnB,yBAA0B,CAC1B,gCACF,CAMA,SAEE,kBACF,CAOA,cAGE,+BAAiC,CACjC,aACF,CAeA,QAEE,aAAc,CACd,aAAc,CACd,iBAAkB,CAClB,uBACF,CAEA,IACE,aACF,CAEA,IACE,SACF,CASA,IACE,iBACF,CAUA,sCAKE,mBAAoB,CACpB,cAAe,CACf,gBAAiB,CACjB,QACF,CAOA,aAEE,gBACF,CAOA,cAEE,mBACF,CAMA,gDAIE,yBACF,CAMA,wHAIE,iBAAkB,CAClB,SACF,CAMA,4GAIE,6BACF,CAMA,SACE,0BACF,CASA,OACE,qBAAsB,CACtB,aAAc,CACd,aAAc,CACd,cAAe,CACf,SAAU,CACV,kBACF,CAMA,SACE,uBACF,CAMA,SACE,aACF,CAOA,6BAEE,qBAAsB,CACtB,SACF,CAMA,kFAEE,WACF,CAOA,cACE,4BAA6B,CAC7B,mBACF,CAMA,yCACE,uBACF,CAOA,6BACE,yBAA0B,CAC1B,YACF,CASA,QACE,aACF,CAMA,QACE,iBACF,CAiBA,kBACE,YACF,CCvVA,aAcE,kEACE,uBAOF,WACE,iDAMF,kCACE,wBAEF,qCAEE,uBADA,uBACA,CAEF,SACE,wBAtBA,CCpBJ,iBAGE,qBAEA,sBACA,0BAFA,oBAHA,4BACA,oBAKA,6BAIA,2CAFA,mBACA,sCAFA,4BAGA,CAEF,gBACE,aCTF,KCGE,mHAEA,wGAEA,wCAAyC,CAEzC,wBAAyB,CACzB,wBAAyB,CACzB,4BAA6B,CAC7B,yBAA0B,CAC1B,2BAA4B,CAG5B,sDAAuD,CACvD,gDAAiD,CACjD,wDAAyD,CAGzD,0CAA2C,CAC3C,gDAAiD,CACjD,gDAAiD,CAKjD,gCAAiC,CACjC,sCAAuC,CAGvC,2CAA4C,CAG5C,uCAAwC,CCjCxC,+FAGA,uBAAwB,CAGxB,iCAAkC,CAClC,kCAAmC,CAEnC,+BAAgC,CAChC,sCAAuC,CACvC,sCAAuC,CACvC,qGAIA,mDAAoD,CAEpD,mCAAoC,CACpC,8CAA+C,CAC/C,gDAAiD,CACjD,kCAAmC,CACnC,6DAA8D,CAG9D,6BAA8B,CAC9B,6BAA8B,CAC9B,+BAAgC,CAChC,kCAAmC,CACnC,kCAAmC,CCPjC,+jBCYA,iqCAZF,iaCVA,8KAOA,4SAWA,4SAUA,0CACA,gEAGA,0CAGA,gEAGA,yCACA,+DAIA,4CACA,kEAGA,wCAUA,8DACA,uCAGA,4DACA,sCACA,2DAGA,4CACA,kEACA,uCAGA,6DACA,2GAGA,sHAEA,yFAEA,+CACA,+EAGA,4MAOA,gCACA,sHAIA,kCACA,uEACA,gEACA,4DACA,kEAGA,2DACA,sDACA,0CACA,8CACA,wGAGA,0BACA,iCAGA,+DACA,+BACA,sCACA,+DAEA,kGACA,oCACA,yDACA,sCL7HF,kCAEA,sDAIA,0CK2HE,kEAIA,oDACA,sDAGA,oCACA,oEAEA,0DACA,qDAIA,oDACA,6DAIA,iEAIA,2DAIA,2DAGA,4DACA,gEAIA,gEAEA,gFAEA,oNASA,qDLxKE,gFAGE,4DAIF,oEKkHF,yEAEA,6DAGA,0DAEA,uDACA,qDACA,wDAIA,6DAIA,yDACA,2DAIA,uCAGA,wCACA,sDAGA,+CAGA,6DAEA,iDACA,+DAEA,wDAEA,sEAMA,0DACA,sBACA,mEL9JI,wEAEA,iCACE,+BAMN,wEAGA,iCACE,kFAEA,uEAIF,gEACE,8BAGF,qEMvDA,sCAKA,wFAKA,iCAIA,0BAWA,iCACA,4BACA,mCAGA,+BAEA,sCACA,4BAEA,mCAEA,sCAKA,sDAIA,gCAEA,gEAQF,wCAME,sBACA,kCAKA,uBAEA,gEAIA,2BAIA,mCAEA,qCACA,iCAGE,+BACA,wEAEE,iCACA,kFAGF,6BACA,0CACF,kCAEE,8BACE,8BACA,qEAEE,sCACA,wFCnFN,iCAGF,2DAEE,4BACA,oCAGA,mIAGA,4HACE,gEAMJ,+CAGE,sBACA,yCAEF,uBAEE,sEAKA,gDACA,kEAGA,iFAGE,YAGF,EACA,4HAQF,mBACE,6BACA,mBACA,wCACA,wCACA,2CAIA,eAGA,mBAKE,mBAGA,CAJA,uCACA,iBAFF,gBACE,CAKE,mBACA,mBAGJ,oBAIF,+BAGE,kDACA,OADA,kBAGA,CAFA,gBAEA,mBACA,oBAEA,sCACA,OAGF,cAHE,WAGF,GAEE,oBACA,CAHF,gBAGE,CC9Gc,YDiHd,+CAIF,SAEE,CAPF,UACE,wBAMA,4BAEA,GAGA,uBACA,CAJA,yBAGA,CACA,iDAKA,2CAGA,2DAQA,iBACA,uCAGA,kEAKE,SAKJ,8BACE,yDACA,2BAEA,oBACA,8BAEA,yDAEE,4BAEJ,uCACE,CACA,iEAGA,CAEA,wCACE,uBACA,kDAEA,0DAEE,CAJF,oBAIE,0GAWN,aACE,CAHA,YAGA,4HASA,+CAGF,sBACE,WACA,WAQA,4BAFF,0CAEE,CARA,qCAsBA,CAdA,iBAEA,kBACE,aADF,4BACE,WAMF,2BAGF,qCAEE,CAXE,UAWF,+BAGA,uBAEA,SAEA,0CAIE,CANF,qCAEA,CAIE,2DACE,gBAIN,+CAIA,CAEA,kDAKE,CAPF,8BAEA,CAOE,YACA,CAjBI,2BAGN,CAHM,WAcJ,UAGA,CAEA,2GAIF,iCAGE,8BAIA,qBACA,oBACF,uBAOI,0CAIA,CATF,6DAKE,CALF,sBASE,qCAKF,CACE,cACA,CAFF,sBAEE,CACA,+BAEA,qBAEE,WAKN,aACE,sCAGA,mBAEA,6BAMA,kCACA,CAJA,sBACA,aAEA,CAJA,eACA,MAIA,2FAEA,UAGA,YACA,sBACE,8BAEA,CALF,aACA,WAIE,OACA,oBAEF,uBACE,WAEF,YAFE,UAEF,eAgBA,kBACE,CAhBA,qDAQF,qCAGF,CAGI,YACF,CAJF,2BAGI,CAEA,eACA,qBAGA,mEAEA,qBACA,8BAIA,kBADF,kBACE,yBAEJ,oCAGI,qDAIJ,+BAGI,oCAEA,+CAQF,4CACE,yBACF,2BAOE,sBACA,CAHA,WACA,CAFF,cACE,CAJA,YAGF,CAEE,SAEA,mBAGA,kDAEE,CAJF,cAEA,cAEE,sBAEA,mBADA,YACA,uBACA,mDACE,CADF,YACE,iDAEA,uCAEN,+DAOE,mBADF,sBACE,mBAGF,aACE,sCAIA,aADF,WACE,CAKF,SACE,CAHJ,kBAEE,CAJE,gBAEJ,CAHI,iBAMA,yFAKA,aACA,eACA,cElbJ,iBAEE,aADA,iBACA,6BAEA,kCAEA,SACA,UAIA,gCACA,CALA,SAEA,SAEA,CAJA,0EAEA,CAFA,OAKA,CAGA,mDACE,iBAGF,gCACE,CADF,UACE,aAEJ,iCAEE,CAFF,UAEE,wCAEA,WACA,WADA,UACA,CACA,4CAGA,MACA,CADA,KACA,wCACA,UAGA,CAJA,UAIA,6DAUA,0CACE,CAFF,mBAEE,wEACA,CAVA,YACA,CAMF,mBAJE,OAOA,gBAJJ,gCACE,CANE,cACA,CAHA,oBACA,CAGA,QAGJ,CAII,0BACA,CADA,UACA,wCAEJ,kBACE,0DACA,gCACE,kBACA,CADA,YACA,oEACA,2CAMF,mDAII,CALN,YACE,CANE,cAKJ,CACE,iBAII,kEACA,yCACE,kDACA,yDACE,+CACA,uBANN,CAMM,+BANN,uCACE,qDACA,4BAEE,mBADA,0CACA,CADA,qBACA,0DACE,wCACA,sGALJ,oCACA,sBACE,kBAFF,UAEE,2CACA,wFACE,cACA,kEANN,uBACE,iDACA,CADA,UACA,0DACE,wDAEE,iEACA,qEANN,sCACE,CAGE,iBAHF,gBAGE,qBACE,CAJJ,uBACA,gDACE,wDACA,6DAHF,2CACA,CADA,gBACA,eACE,CAGE,sBANN,8BACE,CAII,iBAFF,4DACA,WACE,YADF,uCACE,6EACA,2BANN,8CACE,kDACA,0CACE,8BACA,yFACE,sBACA,sFALJ,mEACA,sBACE,kEACA,6EACE,uCACA,kEALJ,qGAEE,kEACA,6EACE,uCACA,kEALJ,8CACA,uDACE,sEACA,2EACE,sCACA,iEALJ,mGACA,qCACE,oDACA,0DACE,6GACA,gDAGR,yDCrEA,sEACE,CACA,6GACE,gEACF,iGAIF,wFACE,qDAGA,mGAEE,2CAEF,4FACE,gCACF,wGACE,8DAEE,6FAIA,iJAKN,6GACE,gDAKF,yDACA,qCAGA,6BACA,kBACA,qDAKA,oCAEA,+DAGA,2CAGE,oDAIA,oEAEE,qBAGJ,wDAEE,uCAEF,kEAGA,8CAEA,uDAIF,gEAIE,6BACA,gEAIA,+CACE,0EAIF,sDAEE,+DAGF,sCACA,8BACE,oCAEJ,wBACE,4FAEE,gBAEJ,yGAGI,kBAGJ,CCnHE,2MCFF,oBAGE,wGAKA,iCACE,CADF,wBACE,8GAQA,mBCjBJ,2GAIE,mBACA,6HAMA,YACE,mIAYF,eACA,CAHF,YAGE,4FAGE,8BAKF,uBAkBE,sCACA,CADA,qBAbA,wCAIA,CALF,8BACE,CADF,gBAKE,wCACA,CAOA,kDACA,CACA,kCAKF,6BAGA,4CACE,kDACA,eAGF,cACE,aACA,iBACA,yBACA,8BACA,WAGJ,2BACE,cAGA,+BACA,CAHA,eAGA,wCACA,YACA,iBACA,uEAGA,0BACA,2CAEA,8EAGI,qBACA,CAFF,kBAEE,kBAGN,0CAGE,mCAGA,4BAIA,gEACE,qCACA,8BAEA,gBACA,+CACA,iCAEF,iCAEE,gEACA,qCAGF,8BAEE,+BAIA,yCAEE,qBADA,gBACA,yBAKF,eACA,CAFF,YACE,CACA,iBACA,qDAEA,mDCvIJ,2FAOE,iCACA,CAEA,eACA,CAHA,kBAEA,CAFA,wBAGA,8BACA,eACE,CAFF,YAEE,0BACA,8CAGA,oBACE,oCAGA,kBACE,8DAEA,iBAEN,UACE,8BAIJ,+CAEE,qDAEF,kDAIE,YAEF,CAFE,YAEF,CCpCE,mFADA,kBAKE,CAJF,IAGA,aACE,mCAGA,iDACE,+BAEJ,wBAEE,mBAMA,6CAEF,CAJE,mBAEA,CAEF,kCAGE,CARF,kBACE,CAHA,eAUA,YACA,mBACA,CADA,UACA,wCC9BF,oBDkCE,wBCnCJ,uCACE,+BACA,+DACA,sBAGA,qBCDA,6CAIE,CAPF,uBAGA,CDGE,oBACF,yDAEE,CCDE,2CAGF,CAJA,kCACE,CDJJ,YACE,CAIA,eCTF,CDKE,uBCMA,gCACE,YAEF,oCAEE,wBACA,0BAIF,iBAEA,cADF,UACE,uBAEA,iCAEA,wCAEA,6CAMA,CAYF,gCATI,4BASJ,CAZE,mCAEE,iCAUJ,4BAGE,4DADA,+BACA,CAHF,qBAGE,sCACE,OAEF,iBAHA,SAGA,iHACE,2DAKF,CANA,8EAMA,uSAEE,kBAEF,+FACE,yCCjEJ,WACA,yBAGA,uBACA,gBAEA,uCAIA,CAJA,iCAIA,uCAGA,UACE,gBACA,qBAEA,0CClBJ,gBACE,KAGF,qBACE,YAGF,CAHE,cAGF,gCAEE,mBACA,iEAEA,oCACA,wCAEA,sBACA,WAEA,CAFA,YAEA,8EAEA,mCAFA,iBAEA,6BAIA,wEAKA,sDAIE,CARF,mDAIA,CAIE,cAEF,8CAIA,oBAFE,iBAEF,8CAGE,eAEF,CAFE,YAEF,OAEE,kBAGJ,CAJI,eACA,CAFF,mBAKF,yCCjDE,oBACA,CAFA,iBAEA,uCAKE,iBACA,qCAGA,mBCZJ,CDWI,gBCXJ,6BAEE,eACA,sBAGA,eAEA,sBACA,oDACA,iGAMA,gBAFE,YAEF,8FAME,iJCnBF,YACA,gNAWE,gDAEF,iSAaE,kBACE,gHAKF,oCACE,eACF,CADE,UACF,8CACE,gDACF,wCACE,oBCxCJ,oBAEF,6BACE,QACE,kDAGF,yBACE,kDAmBA,kDAEF,CAhBA,+CAaA,CAbA,oBAaA,0FACE,CADF,gGAfF,cACE,gBACA,CAaA,0BAGA,mQACE,gBAGF,oMACE,iBACA,CAFF,eACE,CADF,gBAEE,aAGJ,iCAEE,CAFF,wCAEE,wBAUE,+VAIE,uEAHA,2BAGA,wXAKJ,iDAGF,CARM,+CACE,iDAIN,CALI,gBAQN,mHACE,gBAGF,2DACE,0EAOA,0EAGF,gBAEE,6DC/EA,kDACA,gCACA,qDAGA,qBACA,qDCFA,cACA,eAEA,yBAGF,sBAEE,iBACA,sNAWA,iBACE,kBACA,wRAgBA,kBAEA,iOAgBA,uCACE,uEAEA,kBAEF,qUAuBE,iDAIJ,CACA,geCxFF,4BAEE,CAQA,6JACA,iDAIA,sEAGA,mDAOF,iDAGE,4DAIA,8CACA,qDAEE,eAFF,cAEE,oBAEF,uBAFE,kCAGA,eACA,iBACA,mBAIA,mDACA,CAHA,uCAEA,CAJA,0CACA,CAIA,gBAJA,gBACA,oBADA,gBAIA,wBAEJ,gBAGE,6BACA,YAHA,iBAGA,gCACA,iEAEA,6CACA,sDACA,0BADA,wBACA,0BACA,oIAIA,mBAFA,YAEA,qBACA,0CAIE,uBAEF,CAHA,yBACE,CAEF,iDACE,mFAKJ,oCACE,CANE,aAKJ,CACE,qEAIA,YAFA,WAEA,CAHA,aACA,CAEA,gBACE,4BACA,sBADA,aACA,gCAMF,oCACA,yDACA,2CAEA,qBAGE,kBAEA,CACA,mCAIF,CARE,YACA,CAOF,iCAEE,CAPA,oBACA,CAQA,oBACE,uDAEJ,sDAGA,CAHA,cAGA,0BACE,oDAIA,oCACA,4BACA,sBAGA,cAEA,oFAGA,sBAEA,yDACE,CAIF,iBAJE,wBAIF,6CAHE,6CAKA,eACA,aACA,CADA,cACA,yCAGJ,kBACE,CAKA,iDAEA,CARF,aACE,4CAGA,kBAIA,wEAGA,wDAGA,kCAOA,iDAGA,CAPF,WAEE,sCAEA,CAJF,2CACE,CAMA,qCACA,+BARF,kBACE,qCAOA,iBAsBA,sBACE,CAvBF,WAKA,CACE,0DAIF,CALA,uDACE,CANF,sBAqBA,4CACA,CALA,gRAIA,YAEE,6CAEN,mCAEE,+CASA,6EAIA,4BChNA,SDmNA,qFCnNA,gDACA,sCAGA,qCACA,sDACA,CAKA,kDAGA,CARA,0CAQA,kBAGA,YACA,sBACA,iBAFA,gBADF,YACE,CAHA,SAKA,kBAEA,SAFA,iBAEA,uEAGA,CAEE,6CAFF,oCAgBI,CAdF,yBACE,qBACF,CAGF,oBACE,CAIF,WACE,CALA,2CAGA,uBACF,CACE,mFAGE,CALF,qBAEA,UAGE,gCAIF,sDAEA,CALE,oCAKF,yCC7CJ,oCACE,CD+CA,yXAQE,sCCrDJ,wCAGA,oCACE","sources":["webpack:///./node_modules/normalize.css/normalize.css","webpack:///./src/furo/assets/styles/base/_print.sass","webpack:///./src/furo/assets/styles/base/_screen-readers.sass","webpack:///./src/furo/assets/styles/base/_theme.sass","webpack:///./src/furo/assets/styles/variables/_fonts.scss","webpack:///./src/furo/assets/styles/variables/_spacing.scss","webpack:///./src/furo/assets/styles/variables/_icons.scss","webpack:///./src/furo/assets/styles/variables/_admonitions.scss","webpack:///./src/furo/assets/styles/variables/_colors.scss","webpack:///./src/furo/assets/styles/base/_typography.sass","webpack:///./src/furo/assets/styles/_scaffold.sass","webpack:///./src/furo/assets/styles/variables/_layout.scss","webpack:///./src/furo/assets/styles/content/_admonitions.sass","webpack:///./src/furo/assets/styles/content/_api.sass","webpack:///./src/furo/assets/styles/content/_blocks.sass","webpack:///./src/furo/assets/styles/content/_captions.sass","webpack:///./src/furo/assets/styles/content/_code.sass","webpack:///./src/furo/assets/styles/content/_footnotes.sass","webpack:///./src/furo/assets/styles/content/_images.sass","webpack:///./src/furo/assets/styles/content/_indexes.sass","webpack:///./src/furo/assets/styles/content/_lists.sass","webpack:///./src/furo/assets/styles/content/_math.sass","webpack:///./src/furo/assets/styles/content/_misc.sass","webpack:///./src/furo/assets/styles/content/_rubrics.sass","webpack:///./src/furo/assets/styles/content/_sidebar.sass","webpack:///./src/furo/assets/styles/content/_tables.sass","webpack:///./src/furo/assets/styles/content/_target.sass","webpack:///./src/furo/assets/styles/content/_gui-labels.sass","webpack:///./src/furo/assets/styles/components/_footer.sass","webpack:///./src/furo/assets/styles/components/_sidebar.sass","webpack:///./src/furo/assets/styles/components/_table_of_contents.sass","webpack:///./src/furo/assets/styles/_shame.sass"],"sourcesContent":["/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","// This file contains styles for managing print media.\n\n////////////////////////////////////////////////////////////////////////////////\n// Hide elements not relevant to print media.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Hide icon container.\n .content-icon-container\n display: none !important\n\n // Hide showing header links if hovering over when printing.\n .headerlink\n display: none !important\n\n // Hide mobile header.\n .mobile-header\n display: none !important\n\n // Hide navigation links.\n .related-pages\n display: none !important\n\n////////////////////////////////////////////////////////////////////////////////\n// Tweaks related to decolorization.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Apply a border around code which no longer have a color background.\n .highlight\n border: 0.1pt solid var(--color-foreground-border)\n\n////////////////////////////////////////////////////////////////////////////////\n// Avoid page break in some relevant cases.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n ul, ol, dl, a, table, pre, blockquote, p\n page-break-inside: avoid\n\n h1, h2, h3, h4, h5, h6, img, figure, caption\n page-break-inside: avoid\n page-break-after: avoid\n\n ul, ol, dl\n page-break-before: avoid\n",".visually-hidden\n position: absolute !important\n width: 1px !important\n height: 1px !important\n padding: 0 !important\n margin: -1px !important\n overflow: hidden !important\n clip: rect(0,0,0,0) !important\n white-space: nowrap !important\n border: 0 !important\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n:-moz-focusring\n outline: auto\n","// This file serves as the \"skeleton\" of the theming logic.\n//\n// This contains the bulk of the logic for handling dark mode, color scheme\n// toggling and the handling of color-scheme-specific hiding of elements.\n\nbody\n @include fonts\n @include spacing\n @include icons\n @include admonitions\n @include default-admonition(#651fff, \"abstract\")\n @include default-topic(#14B8A6, \"pencil\")\n\n @include colors\n\n.only-light\n display: block !important\nhtml body .only-dark\n display: none !important\n\n// Ignore dark-mode hints if print media.\n@media not print\n // Enable dark-mode, if requested.\n body[data-theme=\"dark\"]\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n // Enable dark mode, unless explicitly told to avoid.\n @media (prefers-color-scheme: dark)\n body:not([data-theme=\"light\"])\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n//\n// Theme toggle presentation\n//\nbody[data-theme=\"auto\"]\n .theme-toggle svg.theme-icon-when-auto-light\n display: block\n\n @media (prefers-color-scheme: dark)\n .theme-toggle svg.theme-icon-when-auto-dark\n display: block\n .theme-toggle svg.theme-icon-when-auto-light\n display: none\n\nbody[data-theme=\"dark\"]\n .theme-toggle svg.theme-icon-when-dark\n display: block\n\nbody[data-theme=\"light\"]\n .theme-toggle svg.theme-icon-when-light\n display: block\n","// Fonts used by this theme.\n//\n// There are basically two things here -- using the system font stack and\n// defining sizes for various elements in %ages. We could have also used `em`\n// but %age is easier to reason about for me.\n\n@mixin fonts {\n // These are adapted from https://systemfontstack.com/\n --font-stack: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,\n sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --font-stack--monospace: \"SFMono-Regular\", Menlo, Consolas, Monaco,\n Liberation Mono, Lucida Console, monospace;\n --font-stack--headings: var(--font-stack);\n\n --font-size--normal: 100%;\n --font-size--small: 87.5%;\n --font-size--small--2: 81.25%;\n --font-size--small--3: 75%;\n --font-size--small--4: 62.5%;\n\n // Sidebar\n --sidebar-caption-font-size: var(--font-size--small--2);\n --sidebar-item-font-size: var(--font-size--small);\n --sidebar-search-input-font-size: var(--font-size--small);\n\n // Table of Contents\n --toc-font-size: var(--font-size--small--3);\n --toc-font-size--mobile: var(--font-size--normal);\n --toc-title-font-size: var(--font-size--small--4);\n\n // Admonitions\n //\n // These aren't defined in terms of %ages, since nesting these is permitted.\n --admonition-font-size: 0.8125rem;\n --admonition-title-font-size: 0.8125rem;\n\n // Code\n --code-font-size: var(--font-size--small--2);\n\n // API\n --api-font-size: var(--font-size--small);\n}\n","// Spacing for various elements on the page\n//\n// If the user wants to tweak things in a certain way, they are permitted to.\n// They also have to deal with the consequences though!\n\n@mixin spacing {\n // Header!\n --header-height: calc(\n var(--sidebar-item-line-height) + 4 * #{var(--sidebar-item-spacing-vertical)}\n );\n --header-padding: 0.5rem;\n\n // Sidebar\n --sidebar-tree-space-above: 1.5rem;\n --sidebar-caption-space-above: 1rem;\n\n --sidebar-item-line-height: 1rem;\n --sidebar-item-spacing-vertical: 0.5rem;\n --sidebar-item-spacing-horizontal: 1rem;\n --sidebar-item-height: calc(\n var(--sidebar-item-line-height) + 2 *#{var(--sidebar-item-spacing-vertical)}\n );\n\n --sidebar-expander-width: var(--sidebar-item-height); // be square\n\n --sidebar-search-space-above: 0.5rem;\n --sidebar-search-input-spacing-vertical: 0.5rem;\n --sidebar-search-input-spacing-horizontal: 0.5rem;\n --sidebar-search-input-height: 1rem;\n --sidebar-search-icon-size: var(--sidebar-search-input-height);\n\n // Table of Contents\n --toc-title-padding: 0.25rem 0;\n --toc-spacing-vertical: 1.5rem;\n --toc-spacing-horizontal: 1.5rem;\n --toc-item-spacing-vertical: 0.4rem;\n --toc-item-spacing-horizontal: 1rem;\n}\n","// Expose theme icons as CSS variables.\n\n$icons: (\n // Adapted from tabler-icons\n // url: https://tablericons.com/\n \"search\":\n url('data:image/svg+xml;charset=utf-8,'),\n // Factored out from mkdocs-material on 24-Aug-2020.\n // url: https://squidfunk.github.io/mkdocs-material/reference/admonitions/\n \"pencil\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"abstract\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"info\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"flame\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"question\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"warning\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"failure\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"spark\":\n url('data:image/svg+xml;charset=utf-8,')\n);\n\n@mixin icons {\n @each $name, $glyph in $icons {\n --icon-#{$name}: #{$glyph};\n }\n}\n","// Admonitions\n\n// Structure of these is:\n// admonition-class: color \"icon-name\";\n//\n// The colors are translated into CSS variables below. The icons are\n// used directly in the main declarations to set the `mask-image` in\n// the title.\n\n// prettier-ignore\n$admonitions: (\n // Each of these has an reST directives for it.\n \"caution\": #ff9100 \"spark\",\n \"warning\": #ff9100 \"warning\",\n \"danger\": #ff5252 \"spark\",\n \"attention\": #ff5252 \"warning\",\n \"error\": #ff5252 \"failure\",\n \"hint\": #00c852 \"question\",\n \"tip\": #00c852 \"info\",\n \"important\": #00bfa5 \"flame\",\n \"note\": #00b0ff \"pencil\",\n \"seealso\": #448aff \"info\",\n \"admonition-todo\": #808080 \"pencil\"\n);\n\n@mixin default-admonition($color, $icon-name) {\n --color-admonition-title: #{$color};\n --color-admonition-title-background: #{rgba($color, 0.2)};\n\n --icon-admonition-default: var(--icon-#{$icon-name});\n}\n\n@mixin default-topic($color, $icon-name) {\n --color-topic-title: #{$color};\n --color-topic-title-background: #{rgba($color, 0.2)};\n\n --icon-topic-default: var(--icon-#{$icon-name});\n}\n\n@mixin admonitions {\n @each $name, $values in $admonitions {\n --color-admonition-title--#{$name}: #{nth($values, 1)};\n --color-admonition-title-background--#{$name}: #{rgba(\n nth($values, 1),\n 0.2\n )};\n }\n}\n","// Colors used throughout this theme.\n//\n// The aim is to give the user more control. Thus, instead of hard-coding colors\n// in various parts of the stylesheet, the approach taken is to define all\n// colors as CSS variables and reusing them in all the places.\n//\n// `colors-dark` depends on `colors` being included at a lower specificity.\n\n@mixin colors {\n --color-problematic: #b30000;\n\n // Base Colors\n --color-foreground-primary: black; // for main text and headings\n --color-foreground-secondary: #5a5c63; // for secondary text\n --color-foreground-muted: #6b6f76; // for muted text\n --color-foreground-border: #878787; // for content borders\n\n --color-background-primary: white; // for content\n --color-background-secondary: #f8f9fb; // for navigation + ToC\n --color-background-hover: #efeff4ff; // for navigation-item hover\n --color-background-hover--transparent: #efeff400;\n --color-background-border: #eeebee; // for UI borders\n --color-background-item: #ccc; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #0a4bff;\n --color-brand-content: #2757dd;\n --color-brand-visited: #872ee0;\n\n // API documentation\n --color-api-background: var(--color-background-hover--transparent);\n --color-api-background-hover: var(--color-background-hover);\n --color-api-overall: var(--color-foreground-secondary);\n --color-api-name: var(--color-problematic);\n --color-api-pre-name: var(--color-problematic);\n --color-api-paren: var(--color-foreground-secondary);\n --color-api-keyword: var(--color-foreground-primary);\n\n --color-api-added: #21632c;\n --color-api-added-border: #38a84d;\n --color-api-changed: #046172;\n --color-api-changed-border: #06a1bc;\n --color-api-deprecated: #605706;\n --color-api-deprecated-border: #f0d90f;\n --color-api-removed: #b30000;\n --color-api-removed-border: #ff5c5c;\n\n --color-highlight-on-target: #ffffcc;\n\n // Inline code background\n --color-inline-code-background: var(--color-background-secondary);\n\n // Highlighted text (search)\n --color-highlighted-background: #ddeeff;\n --color-highlighted-text: var(--color-foreground-primary);\n\n // GUI Labels\n --color-guilabel-background: #ddeeff80;\n --color-guilabel-border: #bedaf580;\n --color-guilabel-text: var(--color-foreground-primary);\n\n // Admonitions!\n --color-admonition-background: transparent;\n\n //////////////////////////////////////////////////////////////////////////////\n // Everything below this should be one of:\n // - var(...)\n // - *-gradient(...)\n // - special literal values (eg: transparent, none)\n //////////////////////////////////////////////////////////////////////////////\n\n // Tables\n --color-table-header-background: var(--color-background-secondary);\n --color-table-border: var(--color-background-border);\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: transparent;\n --color-card-marginals-background: var(--color-background-secondary);\n\n // Header\n --color-header-background: var(--color-background-primary);\n --color-header-border: var(--color-background-border);\n --color-header-text: var(--color-foreground-primary);\n\n // Sidebar (left)\n --color-sidebar-background: var(--color-background-secondary);\n --color-sidebar-background-border: var(--color-background-border);\n\n --color-sidebar-brand-text: var(--color-foreground-primary);\n --color-sidebar-caption-text: var(--color-foreground-muted);\n --color-sidebar-link-text: var(--color-foreground-secondary);\n --color-sidebar-link-text--top-level: var(--color-brand-primary);\n\n --color-sidebar-item-background: var(--color-sidebar-background);\n --color-sidebar-item-background--current: var(\n --color-sidebar-item-background\n );\n --color-sidebar-item-background--hover: linear-gradient(\n 90deg,\n var(--color-background-hover--transparent) 0%,\n var(--color-background-hover) var(--sidebar-item-spacing-horizontal),\n var(--color-background-hover) 100%\n );\n\n --color-sidebar-item-expander-background: transparent;\n --color-sidebar-item-expander-background--hover: var(\n --color-background-hover\n );\n\n --color-sidebar-search-text: var(--color-foreground-primary);\n --color-sidebar-search-background: var(--color-background-secondary);\n --color-sidebar-search-background--focus: var(--color-background-primary);\n --color-sidebar-search-border: var(--color-background-border);\n --color-sidebar-search-icon: var(--color-foreground-muted);\n\n // Table of Contents (right)\n --color-toc-background: var(--color-background-primary);\n --color-toc-title-text: var(--color-foreground-muted);\n --color-toc-item-text: var(--color-foreground-secondary);\n --color-toc-item-text--hover: var(--color-foreground-primary);\n --color-toc-item-text--active: var(--color-brand-primary);\n\n // Actual page contents\n --color-content-foreground: var(--color-foreground-primary);\n --color-content-background: transparent;\n\n // Links\n --color-link: var(--color-brand-content);\n --color-link-underline: var(--color-background-border);\n --color-link--hover: var(--color-brand-content);\n --color-link-underline--hover: var(--color-foreground-border);\n\n --color-link--visited: var(--color-brand-visited);\n --color-link-underline--visited: var(--color-background-border);\n --color-link--visited--hover: var(--color-brand-visited);\n --color-link-underline--visited--hover: var(--color-foreground-border);\n}\n\n@mixin colors-dark {\n --color-problematic: #ee5151;\n\n // Base Colors\n --color-foreground-primary: #cfd0d0; // for main text and headings\n --color-foreground-secondary: #9ca0a5; // for secondary text\n --color-foreground-muted: #81868d; // for muted text\n --color-foreground-border: #666666; // for content borders\n\n --color-background-primary: #131416; // for content\n --color-background-secondary: #1a1c1e; // for navigation + ToC\n --color-background-hover: #1e2124ff; // for navigation-item hover\n --color-background-hover--transparent: #1e212400;\n --color-background-border: #303335; // for UI borders\n --color-background-item: #444; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #3d94ff;\n --color-brand-content: #5ca5ff;\n --color-brand-visited: #b27aeb;\n\n // Highlighted text (search)\n --color-highlighted-background: #083563;\n\n // GUI Labels\n --color-guilabel-background: #08356380;\n --color-guilabel-border: #13395f80;\n\n // API documentation\n --color-api-keyword: var(--color-foreground-secondary);\n --color-highlight-on-target: #333300;\n\n --color-api-added: #3db854;\n --color-api-added-border: #267334;\n --color-api-changed: #09b0ce;\n --color-api-changed-border: #056d80;\n --color-api-deprecated: #b1a10b;\n --color-api-deprecated-border: #6e6407;\n --color-api-removed: #ff7575;\n --color-api-removed-border: #b03b3b;\n\n // Admonitions\n --color-admonition-background: #18181a;\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: #18181a;\n --color-card-marginals-background: var(--color-background-hover);\n}\n","// This file contains the styling for making the content throughout the page,\n// including fonts, paragraphs, headings and spacing among these elements.\n\nbody\n font-family: var(--font-stack)\npre,\ncode,\nkbd,\nsamp\n font-family: var(--font-stack--monospace)\n\n// Make fonts look slightly nicer.\nbody\n -webkit-font-smoothing: antialiased\n -moz-osx-font-smoothing: grayscale\n\n// Line height from Bootstrap 4.1\narticle\n line-height: 1.5\n\n//\n// Headings\n//\nh1,\nh2,\nh3,\nh4,\nh5,\nh6\n line-height: 1.25\n font-family: var(--font-stack--headings)\n font-weight: bold\n\n border-radius: 0.5rem\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n margin-left: -0.5rem\n margin-right: -0.5rem\n padding-left: 0.5rem\n padding-right: 0.5rem\n\n + p\n margin-top: 0\n\nh1\n font-size: 2.5em\n margin-top: 1.75rem\n margin-bottom: 1rem\nh2\n font-size: 2em\n margin-top: 1.75rem\nh3\n font-size: 1.5em\nh4\n font-size: 1.25em\nh5\n font-size: 1.125em\nh6\n font-size: 1em\n\nsmall\n opacity: 75%\n font-size: 80%\n\n// Paragraph\np\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n\n// Horizontal rules\nhr.docutils\n height: 1px\n padding: 0\n margin: 2rem 0\n background-color: var(--color-background-border)\n border: 0\n\n.centered\n text-align: center\n\n// Links\na\n text-decoration: underline\n\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n &:visited\n color: var(--color-link--visited)\n text-decoration-color: var(--color-link-underline--visited)\n &:hover\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &.muted-link\n color: inherit\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &:visited\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n","// This file contains the styles for the overall layouting of the documentation\n// skeleton, including the responsive changes as well as sidebar toggles.\n//\n// This is implemented as a mobile-last design, which isn't ideal, but it is\n// reasonably good-enough and I got pretty tired by the time I'd finished this\n// to move the rules around to fix this. Shouldn't take more than 3-4 hours,\n// if you know what you're doing tho.\n\n// HACK: Not all browsers account for the scrollbar width in media queries.\n// This results in horizontal scrollbars in the breakpoint where we go\n// from displaying everything to hiding the ToC. We accomodate for this by\n// adding a bit of padding to the TOC drawer, disabling the horizontal\n// scrollbar and allowing the scrollbars to cover the padding.\n// https://www.456bereastreet.com/archive/201301/media_query_width_and_vertical_scrollbars/\n\n// HACK: Always having the scrollbar visible, prevents certain browsers from\n// causing the content to stutter horizontally between taller-than-viewport and\n// not-taller-than-viewport pages.\n\nhtml\n overflow-x: hidden\n overflow-y: scroll\n scroll-behavior: smooth\n\n.sidebar-scroll, .toc-scroll, article[role=main] *\n // Override Firefox scrollbar style\n scrollbar-width: thin\n scrollbar-color: var(--color-foreground-border) transparent\n\n // Override Chrome scrollbar styles\n &::-webkit-scrollbar\n width: 0.25rem\n height: 0.25rem\n &::-webkit-scrollbar-thumb\n background-color: var(--color-foreground-border)\n border-radius: 0.125rem\n\n//\n// Overalls\n//\nhtml,\nbody\n height: 100%\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n.skip-to-content\n position: fixed\n padding: 1rem\n border-radius: 1rem\n left: 0.25rem\n top: 0.25rem\n z-index: 40\n background: var(--color-background-primary)\n color: var(--color-foreground-primary)\n\n transform: translateY(-200%)\n transition: transform 300ms ease-in-out\n\n &:focus-within\n transform: translateY(0%)\n\narticle\n color: var(--color-content-foreground)\n background: var(--color-content-background)\n overflow-wrap: break-word\n\n.page\n display: flex\n // fill the viewport for pages with little content.\n min-height: 100%\n\n.mobile-header\n width: 100%\n height: var(--header-height)\n background-color: var(--color-header-background)\n color: var(--color-header-text)\n border-bottom: 1px solid var(--color-header-border)\n\n // Looks like sub-script/super-script have this, and we need this to\n // be \"on top\" of those.\n z-index: 10\n\n // We don't show the header on large screens.\n display: none\n\n // Add shadow when scrolled\n &.scrolled\n border-bottom: none\n box-shadow: 0 0 0.2rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.4rem rgba(0, 0, 0, 0.2)\n\n .header-center\n a\n color: var(--color-header-text)\n text-decoration: none\n\n.main\n display: flex\n flex: 1\n\n// Sidebar (left) also covers the entire left portion of screen.\n.sidebar-drawer\n box-sizing: border-box\n\n border-right: 1px solid var(--color-sidebar-background-border)\n background: var(--color-sidebar-background)\n\n display: flex\n justify-content: flex-end\n // These next two lines took me two days to figure out.\n width: calc((100% - #{$full-width}) / 2 + #{$sidebar-width})\n min-width: $sidebar-width\n\n// Scroll-along sidebars\n.sidebar-container,\n.toc-drawer\n box-sizing: border-box\n width: $sidebar-width\n\n.toc-drawer\n background: var(--color-toc-background)\n // See HACK described on top of this document\n padding-right: 1rem\n\n.sidebar-sticky,\n.toc-sticky\n position: sticky\n top: 0\n height: min(100%, 100vh)\n height: 100vh\n\n display: flex\n flex-direction: column\n\n.sidebar-scroll,\n.toc-scroll\n flex-grow: 1\n flex-shrink: 1\n\n overflow: auto\n scroll-behavior: smooth\n\n// Central items.\n.content\n padding: 0 $content-padding\n width: $content-width\n\n display: flex\n flex-direction: column\n justify-content: space-between\n\n.icon\n display: inline-block\n height: 1rem\n width: 1rem\n svg\n width: 100%\n height: 100%\n\n//\n// Accommodate announcement banner\n//\n.announcement\n background-color: var(--color-announcement-background)\n color: var(--color-announcement-text)\n\n height: var(--header-height)\n display: flex\n align-items: center\n overflow-x: auto\n & + .page\n min-height: calc(100% - var(--header-height))\n\n.announcement-content\n box-sizing: border-box\n padding: 0.5rem\n min-width: 100%\n white-space: nowrap\n text-align: center\n\n a\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-announcement-text)\n\n &:hover\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-link--hover)\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for theme\n////////////////////////////////////////////////////////////////////////////////\n.no-js .theme-toggle-container // don't show theme toggle if there's no JS\n display: none\n\n.theme-toggle-container\n display: flex\n\n.theme-toggle\n display: flex\n cursor: pointer\n border: none\n padding: 0\n background: transparent\n\n.theme-toggle svg\n height: 1.25rem\n width: 1.25rem\n color: var(--color-foreground-primary)\n display: none\n\n.theme-toggle-header\n display: flex\n align-items: center\n justify-content: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for elements\n////////////////////////////////////////////////////////////////////////////////\n.toc-overlay-icon, .nav-overlay-icon\n display: none\n cursor: pointer\n\n .icon\n color: var(--color-foreground-secondary)\n height: 1.5rem\n width: 1.5rem\n\n.toc-header-icon, .nav-overlay-icon\n // for when we set display: flex\n justify-content: center\n align-items: center\n\n.toc-content-icon\n height: 1.5rem\n width: 1.5rem\n\n.content-icon-container\n float: right\n display: flex\n margin-top: 1.5rem\n margin-left: 1rem\n margin-bottom: 1rem\n gap: 0.5rem\n\n .edit-this-page, .view-this-page\n svg\n color: inherit\n height: 1.25rem\n width: 1.25rem\n\n.sidebar-toggle\n position: absolute\n display: none\n// \n.sidebar-toggle[name=\"__toc\"]\n left: 20px\n.sidebar-toggle:checked\n left: 40px\n// \n\n.overlay\n position: fixed\n top: 0\n width: 0\n height: 0\n\n transition: width 0ms, height 0ms, opacity 250ms ease-out\n\n opacity: 0\n background-color: rgba(0, 0, 0, 0.54)\n.sidebar-overlay\n z-index: 20\n.toc-overlay\n z-index: 40\n\n// Keep things on top and smooth.\n.sidebar-drawer\n z-index: 30\n transition: left 250ms ease-in-out\n.toc-drawer\n z-index: 50\n transition: right 250ms ease-in-out\n\n// Show the Sidebar\n#__navigation:checked\n & ~ .sidebar-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .sidebar-drawer\n top: 0\n left: 0\n // Show the toc sidebar\n#__toc:checked\n & ~ .toc-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .toc-drawer\n top: 0\n right: 0\n\n////////////////////////////////////////////////////////////////////////////////\n// Back to top\n////////////////////////////////////////////////////////////////////////////////\n.back-to-top\n text-decoration: none\n\n display: none\n position: fixed\n left: 0\n top: 1rem\n padding: 0.5rem\n padding-right: 0.75rem\n border-radius: 1rem\n font-size: 0.8125rem\n\n background: var(--color-background-primary)\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), #6b728080 0px 0px 1px 0px\n\n z-index: 10\n\n margin-left: 50%\n transform: translateX(-50%)\n svg\n height: 1rem\n width: 1rem\n fill: currentColor\n display: inline-block\n\n span\n margin-left: 0.25rem\n\n .show-back-to-top &\n display: flex\n align-items: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Responsive layouting\n////////////////////////////////////////////////////////////////////////////////\n// Make things a bit bigger on bigger screens.\n@media (min-width: $full-width + $sidebar-width)\n html\n font-size: 110%\n\n@media (max-width: $full-width)\n // Collapse \"toc\" into the icon.\n .toc-content-icon\n display: flex\n .toc-drawer\n position: fixed\n height: 100vh\n top: 0\n right: -$sidebar-width\n border-left: 1px solid var(--color-background-muted)\n .toc-tree\n border-left: none\n font-size: var(--toc-font-size--mobile)\n\n // Accomodate for a changed content width.\n .sidebar-drawer\n width: calc((100% - #{$full-width - $sidebar-width}) / 2 + #{$sidebar-width})\n\n@media (max-width: $content-padded-width + $sidebar-width)\n // Center the page\n .content\n margin-left: auto\n margin-right: auto\n padding: 0 $content-padding--small\n\n@media (max-width: $content-padded-width--small + $sidebar-width)\n // Collapse \"navigation\".\n .nav-overlay-icon\n display: flex\n .sidebar-drawer\n position: fixed\n height: 100vh\n width: $sidebar-width\n\n top: 0\n left: -$sidebar-width\n\n // Swap which icon is visible.\n .toc-header-icon, .theme-toggle-header\n display: flex\n .toc-content-icon, .theme-toggle-content\n display: none\n\n // Show the header.\n .mobile-header\n position: sticky\n top: 0\n display: flex\n justify-content: space-between\n align-items: center\n\n .header-left,\n .header-right\n display: flex\n height: var(--header-height)\n padding: 0 var(--header-padding)\n label\n height: 100%\n width: 100%\n user-select: none\n\n .nav-overlay-icon .icon,\n .theme-toggle svg\n height: 1.5rem\n width: 1.5rem\n\n // Add a scroll margin for the content\n :target\n scroll-margin-top: calc(var(--header-height) + 2.5rem)\n\n // Show back-to-top below the header\n .back-to-top\n top: calc(var(--header-height) + 0.5rem)\n\n // Accommodate for the header.\n .page\n flex-direction: column\n justify-content: center\n\n@media (max-width: $content-width + 2* $content-padding--small)\n // Content should respect window limits.\n .content\n width: 100%\n overflow-x: auto\n\n@media (max-width: $content-width)\n article[role=main] aside.sidebar\n float: none\n width: 100%\n margin: 1rem 0\n","// Overall Layout Variables\n//\n// Because CSS variables can't be used in media queries. The fact that this\n// makes the layout non-user-configurable is a good thing.\n$content-padding: 3em;\n$content-padding--small: 1em;\n$content-width: 46em;\n$sidebar-width: 15em;\n$content-padded-width: $content-width + 2 * $content-padding;\n$content-padded-width--small: $content-width + 2 * $content-padding--small;\n$full-width: $content-padded-width + 2 * $sidebar-width;\n","//\n// The design here is strongly inspired by mkdocs-material.\n.admonition, .topic\n margin: 1rem auto\n padding: 0 0.5rem 0.5rem 0.5rem\n\n background: var(--color-admonition-background)\n\n border-radius: 0.2rem\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n font-size: var(--admonition-font-size)\n\n overflow: hidden\n page-break-inside: avoid\n\n // First element should have no margin, since the title has it.\n > :nth-child(2)\n margin-top: 0\n\n // Last item should have no margin, since we'll control that w/ padding\n > :last-child\n margin-bottom: 0\n\n.admonition p.admonition-title,\np.topic-title\n position: relative\n margin: 0 -0.5rem 0.5rem\n padding-left: 2rem\n padding-right: .5rem\n padding-top: .4rem\n padding-bottom: .4rem\n\n font-weight: 500\n font-size: var(--admonition-title-font-size)\n line-height: 1.3\n\n // Our fancy icon\n &::before\n content: \"\"\n position: absolute\n left: 0.5rem\n width: 1rem\n height: 1rem\n\n// Default styles\np.admonition-title\n background-color: var(--color-admonition-title-background)\n &::before\n background-color: var(--color-admonition-title)\n mask-image: var(--icon-admonition-default)\n mask-repeat: no-repeat\n\np.topic-title\n background-color: var(--color-topic-title-background)\n &::before\n background-color: var(--color-topic-title)\n mask-image: var(--icon-topic-default)\n mask-repeat: no-repeat\n\n//\n// Variants\n//\n.admonition\n border-left: 0.2rem solid var(--color-admonition-title)\n\n @each $type, $value in $admonitions\n &.#{$type}\n border-left-color: var(--color-admonition-title--#{$type})\n > .admonition-title\n background-color: var(--color-admonition-title-background--#{$type})\n &::before\n background-color: var(--color-admonition-title--#{$type})\n mask-image: var(--icon-#{nth($value, 2)})\n\n.admonition-todo > .admonition-title\n text-transform: uppercase\n","// This file stylizes the API documentation (stuff generated by autodoc). It's\n// deeply nested due to how autodoc structures the HTML without enough classes\n// to select the relevant items.\n\n// API docs!\ndl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)\n // Tweak the spacing of all the things!\n dd\n margin-left: 2rem\n > :first-child\n margin-top: 0.125rem\n > :last-child\n margin-bottom: 0.75rem\n\n // This is used for the arguments\n .field-list\n margin-bottom: 0.75rem\n\n // \"Headings\" (like \"Parameters\" and \"Return\")\n > dt\n text-transform: uppercase\n font-size: var(--font-size--small)\n\n dd:empty\n margin-bottom: 0.5rem\n dd > ul\n margin-left: -1.2rem\n > li\n > p:nth-child(2)\n margin-top: 0\n // When the last-empty-paragraph follows a paragraph, it doesn't need\n // to augument the existing spacing.\n > p + p:last-child:empty\n margin-top: 0\n margin-bottom: 0\n\n // Colorize the elements\n > dt\n color: var(--color-api-overall)\n\n.sig:not(.sig-inline)\n font-weight: bold\n\n font-size: var(--api-font-size)\n font-family: var(--font-stack--monospace)\n\n margin-left: -0.25rem\n margin-right: -0.25rem\n padding-top: 0.25rem\n padding-bottom: 0.25rem\n padding-right: 0.5rem\n\n // These are intentionally em, to properly match the font size.\n padding-left: 3em\n text-indent: -2.5em\n\n border-radius: 0.25rem\n\n background: var(--color-api-background)\n transition: background 100ms ease-out\n\n &:hover\n background: var(--color-api-background-hover)\n\n // adjust the size of the [source] link on the right.\n a.reference\n .viewcode-link\n font-weight: normal\n width: 4.25rem\n\nem.property\n font-style: normal\n &:first-child\n color: var(--color-api-keyword)\n.sig-name\n color: var(--color-api-name)\n.sig-prename\n font-weight: normal\n color: var(--color-api-pre-name)\n.sig-paren\n color: var(--color-api-paren)\n.sig-param\n font-style: normal\n\ndiv.versionadded,\ndiv.versionchanged,\ndiv.deprecated,\ndiv.versionremoved\n border-left: 0.1875rem solid\n border-radius: 0.125rem\n\n padding-left: 0.75rem\n\n p\n margin-top: 0.125rem\n margin-bottom: 0.125rem\n\ndiv.versionadded\n border-color: var(--color-api-added-border)\n .versionmodified\n color: var(--color-api-added)\n\ndiv.versionchanged\n border-color: var(--color-api-changed-border)\n .versionmodified\n color: var(--color-api-changed)\n\ndiv.deprecated\n border-color: var(--color-api-deprecated-border)\n .versionmodified\n color: var(--color-api-deprecated)\n\ndiv.versionremoved\n border-color: var(--color-api-removed-border)\n .versionmodified\n color: var(--color-api-removed)\n\n// Align the [docs] and [source] to the right.\n.viewcode-link, .viewcode-back\n float: right\n text-align: right\n",".line-block\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n .line-block\n margin-top: 0rem\n margin-bottom: 0rem\n padding-left: 1rem\n","// Captions\narticle p.caption,\ntable > caption,\n.code-block-caption\n font-size: var(--font-size--small)\n text-align: center\n\n// Caption above a TOCTree\n.toctree-wrapper.compound\n .caption, :not(.caption) > .caption-text\n font-size: var(--font-size--small)\n text-transform: uppercase\n\n text-align: initial\n margin-bottom: 0\n\n > ul\n margin-top: 0\n margin-bottom: 0\n","// Inline code\ncode.literal, .sig-inline\n background: var(--color-inline-code-background)\n border-radius: 0.2em\n // Make the font smaller, and use padding to recover.\n font-size: var(--font-size--small--2)\n padding: 0.1em 0.2em\n\n pre.literal-block &\n font-size: inherit\n padding: 0\n\n p &\n border: 1px solid var(--color-background-border)\n\n.sig-inline\n font-family: var(--font-stack--monospace)\n\n// Code and Literal Blocks\n$code-spacing-vertical: 0.625rem\n$code-spacing-horizontal: 0.875rem\n\n// Wraps every literal block + line numbers.\ndiv[class*=\" highlight-\"],\ndiv[class^=\"highlight-\"]\n margin: 1em 0\n display: flex\n\n .table-wrapper\n margin: 0\n padding: 0\n\npre\n margin: 0\n padding: 0\n overflow: auto\n\n // Needed to have more specificity than pygments' \"pre\" selector. :(\n article[role=\"main\"] .highlight &\n line-height: 1.5\n\n &.literal-block,\n .highlight &\n font-size: var(--code-font-size)\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n // Make it look like all the other blocks.\n &.literal-block\n margin-top: 1rem\n margin-bottom: 1rem\n\n border-radius: 0.2rem\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n\n// All code is always contained in this.\n.highlight\n width: 100%\n border-radius: 0.2rem\n\n // Make line numbers and prompts un-selectable.\n .gp, span.linenos\n user-select: none\n pointer-events: none\n\n // Expand the line-highlighting.\n .hll\n display: block\n margin-left: -$code-spacing-horizontal\n margin-right: -$code-spacing-horizontal\n padding-left: $code-spacing-horizontal\n padding-right: $code-spacing-horizontal\n\n/* Make code block captions be nicely integrated */\n.code-block-caption\n display: flex\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n border-radius: 0.25rem\n border-bottom-left-radius: 0\n border-bottom-right-radius: 0\n font-weight: 300\n border-bottom: 1px solid\n\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n border-color: var(--color-background-border)\n\n + div[class]\n margin-top: 0\n pre\n border-top-left-radius: 0\n border-top-right-radius: 0\n\n// When `html_codeblock_linenos_style` is table.\n.highlighttable\n width: 100%\n display: block\n tbody\n display: block\n\n tr\n display: flex\n\n // Line numbers\n td.linenos\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n padding: $code-spacing-vertical $code-spacing-horizontal\n padding-right: 0\n border-top-left-radius: 0.2rem\n border-bottom-left-radius: 0.2rem\n\n .linenodiv\n padding-right: $code-spacing-horizontal\n font-size: var(--code-font-size)\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n\n // Actual code\n td.code\n padding: 0\n display: block\n flex: 1\n overflow: hidden\n\n .highlight\n border-top-left-radius: 0\n border-bottom-left-radius: 0\n\n// When `html_codeblock_linenos_style` is inline.\n.highlight\n span.linenos\n display: inline-block\n padding-left: 0\n padding-right: $code-spacing-horizontal\n margin-right: $code-spacing-horizontal\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n","// Inline Footnote Reference\n.footnote-reference\n font-size: var(--font-size--small--4)\n vertical-align: super\n\n// Definition list, listing the content of each note.\n// docutils <= 0.17\ndl.footnote.brackets\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\n display: grid\n grid-template-columns: max-content auto\n dt\n margin: 0\n > .fn-backref\n margin-left: 0.25rem\n\n &:after\n content: \":\"\n\n .brackets\n &:before\n content: \"[\"\n &:after\n content: \"]\"\n\n dd\n margin: 0\n padding: 0 1rem\n\n// docutils >= 0.18\naside.footnote\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\naside.footnote > span,\ndiv.citation > span\n float: left\n font-weight: 500\n padding-right: 0.25rem\n\naside.footnote > *:not(span),\ndiv.citation > p\n margin-left: 2rem\n","//\n// Figures\n//\nimg\n box-sizing: border-box\n max-width: 100%\n height: auto\n\narticle\n figure, .figure\n border-radius: 0.2rem\n\n margin: 0\n :last-child\n margin-bottom: 0\n\n .align-left\n float: left\n clear: left\n margin: 0 1rem 1rem\n\n .align-right\n float: right\n clear: right\n margin: 0 1rem 1rem\n\n .align-default,\n .align-center\n display: block\n text-align: center\n margin-left: auto\n margin-right: auto\n\n // WELL, table needs to be stylised like a table.\n table.align-default\n display: table\n text-align: initial\n",".genindex-jumpbox, .domainindex-jumpbox\n border-top: 1px solid var(--color-background-border)\n border-bottom: 1px solid var(--color-background-border)\n padding: 0.25rem\n\n.genindex-section, .domainindex-section\n h2\n margin-top: 0.75rem\n margin-bottom: 0.5rem\n ul\n margin-top: 0\n margin-bottom: 0\n","ul,\nol\n padding-left: 1.2rem\n\n // Space lists out like paragraphs\n margin-top: 1rem\n margin-bottom: 1rem\n // reduce margins within li.\n li\n > p:first-child\n margin-top: 0.25rem\n margin-bottom: 0.25rem\n\n > p:last-child\n margin-top: 0.25rem\n\n > ul,\n > ol\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n\nol\n &.arabic\n list-style: decimal\n &.loweralpha\n list-style: lower-alpha\n &.upperalpha\n list-style: upper-alpha\n &.lowerroman\n list-style: lower-roman\n &.upperroman\n list-style: upper-roman\n\n// Don't space lists out when they're \"simple\" or in a `.. toctree::`\n.simple,\n.toctree-wrapper\n li\n > ul,\n > ol\n margin-top: 0\n margin-bottom: 0\n\n// Definition Lists\n.field-list,\n.option-list,\ndl:not([class]),\ndl.simple,\ndl.footnote,\ndl.glossary\n dt\n font-weight: 500\n margin-top: 0.25rem\n + dt\n margin-top: 0\n\n .classifier::before\n content: \":\"\n margin-left: 0.2rem\n margin-right: 0.2rem\n\n dd\n > p:first-child,\n ul\n margin-top: 0.125rem\n\n ul\n margin-bottom: 0.125rem\n",".math-wrapper\n width: 100%\n overflow-x: auto\n\ndiv.math\n position: relative\n text-align: center\n\n .headerlink,\n &:focus .headerlink\n display: none\n\n &:hover .headerlink\n display: inline-block\n\n span.eqno\n position: absolute\n right: 0.5rem\n top: 50%\n transform: translate(0, -50%)\n z-index: 1\n","// Abbreviations\nabbr[title]\n cursor: help\n\n// \"Problematic\" content, as identified by Sphinx\n.problematic\n color: var(--color-problematic)\n\n// Keyboard / Mouse \"instructions\"\nkbd:not(.compound)\n margin: 0 0.2rem\n padding: 0 0.2rem\n border-radius: 0.2rem\n border: 1px solid var(--color-foreground-border)\n color: var(--color-foreground-primary)\n vertical-align: text-bottom\n\n font-size: var(--font-size--small--3)\n display: inline-block\n\n box-shadow: 0 0.0625rem 0 rgba(0, 0, 0, 0.2), inset 0 0 0 0.125rem var(--color-background-primary)\n\n background-color: var(--color-background-secondary)\n\n// Blockquote\nblockquote\n border-left: 4px solid var(--color-background-border)\n background: var(--color-background-secondary)\n\n margin-left: 0\n margin-right: 0\n padding: 0.5rem 1rem\n\n .attribution\n font-weight: 600\n text-align: right\n\n &.pull-quote,\n &.highlights\n font-size: 1.25em\n\n &.epigraph,\n &.pull-quote\n border-left-width: 0\n border-radius: 0.5rem\n\n &.highlights\n border-left-width: 0\n background: transparent\n\n// Center align embedded-in-text images\np .reference img\n vertical-align: middle\n","p.rubric\n line-height: 1.25\n font-weight: bold\n font-size: 1.125em\n\n // For Numpy-style documentation that's got rubrics within it.\n // https://github.com/pradyunsg/furo/discussions/505\n dd &\n line-height: inherit\n font-weight: inherit\n\n font-size: var(--font-size--small)\n text-transform: uppercase\n","article .sidebar\n float: right\n clear: right\n width: 30%\n\n margin-left: 1rem\n margin-right: 0\n\n border-radius: 0.2rem\n background-color: var(--color-background-secondary)\n border: var(--color-background-border) 1px solid\n\n > *\n padding-left: 1rem\n padding-right: 1rem\n\n > ul, > ol // lists need additional padding, because bullets.\n padding-left: 2.2rem\n\n .sidebar-title\n margin: 0\n padding: 0.5rem 1rem\n border-bottom: var(--color-background-border) 1px solid\n\n font-weight: 500\n\n// TODO: subtitle\n// TODO: dedicated variables?\n","[role=main] .table-wrapper.container\n width: 100%\n overflow-x: auto\n margin-top: 1rem\n margin-bottom: 0.5rem\n padding: 0.2rem 0.2rem 0.75rem\n\ntable.docutils\n border-radius: 0.2rem\n border-spacing: 0\n border-collapse: collapse\n\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n th\n background: var(--color-table-header-background)\n\n td,\n th\n // Space things out properly\n padding: 0 0.25rem\n\n // Get the borders looking just-right.\n border-left: 1px solid var(--color-table-border)\n border-right: 1px solid var(--color-table-border)\n border-bottom: 1px solid var(--color-table-border)\n\n p\n margin: 0.25rem\n\n &:first-child\n border-left: none\n &:last-child\n border-right: none\n\n // MyST-parser tables set these classes for control of column alignment\n &.text-left\n text-align: left\n &.text-right\n text-align: right\n &.text-center\n text-align: center\n",":target\n scroll-margin-top: 2.5rem\n\n@media (max-width: $full-width - $sidebar-width)\n :target\n scroll-margin-top: calc(2.5rem + var(--header-height))\n\n // When a heading is selected\n section > span:target\n scroll-margin-top: calc(2.8rem + var(--header-height))\n\n// Permalinks\n.headerlink\n font-weight: 100\n user-select: none\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\ndl dt,\np.caption,\nfigcaption p,\ntable > caption,\n.code-block-caption\n > .headerlink\n margin-left: 0.5rem\n visibility: hidden\n &:hover > .headerlink\n visibility: visible\n\n // Don't change to link-like, if someone adds the contents directive.\n > .toc-backref\n color: inherit\n text-decoration-line: none\n\n// Figure and table captions are special.\nfigure:hover > figcaption > p > .headerlink,\ntable:hover > caption > .headerlink\n visibility: visible\n\n:target >, // Regular section[id] style anchors\nspan:target ~ // Non-regular span[id] style \"extra\" anchors\n h1,\n h2,\n h3,\n h4,\n h5,\n h6\n &:nth-of-type(1)\n background-color: var(--color-highlight-on-target)\n // .headerlink\n // visibility: visible\n code.literal\n background-color: transparent\n\ntable:target > caption,\nfigure:target\n background-color: var(--color-highlight-on-target)\n\n// Inline page contents\n.this-will-duplicate-information-and-it-is-still-useful-here li :target\n background-color: var(--color-highlight-on-target)\n\n// Code block permalinks\n.literal-block-wrapper:target .code-block-caption\n background-color: var(--color-highlight-on-target)\n\n// When a definition list item is selected\n//\n// There isn't really an alternative to !important here, due to the\n// high-specificity of API documentation's selector.\ndt:target\n background-color: var(--color-highlight-on-target) !important\n\n// When a footnote reference is selected\n.footnote > dt:target + dd,\n.footnote-reference:target\n background-color: var(--color-highlight-on-target)\n",".guilabel\n background-color: var(--color-guilabel-background)\n border: 1px solid var(--color-guilabel-border)\n color: var(--color-guilabel-text)\n\n padding: 0 0.3em\n border-radius: 0.5em\n font-size: 0.9em\n","// This file contains the styles used for stylizing the footer that's shown\n// below the content.\n\nfooter\n font-size: var(--font-size--small)\n display: flex\n flex-direction: column\n\n margin-top: 2rem\n\n// Bottom of page information\n.bottom-of-page\n display: flex\n align-items: center\n justify-content: space-between\n\n margin-top: 1rem\n padding-top: 1rem\n padding-bottom: 1rem\n\n color: var(--color-foreground-secondary)\n border-top: 1px solid var(--color-background-border)\n\n line-height: 1.5\n\n @media (max-width: $content-width)\n text-align: center\n flex-direction: column-reverse\n gap: 0.25rem\n\n .left-details\n font-size: var(--font-size--small)\n\n .right-details\n display: flex\n flex-direction: column\n gap: 0.25rem\n text-align: right\n\n .icons\n display: flex\n justify-content: flex-end\n gap: 0.25rem\n font-size: 1rem\n\n a\n text-decoration: none\n\n svg,\n img\n font-size: 1.125rem\n height: 1em\n width: 1em\n\n// Next/Prev page information\n.related-pages\n a\n display: flex\n align-items: center\n\n text-decoration: none\n &:hover .page-info .title\n text-decoration: underline\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n svg.furo-related-icon,\n svg.furo-related-icon > use\n flex-shrink: 0\n\n color: var(--color-foreground-border)\n\n width: 0.75rem\n height: 0.75rem\n margin: 0 0.5rem\n\n &.next-page\n max-width: 50%\n\n float: right\n clear: right\n text-align: right\n\n &.prev-page\n max-width: 50%\n\n float: left\n clear: left\n\n svg\n transform: rotate(180deg)\n\n.page-info\n display: flex\n flex-direction: column\n overflow-wrap: anywhere\n\n .next-page &\n align-items: flex-end\n\n .context\n display: flex\n align-items: center\n\n padding-bottom: 0.1rem\n\n color: var(--color-foreground-muted)\n font-size: var(--font-size--small)\n text-decoration: none\n","// This file contains the styles for the contents of the left sidebar, which\n// contains the navigation tree, logo, search etc.\n\n////////////////////////////////////////////////////////////////////////////////\n// Brand on top of the scrollable tree.\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-brand\n display: flex\n flex-direction: column\n flex-shrink: 0\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n text-decoration: none\n\n.sidebar-brand-text\n color: var(--color-sidebar-brand-text)\n overflow-wrap: break-word\n margin: var(--sidebar-item-spacing-vertical) 0\n font-size: 1.5rem\n\n.sidebar-logo-container\n margin: var(--sidebar-item-spacing-vertical) 0\n\n.sidebar-logo\n margin: 0 auto\n display: block\n max-width: 100%\n\n////////////////////////////////////////////////////////////////////////////////\n// Search\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-search-container\n display: flex\n align-items: center\n margin-top: var(--sidebar-search-space-above)\n\n position: relative\n\n background: var(--color-sidebar-search-background)\n &:hover,\n &:focus-within\n background: var(--color-sidebar-search-background--focus)\n\n &::before\n content: \"\"\n position: absolute\n left: var(--sidebar-item-spacing-horizontal)\n width: var(--sidebar-search-icon-size)\n height: var(--sidebar-search-icon-size)\n\n background-color: var(--color-sidebar-search-icon)\n mask-image: var(--icon-search)\n\n.sidebar-search\n box-sizing: border-box\n\n border: none\n border-top: 1px solid var(--color-sidebar-search-border)\n border-bottom: 1px solid var(--color-sidebar-search-border)\n\n padding-top: var(--sidebar-search-input-spacing-vertical)\n padding-bottom: var(--sidebar-search-input-spacing-vertical)\n padding-right: var(--sidebar-search-input-spacing-horizontal)\n padding-left: calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size))\n\n width: 100%\n\n color: var(--color-sidebar-search-foreground)\n background: transparent\n z-index: 10\n\n &:focus\n outline: none\n\n &::placeholder\n font-size: var(--sidebar-search-input-font-size)\n\n//\n// Hide Search Matches link\n//\n#searchbox .highlight-link\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0\n margin: 0\n text-align: center\n\n a\n color: var(--color-sidebar-search-icon)\n font-size: var(--font-size--small--2)\n\n////////////////////////////////////////////////////////////////////////////////\n// Structure/Skeleton of the navigation tree (left)\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-tree\n font-size: var(--sidebar-item-font-size)\n margin-top: var(--sidebar-tree-space-above)\n margin-bottom: var(--sidebar-item-spacing-vertical)\n\n ul\n padding: 0\n margin-top: 0\n margin-bottom: 0\n\n display: flex\n flex-direction: column\n\n list-style: none\n\n li\n position: relative\n margin: 0\n\n > ul\n margin-left: var(--sidebar-item-spacing-horizontal)\n\n .icon\n color: var(--color-sidebar-link-text)\n\n .reference\n box-sizing: border-box\n color: var(--color-sidebar-link-text)\n\n // Fill the parent.\n display: inline-block\n line-height: var(--sidebar-item-line-height)\n text-decoration: none\n\n // Don't allow long words to cause wrapping.\n overflow-wrap: anywhere\n\n height: 100%\n width: 100%\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n &:hover\n color: var(--color-sidebar-link-text)\n background: var(--color-sidebar-item-background--hover)\n\n // Add a nice little \"external-link\" arrow here.\n &.external::after\n content: url('data:image/svg+xml,')\n margin: 0 0.25rem\n vertical-align: middle\n color: var(--color-sidebar-link-text)\n\n // Make the current page reference bold.\n .current-page > .reference\n font-weight: bold\n\n label\n position: absolute\n top: 0\n right: 0\n height: var(--sidebar-item-height)\n width: var(--sidebar-expander-width)\n\n cursor: pointer\n user-select: none\n\n display: flex\n justify-content: center\n align-items: center\n\n .caption, :not(.caption) > .caption-text\n font-size: var(--sidebar-caption-font-size)\n color: var(--color-sidebar-caption-text)\n\n font-weight: bold\n text-transform: uppercase\n\n margin: var(--sidebar-caption-space-above) 0 0 0\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n // If it has children, add a bit more padding to wrap the content to avoid\n // overlapping with the