Improve documentation
This commit is contained in:
parent
51f6f7174b
commit
63a45989f4
40 changed files with 956 additions and 420 deletions
4
.vscode/tasks.json
vendored
4
.vscode/tasks.json
vendored
|
|
@ -4,9 +4,9 @@
|
||||||
{
|
{
|
||||||
"label": "Format and lint",
|
"label": "Format and lint",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "source .env/bin/activate && scripts/format-python.sh great_ai tests",
|
"command": "source .env/bin/activate && scripts/format-python.sh great_ai docs tests",
|
||||||
"windows": {
|
"windows": {
|
||||||
"command": ".env\\bin\\activate.bat; scripts\\format-python.sh great_ai tests"
|
"command": ".env\\bin\\activate.bat; scripts\\format-python.sh great_ai docs tests"
|
||||||
},
|
},
|
||||||
"group": "test",
|
"group": "test",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
|
|
|
||||||
16
README.md
16
README.md
|
|
@ -1,13 +1,15 @@
|
||||||
# GreatAI
|
#  GreatAI
|
||||||
|
|
||||||
|
> GreatAI helps you easily transform your prototype AI code into production-ready software.
|
||||||
|
|
||||||
**work in progress, do not use!**
|
[](https://github.com/schmelczer/great-ai/actions/workflows/test.yml)
|
||||||
|
|
||||||
[](https://github.com/schmelczer/great-ai/actions/workflows/check.yml)
|
|
||||||
[](https://sonar.schmelczer.com/dashboard?id=great-ai)
|
[](https://sonar.schmelczer.com/dashboard?id=great-ai)
|
||||||
[](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml)
|
[](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml)
|
||||||
[](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml)
|
[](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml)
|
||||||
[](https://pepy.tech/project/great-ai)
|
[](https://pepy.tech/project/great-ai)
|
||||||
|
|
||||||
|
[Check out the documentation here](https://great-ai.scoutinscience.com/).
|
||||||
|
|
||||||
|
|
||||||
## Find `great-ai` on [DockerHub](https://hub.docker.com/repository/docker/schmelczera/great-ai)
|
## Find `great-ai` on [DockerHub](https://hub.docker.com/repository/docker/schmelczera/great-ai)
|
||||||
|
|
||||||
|
|
@ -33,8 +35,10 @@ def hello_world(name: str) -> str:
|
||||||
```
|
```
|
||||||
> Create a new file called `main.py`
|
> Create a new file called `main.py`
|
||||||
|
|
||||||
Deploy by executing `python3 -m great-ai main.py`
|
Deploy by executing `great-ai main.py`
|
||||||
> Or: `python3 -m great-ai main.py`
|
> Or: `great_ai main.py`
|
||||||
|
|
||||||
|
> Or: `python3 -m great_ai main.py`
|
||||||
|
|
||||||
Find the dashboard at [http://localhost:6060](http://localhost:6060/dashboard/).
|
Find the dashboard at [http://localhost:6060](http://localhost:6060/dashboard/).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
# **S**coutinScience **U**tilitie**S** for text processing [](https://github.com/ScoutinScience/platform/actions/workflows/sus-general.yaml)
|
|
||||||
|
|
||||||
## Exports
|
|
||||||
|
|
||||||
- [clean](src/sus/clean.py)
|
|
||||||
- [language](src/sus/clean.py)
|
|
||||||
- [unique](src/sus/unique.py)
|
|
||||||
- [parallel_map](src/sus/parallel_map.py)
|
|
||||||
- [evaluate_ranking](src/sus/evaluate_ranking/evaluate_ranking.py)
|
|
||||||
- [get_sentences](src/sus/get_sentences.py)
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
- Optional booleans must have a default value of `False`.
|
|
||||||
- No imports in top-level `__init__.py`, in order to not load anything unnecessary automatically
|
|
||||||
- Should only be updated through a PR
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Explanation
|
||||||
|
|
||||||
|
A lot more details and discussion about the problem context and approaches of GreatAI can be found in my thesis.
|
||||||
|
|
||||||
|
<div style="display: flex; justify-content: space-evenly;" markdown>
|
||||||
|
[::fontawesome-solid-graduation-cap: Download](thesis/main.py){ .md-button .md-button--primary }
|
||||||
|
</div>
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
.venv
|
|
||||||
.env
|
|
||||||
**/.cache
|
|
||||||
.git
|
|
||||||
**/__pycache__
|
|
||||||
.dockerignore
|
|
||||||
10
docs/great_ai_example-main/.gitignore
vendored
10
docs/great_ai_example-main/.gitignore
vendored
|
|
@ -1,10 +0,0 @@
|
||||||
.env
|
|
||||||
.venv
|
|
||||||
.DS_Store
|
|
||||||
__pycache__
|
|
||||||
.cache
|
|
||||||
.mypy_cache
|
|
||||||
.pytest_cache
|
|
||||||
**/.ipynb_checkpoints
|
|
||||||
**/tracing_database.json
|
|
||||||
*.egg-info
|
|
||||||
10
docs/great_ai_example-main/.vscode/settings.json
vendored
10
docs/great_ai_example-main/.vscode/settings.json
vendored
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"files.exclude": {
|
|
||||||
"**/__pycache__": true,
|
|
||||||
"**/.ipynb_checkpoints": true,
|
|
||||||
"**/.mypy_cache": true,
|
|
||||||
"**/.pytest_cache": true
|
|
||||||
},
|
|
||||||
"notebook.output.textLineLimit": 400,
|
|
||||||
"python.defaultInterpreterPath": ".env/bin/python"
|
|
||||||
}
|
|
||||||
21
docs/great_ai_example-main/.vscode/tasks.json
vendored
21
docs/great_ai_example-main/.vscode/tasks.json
vendored
|
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
"version": "2.0.0",
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"label": "Format and lint",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "source .env/bin/activate; ./format.sh .",
|
|
||||||
"windows": {
|
|
||||||
"command": ".env\\bin\\activate.bat; .\\format.sh ."
|
|
||||||
},
|
|
||||||
"group": "test",
|
|
||||||
"presentation": {
|
|
||||||
"reveal": "always",
|
|
||||||
"panel": "new"
|
|
||||||
},
|
|
||||||
"options": {
|
|
||||||
"cwd": "${workspaceFolder}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
FROM test
|
|
||||||
|
|
||||||
COPY requirements.txt .
|
|
||||||
RUN pip install --no-cache-dir ./great_ai
|
|
||||||
|
|
||||||
COPY mongo.ini .
|
|
||||||
COPY deploy.ipynb .
|
|
||||||
|
|
||||||
# RUN python3 -m large_file --backend s3 -secrets ~/.aws/credentials --cache my_first_file.json:3 my_second_file my_folder:0
|
|
||||||
|
|
||||||
CMD ["deploy.ipynb"]
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# Train a domain classifier on the [semantic scholar dataset](https://api.semanticscholar.org/corpus)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
### System dependencies
|
|
||||||
|
|
||||||
Make sure you have `python3`, `pip`, and `venv` installed.
|
|
||||||
> On Ubuntu, execute: `sudo apt install -y python3 python3-pip python3-venv`
|
|
||||||
|
|
||||||
### Install dependencies
|
|
||||||
```sh
|
|
||||||
python3 -m venv --copies .env
|
|
||||||
source .env/bin/activate
|
|
||||||
|
|
||||||
pip install -r requirements.txt
|
|
||||||
```
|
|
||||||
## Execute
|
|
||||||
|
|
||||||
- [Part 1](src/data.ipynb)
|
|
||||||
- [Part 2](src/train.ipynb)
|
|
||||||
- [Part 3](src/deploy.ipynb)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "Installing dependencies if necessary"
|
|
||||||
python3 -m pip install --upgrade autoflake isort black[jupyter] mypy flake8
|
|
||||||
|
|
||||||
echo "Formatting and checking $1"
|
|
||||||
|
|
||||||
cd $1
|
|
||||||
|
|
||||||
echo Running autoflake
|
|
||||||
python3 -m autoflake --expand-star-imports --remove-all-unused-imports --ignore-init-module-imports --remove-unused-variables --in-place -r .
|
|
||||||
|
|
||||||
echo Running isort
|
|
||||||
python3 -m isort --profile black --skip .env .
|
|
||||||
|
|
||||||
echo Running black
|
|
||||||
python3 -m black . --exclude .env
|
|
||||||
|
|
||||||
if ls *.py 1> /dev/null 2>&1; then
|
|
||||||
echo Running mypy
|
|
||||||
python3 -m mypy --namespace-packages --ignore-missing-imports --install-types --non-interactive --disallow-untyped-defs --disallow-incomplete-defs --pretty --follow-imports=silent --exclude=external/ --exclude=/build/ .
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo Running Flake8
|
|
||||||
python3 -m flake8 . --count --show-source --statistics --exclude=__init__.py,.env,external --ignore=E501,E722,E402,W503,E203
|
|
||||||
|
|
||||||
cd -
|
|
||||||
|
|
||||||
echo "Finished formatting"
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
great_ai
|
|
||||||
notebook
|
|
||||||
nbformat
|
|
||||||
nbconvert
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
mongo_connection_string=mongodb://localhost:27017/ # change this
|
|
||||||
mongo_database=great_ai_example # this will be automatically created
|
|
||||||
0
docs/how-to-guides/index.md
Normal file
0
docs/how-to-guides/index.md
Normal file
29
docs/how-to-guides/scraping.ipynb
Normal file
29
docs/how-to-guides/scraping.ipynb
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import httpx\n",
|
||||||
|
"\n",
|
||||||
|
"transport = httpx.AsyncHTTPTransport(retries=2)\n",
|
||||||
|
"limits = httpx.Limits(max_connections=None)\n",
|
||||||
|
"timeout = httpx.Timeout(connect=60.0, read=300, write=60, pool=None)\n",
|
||||||
|
"async with httpx.AsyncClient(\n",
|
||||||
|
" transport=transport, limits=limits, timeout=timeout\n",
|
||||||
|
") as client:\n",
|
||||||
|
" pass"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"language_info": {
|
||||||
|
"name": "python"
|
||||||
|
},
|
||||||
|
"orig_nbformat": 4
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,29 +1,30 @@
|
||||||
# Overview of GreatAI
|
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||||
|
<h1 style="margin: 0">Overview of GreatAI</h1>
|
||||||
|
<img src="media/logo.png" width=80>
|
||||||
|
</div>
|
||||||
|
|
||||||
[](https://github.com/schmelczer/great-ai/actions/workflows/check.yml)
|
[](https://github.com/schmelczer/great-ai/actions/workflows/check.yml)
|
||||||
[](https://sonar.schmelczer.com/dashboard?id=great-ai)
|
[](https://sonar.schmelczer.com/dashboard?id=great-ai)
|
||||||
[](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml)
|
[](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml)
|
||||||
[](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml)
|
[](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml)
|
||||||
[](https://pepy.tech/project/great-ai)
|
[](https://pepy.tech/project/great-ai)
|
||||||
|
|
||||||
|
|
||||||
Applying AI is becoming increasingly easier but many case studies have shown that these applications are often deployed poorly. This may lead to suboptimal performance and to introducing [unintended biases](https://en.wikipedia.org/wiki/Weapons_of_Math_Destruction){ target=_blank }. To extend the list of available solutions, ==GreatAI helps you easily transform your prototype AI code into production-ready software.==
|
Applying AI is becoming increasingly easier but many case studies have shown that these applications are often deployed poorly. This may lead to suboptimal performance and to introducing [unintended biases](https://en.wikipedia.org/wiki/Weapons_of_Math_Destruction){ target=_blank }. To extend the list of available solutions, ==GreatAI helps you easily transform your prototype AI code into production-ready software.==
|
||||||
|
|
||||||
??? quote "Case studies"
|
??? quote "Case studies"
|
||||||
"There is a need to consider and adapt well established SE practices which have been ignored or had a very narrow focus in ML literature."
|
"There is a need to consider and adapt well established SE practices which have been ignored or had a very narrow focus in ML literature."
|
||||||
— [John et al.](https://ieeexplore.ieee.org/abstract/document/9359253)
|
— [John et al.](https://ieeexplore.ieee.org/abstract/document/9359253){ target=_blank }
|
||||||
|
|
||||||
"Finally, we have found that existing tools to aid Machine Learning development do not address the specificities of different projects, and thus, are seldom adopted by teams." — [Haakman et al.](https://link.springer.com/article/10.1007/s10664-021-09993-1)
|
"Finally, we have found that existing tools to aid Machine Learning development do not address the specificities of different projects, and thus, are seldom adopted by teams." — [Haakman et al.](https://link.springer.com/article/10.1007/s10664-021-09993-1){ target=_blank }
|
||||||
|
|
||||||
"Because a mature system might end up being (at most) 5% machine learning code and (at least) 95% glue code, it may be less costly to create a clean native solution rather than re-use a generic package." — [Sculley et al.](https://www.researchgate.net/profile/Todd-Phillips/publication/319769912_Hidden_Technical_Debt_in_Machine_Learning_Systems/links/61e716d68d338833e37a7fd6/Hidden-Technical-Debt-in-Machine-Learning-Systems.pdf)
|
|
||||||
|
|
||||||
"For example, practice 25 is very important for “Traceability", yet relatively weakly adopted. We expect that the results from this type of analysis can, in the future, provide useful guidance for practitioners in terms of aiding them to assess their rate of adoption for each practice and to create roadmaps for improving their processes. — [Serban et al.](https://dl.acm.org/doi/abs/10.1145/3382494.3410681?casa_token=uCFz0dtDR6gAAAAA:4_8OMJ-5njwopYkB1KSGAu9JfbNq4nfa8LRE0fj84ckjfo-GgtcYQivZTGxal3M4haoA8r_xwpw)
|
|
||||||
|
|
||||||
|
"Because a mature system might end up being (at most) 5% machine learning code and (at least) 95% glue code, it may be less costly to create a clean native solution rather than re-use a generic package." — [Sculley et al.](https://www.researchgate.net/profile/Todd-Phillips/publication/319769912_Hidden_Technical_Debt_in_Machine_Learning_Systems/links/61e716d68d338833e37a7fd6/Hidden-Technical-Debt-in-Machine-Learning-Systems.pdf){ target=_blank }
|
||||||
|
|
||||||
|
"For example, practice 25 is very important for “Traceability", yet relatively weakly adopted. We expect that the results from this type of analysis can, in the future, provide useful guidance for practitioners in terms of aiding them to assess their rate of adoption for each practice and to create roadmaps for improving their processes. — [Serban et al.](https://dl.acm.org/doi/abs/10.1145/3382494.3410681?casa_token=uCFz0dtDR6gAAAAA:4_8OMJ-5njwopYkB1KSGAu9JfbNq4nfa8LRE0fj84ckjfo-GgtcYQivZTGxal3M4haoA8r_xwpw){ target=_blank }
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- [x] Save prediction traces of each prediction including arguments and model versions
|
- [x] Save prediction traces of each prediction including arguments and model versions
|
||||||
- [x] Save feedback and merge it into a ground-truth database
|
- [x] Save feedback and merge it into a ground-truth database *:arrow_right: quasi-shadow deployment*
|
||||||
- [x] Version and store models and data on shared infrastructure *(MongoDB GridFS, S3-compatible storage, shared local-volume)*
|
- [x] Version and store models and data on shared infrastructure *(MongoDB GridFS, S3-compatible storage, shared local-volume)*
|
||||||
- [x] Automatically scaffolded custom REST API (and OpenAPI schema) for easy integration
|
- [x] Automatically scaffolded custom REST API (and OpenAPI schema) for easy integration
|
||||||
- [x] Input validation
|
- [x] Input validation
|
||||||
|
|
@ -33,11 +34,11 @@ Applying AI is becoming increasingly easier but many case studies have shown tha
|
||||||
- [x] Built-in parallelisation (with support for multiprocessing, async, and mixed modes) for batch processing
|
- [x] Built-in parallelisation (with support for multiprocessing, async, and mixed modes) for batch processing
|
||||||
- [x] Well-tested utilities for common NLP tasks (cleaning, language-tagging, sentence-segmentation, etc.)
|
- [x] Well-tested utilities for common NLP tasks (cleaning, language-tagging, sentence-segmentation, etc.)
|
||||||
- [x] A simple, unified configuration interface
|
- [x] A simple, unified configuration interface
|
||||||
- [x] Fully-typed API for IntelliSense support
|
- [x] Fully-typed API for [Pylance](https://github.com/microsoft/pylance-release){ target=_blank } and [MyPy](http://mypy-lang.org){ target=_blank } support
|
||||||
- [x] Auto-reload for development
|
- [x] Auto-reload for development
|
||||||
|
- [x] Deployable Jupyter Notebooks
|
||||||
- [x] Docker support for deployment
|
- [x] Docker support for deployment
|
||||||
- [x] Dashboard for high-level overview and searching traces
|
- [x] Dashboard for high-level overview and searching traces
|
||||||
- [ ] Shadow deployment
|
|
||||||
|
|
||||||
## Hello world
|
## Hello world
|
||||||
|
|
||||||
|
|
@ -66,7 +67,7 @@ def hello_world(name: str) -> str: #(2)
|
||||||
```sh title="terminal"
|
```sh title="terminal"
|
||||||
great-ai hello-world.py
|
great-ai hello-world.py
|
||||||
```
|
```
|
||||||
> Navigate to [localhost:6060](http://127.0.0.1:6060/) in your browser.
|
> Navigate to [localhost:6060](http://127.0.0.1:6060) in your browser.
|
||||||
|
|
||||||
<div style="display: flex; justify-content: space-evenly;" markdown>
|
<div style="display: flex; justify-content: space-evenly;" markdown>
|
||||||
{ loading=lazy }
|
{ loading=lazy }
|
||||||
|
|
@ -75,14 +76,13 @@ great-ai hello-world.py
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
!!! success
|
!!! success
|
||||||
Your GreatAI service is ready for production use. Many of the [SE4ML best-practices](https://se-ml.github.io/){ target=_blank } are configured and implemented automatically. To have full control over your service and to understand what else you might need to do in your use case, continue reading this documentation.
|
Your GreatAI service is ready for production use. Many of the [SE4ML best-practices](https://se-ml.github.io){ target=_blank } are configured and implemented automatically. To have full control over your service and to understand what else you might need to do in your use case, continue reading this documentation.
|
||||||
|
|
||||||
|
|
||||||
## Why is this GREAT?
|
## Why is this GREAT?
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
GreatAI fits between the prototype and deployment phase of your (or your organisation's) AI development lifecycle. This is highlighted with blue in the diagram. Here, a number of best practices can be automatically implemented concerning the following 5 aspects:
|
GreatAI fits between the prototype and deployment phase of your (or your organisation's) AI development lifecycle. This is highlighted with blue in the diagram. Here, a number of best practices can be automatically implemented aiming to achieve the following attributes:
|
||||||
|
|
||||||
- **G**eneral: use any Python library without restriction
|
- **G**eneral: use any Python library without restriction
|
||||||
- **R**obust: have error-handling and well-tested utilities out-of-the-box
|
- **R**obust: have error-handling and well-tested utilities out-of-the-box
|
||||||
|
|
@ -92,13 +92,20 @@ GreatAI fits between the prototype and deployment phase of your (or your organis
|
||||||
|
|
||||||
## Why GreatAI?
|
## Why GreatAI?
|
||||||
|
|
||||||
There are other, existing solutions aiming to facilitate this phase. [Amazon SageMaker](https://aws.amazon.com/sagemaker/){ target=_blank } and [Seldon Core](https://www.seldon.io/solutions/open-source-projects/core){ target=_blank } provide the most comprehensive suite of features. If you have the opportunity use those, do that because they're great.
|
There are other, existing solutions aiming to facilitate this phase. [Amazon SageMaker](https://aws.amazon.com/sagemaker){ target=_blank } and [Seldon Core](https://www.seldon.io/solutions/open-source-projects/core){ target=_blank } provide the most comprehensive suite of features. If you have the opportunity use those, do that because they're great.
|
||||||
|
|
||||||
However, research indicates that professionals rarely use them. This may be due to their inherent setup and operating complexity. GreatAI is designed to be as simple to use as possible. Its clear, high-level API and sensible default configuration makes it extremely easy to start using. Despite its relative simplicity over Seldon Core, it still implements many [best-practices](https://se-ml.github.io/){ target=_blank }, and thus, can meaningfully improve your deployment without requiring prohibitively large effort.
|
However, research indicates that professionals rarely use them. This may be due to their inherent setup and operating complexity. GreatAI is designed to be as simple to use as possible. Its clear, high-level API and sensible default configuration makes it extremely easy to start using. Despite its relative simplicity over Seldon Core, it still implements many [best-practices](https://se-ml.github.io){ target=_blank }, and thus, can meaningfully improve your deployment without requiring prohibitively large effort.
|
||||||
|
|
||||||
|
|
||||||
<div style="display: flex; justify-content: space-evenly;" markdown>
|
<div style="display: flex; justify-content: space-evenly;" markdown>
|
||||||
[:fontawesome-brands-python: Find it on PyPI](https://pypi.org/project/great-ai/){ .md-button .md-button--primary }
|
[:fontawesome-brands-python: Find it on PyPI](https://pypi.org/project/great-ai){ .md-button .md-button--primary }
|
||||||
|
|
||||||
[:fontawesome-brands-docker: Find it on DockerHub](https://hub.docker.com/repository/docker/schmelczera/great-ai){ .md-button .md-button--primary }
|
[:fontawesome-brands-docker: Find it on DockerHub](https://hub.docker.com/repository/docker/schmelczera/great-ai){ .md-button .md-button--primary }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
## Production use
|
||||||
|
|
||||||
|
GreatAI has been battle-tested on the core platform services of [ScoutinScience](https://www.scoutinscience.com/){ target=_blank }.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
|
||||||
BIN
docs/media/favicon.ico
Normal file
BIN
docs/media/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
docs/media/logo.png
Normal file
BIN
docs/media/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
212
docs/media/scope-data.drawio.svg
Normal file
212
docs/media/scope-data.drawio.svg
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1181px" height="281px" viewBox="-0.5 -0.5 1181 281" content="<mxfile><diagram id="ccudx8biEBM-x_P_p45R" name="Page-1">3VrbcuI4EP0aqpKHpHzBBh7ZwMxuVVKTKnZrJo+yJUAV2/JIIsH79duy5bsJ5jqZ5QFLLaktqfucbgkG9kO4/cpRvH5imAQDy8DbgT0bWJZpWSN4KEmSScYjLVhxinWnUrCg/xItNLR0QzERtY6SsUDSuC70WRQRX9ZkiHP2Xu+2ZEH9rTFakZZg4aOgLf1OsVzrVeTLUvI/CV2t8zeb7iRrCVHeWa9ErBFm7xWRPR/YD5wxmZXC7QMJ1Obl+5KN+7KjtZgYJ5HsM0DPWMgkXxvBsFRdjVgEjz/WMgygZkJxySKp7WEOod5+n56CYBvua5WWNhHiK6J7DTORelllmJ7jV8JCInkCHTgJkKRv9X1H2nyrol+5QijoRXYvWM/lDQUbrXRguYHUS6tthftzw/KGO5EuegodzGG8LRuhtFLPZ05iznwiBMHKs5FEuWKYUqY769nacfCBWBX9JKARJtyGTu9rKskiRukWvgOK6mbw2AZ64kevECD/dcWV9NtGghqi5ULbyvnIVm+ES7L90A661Z642RANXDv34/cSBia8LJWtqxAwjNNt5x7orLBOnvyAipFXXlTl3smrs221cZZUa8+EU5gh4Vp4lOfbbc+3fpXn2zs93ytd8xxQmKW+byD/54YKKimLdiKhELem4PFccqP1zaMV+DVYJVrd7sQQ2AMFAQnYiqMQBscVK9baKubdB7Yl3ZI8CJnnwZE5Nuo4sjtwlPep4mh8BhiNr8H5w7bnO7/K84fX8vz5Ng4YR5nLg6VcFCpfyr7bnl10iDyhHqFOlLwNDTC4+Vlgs/ApiXzy20PGcRqhpwsy7oUgY9pXCj1NrGEk1gTnSrdU/ijVQO2l0lJqVJWkUmmGsl4AdtoAnpwbwOnQKecoqXSIGY2kqGh+VoLSEcZWnTuHY6Nhykxjadhiar1s7VwoQ/ybI4hfKjlMcS6a6O9iDANySslkAkCFCUZLwhWW05MNJv/D/HI0HO3PL4eXyi/N4edFuXE1lOeH7DPDvIXjkdvAsdUwYTZPPap6hm0ocsy6IqfJ+NnqWopOJR7LPS/xmO7+PGVGIMNIUkAAHpSroggjjvcnF4yvUERFmpwg9VqY2Zph0S+bOJgCrS4KbM7pZpGIKQ4pZEuwO8a3WGSFGXmD8u2hBHeNTKZ3MnzAYcAc7k9tCnI6d2pTsMKxx4FO8srLFT7cTV7HHtOPJT1z0sF67nVYb+zUSWTUDFy9Wa9xhHTNfqx3BDF1Xpo1fEYlBymy2SPySO4r/dFRXNYiL1dpdBtAj5o02bgTNB3ngbOgZrKfqv8RKlFD6iQ4/Qu+cErdIUmN2GbYBUILeOtz+jCuyco3T4/zp4x4p6+vlGVFIv3723aO+jsycuG/+yk5d6aOvLPTmdxzpJ3GR850wnEjEkvGw/QiAQ4Pku1PEuC4gTe+ShHuOEFY7Ygg/I36pJ9DgitlgfuT+IOVtgfBAwsYT6dimx4yiaX7VeTL9KOONJKzV1JpMQx3Pv1yqmddxZNOvdo7/bqhiOVl+H6ptp0Uy4u4syeYX+aiohWC70ZOd952aCy/MxuKep5gjonlXT8DHOwzOTowWaJNID+XsXqjZXcQP+2mZ8olXSJfpklN6NEoo2C5VglBfsmrD3AqK0iYzgo8IuRdzGEoMK44NNhe+n7nkxCpbrVG93XQTDquipxLXRUVv98fflV0IDH2+S3yGKbuCVijDVjzWoiFavlPiIzryv+T2PP/AA==</diagram></mxfile>">
|
||||||
|
<defs/>
|
||||||
|
<g>
|
||||||
|
<path d="M 331 140 L 379.63 140" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
|
||||||
|
<path d="M 384.88 140 L 377.88 143.5 L 379.63 140 L 377.88 136.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<path d="M 216 105 C 216 96.72 241.74 90 273.5 90 C 288.75 90 303.38 91.58 314.16 94.39 C 324.94 97.21 331 101.02 331 105 L 331 175 C 331 183.28 305.26 190 273.5 190 C 241.74 190 216 183.28 216 175 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<path d="M 331 105 C 331 113.28 305.26 120 273.5 120 C 241.74 120 216 113.28 216 105" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<g transform="translate(-0.5 -0.5)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 113px; height: 1px; padding-top: 153px; margin-left: 217px;">
|
||||||
|
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
|
||||||
|
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
|
||||||
|
<font style="font-size: 14px">
|
||||||
|
Preprocessed data
|
||||||
|
</font>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="274" y="157" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
|
||||||
|
Preprocessed data
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
<path d="M 170 140 L 209.63 140" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
|
||||||
|
<path d="M 214.88 140 L 207.88 143.5 L 209.63 140 L 207.88 136.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<path d="M 0 180 L 20 100 L 180 100 L 160 180 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<g transform="translate(-0.5 -0.5)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 140px; margin-left: 1px;">
|
||||||
|
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
|
||||||
|
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
|
||||||
|
<b>
|
||||||
|
<font style="font-size: 14px">
|
||||||
|
Data acquisition
|
||||||
|
</font>
|
||||||
|
</b>
|
||||||
|
<br/>
|
||||||
|
(Data Engineering)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="90" y="144" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
|
||||||
|
Data acquisition...
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
<path d="M 526 140 L 560.63 140" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/>
|
||||||
|
<path d="M 565.88 140 L 558.88 143.5 L 560.63 140 L 558.88 136.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<path d="M 376 180 L 396 100 L 536 100 L 516 180 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<g transform="translate(-0.5 -0.5)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 140px; margin-left: 377px;">
|
||||||
|
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
|
||||||
|
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
|
||||||
|
<b>
|
||||||
|
<font style="font-size: 14px">
|
||||||
|
Exploration &
|
||||||
|
<br/>
|
||||||
|
model building
|
||||||
|
</font>
|
||||||
|
</b>
|
||||||
|
<br/>
|
||||||
|
(Data Science)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="456" y="144" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
|
||||||
|
Exploration &...
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
<path d="M 639.5 190 L 639.92 240 Q 640 250 650 250 L 743.63 250" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/>
|
||||||
|
<path d="M 748.88 250 L 741.88 253.5 L 743.63 250 L 741.88 246.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<path d="M 567 105 C 567 96.72 599.46 90 639.5 90 C 658.73 90 677.17 91.58 690.77 94.39 C 704.36 97.21 712 101.02 712 105 L 712 175 C 712 183.28 679.54 190 639.5 190 C 599.46 190 567 183.28 567 175 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<path d="M 712 105 C 712 113.28 679.54 120 639.5 120 C 599.46 120 567 113.28 567 105" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<g transform="translate(-0.5 -0.5)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 143px; height: 1px; padding-top: 153px; margin-left: 568px;">
|
||||||
|
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
|
||||||
|
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
|
||||||
|
<font style="font-size: 14px">
|
||||||
|
Trained models & prototype inference code
|
||||||
|
</font>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="640" y="157" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
|
||||||
|
Trained models & protot...
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
<path d="M 639.5 90 L 639.92 40 Q 640 30 650 30 L 743.63 30" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/>
|
||||||
|
<path d="M 748.88 30 L 741.88 33.5 L 743.63 30 L 741.88 26.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<path d="M 966 180 L 986 100 L 1180 100 L 1160 180 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<g transform="translate(-0.5 -0.5)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 212px; height: 1px; padding-top: 140px; margin-left: 967px;">
|
||||||
|
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
|
||||||
|
<div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
|
||||||
|
<b>
|
||||||
|
Deploy with standard
|
||||||
|
<br/>
|
||||||
|
organisational methods
|
||||||
|
</b>
|
||||||
|
<br/>
|
||||||
|
<font style="font-size: 12px">
|
||||||
|
(SysAdmin, Ops, DevOps)
|
||||||
|
</font>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="1073" y="144" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="14px" text-anchor="middle">
|
||||||
|
Deploy with standard...
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
<path d="M 922.5 140 L 969.63 140" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/>
|
||||||
|
<path d="M 974.88 140 L 967.88 143.5 L 969.63 140 L 967.88 136.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/>
|
||||||
|
<path d="M 740 280 L 760 220 L 950 220 L 930 280 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/>
|
||||||
|
<g transform="translate(-0.5 -0.5)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 208px; height: 1px; padding-top: 250px; margin-left: 741px;">
|
||||||
|
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
|
||||||
|
<div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">
|
||||||
|
<b>
|
||||||
|
Use an AI deployment
|
||||||
|
<br/>
|
||||||
|
SaaS/PaaS
|
||||||
|
</b>
|
||||||
|
<br/>
|
||||||
|
<font style="font-size: 12px">
|
||||||
|
(MLEM, Akkio, etc.)
|
||||||
|
</font>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="845" y="254" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="14px" text-anchor="middle">
|
||||||
|
Use an AI deployment...
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
<path d="M 740 60 L 760 0 L 950 0 L 930 60 Z" fill="#1ba1e2" stroke="#006eaf" stroke-miterlimit="10" pointer-events="none"/>
|
||||||
|
<g transform="translate(-0.5 -0.5)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 208px; height: 1px; padding-top: 30px; margin-left: 741px;">
|
||||||
|
<div data-drawio-colors="color: #ffffff; " style="box-sizing: border-box; font-size: 0px; text-align: center;">
|
||||||
|
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">
|
||||||
|
<b style="font-size: 14px">
|
||||||
|
Transforming into
|
||||||
|
<br/>
|
||||||
|
production-ready service
|
||||||
|
</b>
|
||||||
|
<br/>
|
||||||
|
(MLOps)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="845" y="34" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">
|
||||||
|
Transforming into...
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
<path d="M 845 190 L 845 213.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"/>
|
||||||
|
<path d="M 845 218.88 L 841.5 211.88 L 845 213.63 L 848.5 211.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/>
|
||||||
|
<path d="M 845 190 L 845 213.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/>
|
||||||
|
<path d="M 845 218.88 L 841.5 211.88 L 845 213.63 L 848.5 211.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/>
|
||||||
|
<path d="M 767.5 105 C 767.5 96.72 802.2 90 845 90 C 865.55 90 885.27 91.58 899.8 94.39 C 914.33 97.21 922.5 101.02 922.5 105 L 922.5 175 C 922.5 183.28 887.8 190 845 190 C 802.2 190 767.5 183.28 767.5 175 Z" fill="#1ba1e2" stroke="#006eaf" stroke-miterlimit="10" pointer-events="none"/>
|
||||||
|
<path d="M 922.5 105 C 922.5 113.28 887.8 120 845 120 C 802.2 120 767.5 113.28 767.5 105" fill="none" stroke="#006eaf" stroke-miterlimit="10" pointer-events="none"/>
|
||||||
|
<g transform="translate(-0.5 -0.5)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 153px; height: 1px; padding-top: 153px; margin-left: 769px;">
|
||||||
|
<div data-drawio-colors="color: #ffffff; " style="box-sizing: border-box; font-size: 0px; text-align: center;">
|
||||||
|
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">
|
||||||
|
<font style="font-size: 14px">
|
||||||
|
Artifact combining the model with deplyoment best-practices
|
||||||
|
</font>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="845" y="157" fill="#ffffff" font-family="Helvetica" font-size="12px" text-anchor="middle">
|
||||||
|
Artifact combining the mod...
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
<path d="M 845 60 L 845 83.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/>
|
||||||
|
<path d="M 845 88.88 L 841.5 81.88 L 845 83.63 L 848.5 81.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/>
|
||||||
|
</g>
|
||||||
|
<switch>
|
||||||
|
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
|
||||||
|
<a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
|
||||||
|
<text text-anchor="middle" font-size="10px" x="50%" y="100%">
|
||||||
|
Viewer does not support full SVG 1.1
|
||||||
|
</text>
|
||||||
|
</a>
|
||||||
|
</switch>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 19 KiB |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue