New upstream version 3.0.0+dfsg1
Louis-Philippe Véronneau
1 year, 5 months ago
0 | name: Lint | |
1 | ||
2 | permissions: | |
3 | contents: write | |
4 | ||
5 | on: | |
6 | push: | |
7 | branches: | |
8 | - main | |
9 | ||
10 | jobs: | |
11 | lint: | |
12 | runs-on: ubuntu-latest | |
13 | steps: | |
14 | - name: Checkout code | |
15 | uses: actions/checkout@v3 | |
16 | ||
17 | - uses: actions/setup-python@v3 | |
18 | with: | |
19 | python-version: "3.10" | |
20 | ||
21 | - name: Run isort check | |
22 | uses: isort/isort-action@master | |
23 | with: | |
24 | configuration: "--check-only --diff --profile black" | |
25 | ||
26 | - name: Run isort | |
27 | if: failure() | |
28 | uses: isort/isort-action@master | |
29 | with: | |
30 | configuration: "--profile black" | |
31 | ||
32 | - name: Run black check | |
33 | uses: psf/black@stable | |
34 | with: | |
35 | options: "--check --diff" | |
36 | ||
37 | - name: Run black format | |
38 | if: failure() | |
39 | uses: psf/black@stable | |
40 | with: | |
41 | options: "" | |
42 | ||
43 | - name: Commit isort+black format | |
44 | if: failure() | |
45 | uses: stefanzweifel/git-auto-commit-action@v4 | |
46 | with: | |
47 | commit_message: "Apply black to code" | |
48 |
0 | name: Test | |
1 | ||
2 | on: [push, pull_request] | |
3 | ||
4 | env: | |
5 | FORCE_COLOR: 1 | |
6 | ||
7 | jobs: | |
8 | build: | |
9 | runs-on: ${{ matrix.os }} | |
10 | strategy: | |
11 | fail-fast: false | |
12 | matrix: | |
13 | python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] | |
14 | os: [ubuntu-22.04] | |
15 | env: | |
16 | - TOXENV: libs | |
17 | - TOXENV: sa12 | |
18 | - TOXENV: sa13 | |
19 | ||
20 | steps: | |
21 | - uses: actions/checkout@v2 | |
22 | ||
23 | - name: Set up Python ${{ matrix.python-version }} | |
24 | uses: actions/setup-python@v4 | |
25 | with: | |
26 | python-version: ${{ matrix.python-version }} | |
27 | ||
28 | - name: Get pip cache dir | |
29 | id: pip-cache | |
30 | run: | | |
31 | echo "::set-output name=dir::$(pip cache dir)" | |
32 | ||
33 | - name: Cache | |
34 | uses: actions/cache@v3 | |
35 | with: | |
36 | path: ${{ steps.pip-cache.outputs.dir }} | |
37 | key: | |
38 | ${{ matrix.os }}-${{ matrix.python-version }}-v1-${{ | |
39 | hashFiles('**/setup.py') }} | |
40 | restore-keys: | | |
41 | ${{ matrix.os }}-${{ matrix.python-version }}-v1- | |
42 | ||
43 | - name: Install dependencies | |
44 | run: | | |
45 | python -m pip install -U pip | |
46 | python -m pip install -U tox tox-venv | |
47 | ||
48 | - name: Install gmpy2 dependencies | |
49 | if: matrix.python-version == '3.11' | |
50 | run: | | |
51 | sudo apt-get -y update | |
52 | sudo apt-get install -y libmpfr-dev libmpc-dev | |
53 | ||
54 | - name: Tox tests | |
55 | run: | | |
56 | tox | |
57 | env: ${{ matrix.env }} |
1 | 1 | /build |
2 | 2 | /dist |
3 | 3 | /docs/build |
4 | /images/benchmark-*.svg | |
4 | 5 | /.eggs |
5 | 6 | /env* |
6 | 7 | /tags |
14 | 15 | *#* |
15 | 16 | *~ |
16 | 17 | *.tar.gz |
18 | ||
19 | # Local benchmarking files for Theelx | |
20 | kern*.py | |
21 | *.lprof |
0 | 0 | repos: |
1 | 1 | - repo: https://github.com/psf/black |
2 | rev: 19.10b0 | |
2 | rev: 22.3.0 | |
3 | 3 | hooks: |
4 | 4 | - id: black |
5 | 5 |
0 | dist: bionic | |
1 | language: python | |
2 | ||
3 | python: | |
4 | - 2.7 | |
5 | - 3.6 | |
6 | - 3.7 | |
7 | - 3.8 | |
8 | - &latest_py3 3.9 | |
9 | ||
10 | env: | |
11 | - TOXENV=libs | |
12 | - TOXENV=sa10 | |
13 | - TOXENV=sa11 | |
14 | - TOXENV=sa12 | |
15 | - TOXENV=sa13 | |
16 | ||
17 | cache: pip | |
18 | ||
19 | install: | |
20 | - pip install tox tox-venv | |
21 | ||
22 | before_script: | |
23 | # Enable IPv6. Ref travis-ci/travis-ci#8361 | |
24 | - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then | |
25 | sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6'; | |
26 | fi | |
27 | script: tox |
0 | ***WARNING: CERTAIN BENCHMARKS WILL SHOW VERY HIGH OUTLIER VALUES, TAKE ALL BENCHMARKS WITH A GRAIN OF SALT.*** | |
1 | ||
2 | **TL;DR** | |
3 | ||
4 | jsonpickle 2.0.0 shows significant improvement in encoding/decoding speeds for virtually every test, the main benefits come in class encoding/decoding, but there are more minor speedups for other common use cases also. Onto the raw data! | |
5 | ||
6 | Environment: | |
7 | - Python 3.9.13 | |
8 | - 8-core Intel i7-11800H CPU (laptop) | |
9 | - Ubuntu 20.04, Linux kernel 5.17.9 (kernel mainline ppa) | |
10 | - Turbo boost disabled, plugged in + on battery | |
11 | ||
12 | Make note of: | |
13 | - If a benchmark ends with `_e`, it's an encode benchmark, if it ends with `_d` then it's a decode benchmark | |
14 | - `homog` is short for homogenous, and `heterog` is short for heterogenous | |
15 | ||
16 | jsonpickle 3.0.0-dev (drops support for python <3.7) | |
17 | ||
18 | <figure><img src="images/jsonpickle-3.0.0-dev.svg"></figure> | |
19 | ||
20 | jsonpickle 2.2.0 (latest release of writing) | |
21 | ||
22 | <figure><img src="images/jsonpickle-2.2.0.svg"></figure> | |
23 | ||
24 | jsonpickle 1.5.2 (major performance increases reverted due to accidental breaking change) | |
25 | ||
26 | <figure><img src="images/jsonpickle-1.5.2.svg"></figure> | |
27 | ||
28 | jsonpickle 1.5.1 (major performance increases in this version) | |
29 | ||
30 | <figure><img src="images/jsonpickle-1.5.1.svg"></figure> | |
31 | ||
32 | jsonpickle 0.9.6 (please upgrade from this!) | |
33 | ||
34 | <figure><img src="images/jsonpickle-0.9.6.svg"></figure> |
0 | .. warning:: | |
1 | The next major release of jsonpickle (v3.0.0) will drop support for | |
2 | Python 3.6 and earlier (including Python 2.7). | |
3 | ||
4 | .. note:: | |
5 | Users on older Python versions should pin requirements to ``jsonpickle<3.0.0``. | |
6 | ||
7 | v3.0.0 | |
8 | ====== | |
9 | * Drop support for CPython<3.7. CPython 3.6 and below have reached EOL | |
10 | and no longer receieve security updates. (#375) | |
11 | * Add support for CPython 3.11. (#395) (+396) | |
12 | * Remove jsonlib and yajl backends (py2 only) | |
13 | * Add ``include_properties`` option to the pickler. This should only | |
14 | be used if analyzing generated json outside of Python. (#297) (+387) | |
15 | * Allow the ``classes`` argument to ``jsonpickle.decode`` to be a dict | |
16 | of class name to class object. This lets you decode arbitrary dumps | |
17 | into different classes. (#148) (+392) | |
18 | * Fix bug with deserializing `numpy.poly1d`. (#391) | |
19 | * Allow frozen dataclasses to be deserialized. (#240) | |
20 | * Fixed a bug where pickling a function could return a ``None`` module. (#399) | |
21 | * Removed old bytes/quopri and ref decoding abaility from the unpickler. | |
22 | These were last used in jsonpickle<1. Removing them causes a slight speedup | |
23 | in unpickling lists (~5%). (+403) | |
24 | * Fixed a bug with namedtuples encoding on CPython 3.11. (#411) | |
25 | * When using the ``sort_keys`` option for the ``simplejson`` backend, | |
26 | jsonpickle now produces correct object references with py/id tags. (#408) | |
27 | * Speed up the internal method ``_restore_tags`` by ~10%. This should speed | |
28 | up unpickling of almost every object. | |
29 | ||
30 | v2.2.0 | |
31 | ====== | |
32 | ||
33 | * Classes with a custom ``__getitem__()`` and ``append()`` | |
34 | now pickle properly. (#362) (+379) | |
35 | * Remove the demjson backend, as demjson hasn't been maintained | |
36 | for 5 years. (+379) | |
37 | * Added new handler for numpy objects when using unpickleable=False. | |
38 | (#381) (+382) | |
39 | * Added exception handling for class attributes that can't be accessed. | |
40 | (#301) (+383) | |
41 | * Added a long-requested on_missing attribute to the Unpickler class. | |
42 | This lets you choose behavior for when jsonpickle can't find a class | |
43 | to deserialize to. (#190) (#193) (+384) | |
44 | * Private members of ``__slots__`` are no longer skipped when encoding. | |
45 | Any objects encoded with versions prior to 2.2.0 should still decode | |
46 | properly. (#318) (+385) | |
47 | ||
48 | v2.1.0 | |
49 | ====== | |
50 | ||
51 | * Python 3.10 is now officially supported. (+376) | |
52 | * Benchmarks were added to aid in optimization efforts. (#350) (+352) | |
53 | * ``is_reducible()`` was sped up by ~80%. (+353) (+354) | |
54 | * ``_restore_tags()`` was sped up by ~100%. Unpickling items | |
55 | with a lot of tuples and sets will benefit most. Python 2 users | |
56 | and users deserializing pickles from jsonpickle <= 0.9.6 may see | |
57 | a slight performance decrease if using a lot of bytes, ref, | |
58 | and/or repr objects. (+354) | |
59 | * ``is_iterator()`` was sped up by ~20% by removing an unnecessary | |
60 | variable assignment. (+354) | |
61 | * ``jsonpickle.decode`` has a new option, ``v1_decode`` to assist in | |
62 | decoding objects created in jsonpickle version 1. (#364) | |
63 | * The ``encode()`` documentation has been updated to help sklearn users. | |
64 | * ``demjson`` has been removed from the test suite. (+374) | |
65 | * ``SQLALchemy<1.2`` is no longer being tested by jsonpickle. | |
66 | Users of sqlalchemy + jsonpickle can always use 1.2 or 1.3. | |
67 | When jsonpickle v3 is released we will add SQLAlchemy 1.4 to | |
68 | the test suite alongside removal of support for Python 3.5 and earlier. | |
69 | ||
0 | 70 | v2.0.0 |
1 | 71 | ====== |
2 | 72 | * Major release: the serialized JSON format now preserves dictionary |
5 | 75 | dictionary appears twice in a list, the reconstituted list |
6 | 76 | will now contain two references to the same dictionary. (#255) (+332) |
7 | 77 | |
8 | v1.5.3 | |
78 | v1.5.2 | |
9 | 79 | ====== |
10 | 80 | * Patch release to avoid the change in behavior from the preservation |
11 | 81 | of dict identity. The next release will be v2.0.0. (#351) |
12 | * This relese does *not* include the performance improvements | |
82 | * This release does *not* include the performance improvements | |
13 | 83 | from v1.5.1. |
14 | 84 | * Pandas DataFrame objects with multilevel columns are now supported. |
15 | 85 | (#346) (+347) |
296 | 366 | (#16). |
297 | 367 | * Experimental support for `jsonlib <http://pypi.python.org/pypi/jsonlib/>`_ |
298 | 368 | and `py-yajl <http://github.com/rtyler/py-yajl/>`_ backends. |
299 | * New contributers David K. Hess and Alec Thomas | |
369 | * New contributors David K. Hess and Alec Thomas | |
300 | 370 | |
301 | 371 | .. warning:: |
302 | 372 |
0 | 0 | Copyright (C) 2008 John Paulett (john -at- paulett.org) |
1 | Copyright (C) 2009-2018 David Aguilar (davvid -at- gmail.com) | |
2 | All rights reserved. | |
1 | Copyright (C) 2009-2021 David Aguilar (davvid -at- gmail.com) | |
3 | 2 | |
4 | 3 | Redistribution and use in source and binary forms, with or without |
5 | modification, are permitted provided that the following conditions | |
6 | are met: | |
4 | modification, are permitted provided that the following conditions are met: | |
7 | 5 | |
8 | 1. Redistributions of source code must retain the above copyright | |
9 | notice, this list of conditions and the following disclaimer. | |
10 | 2. Redistributions in binary form must reproduce the above copyright | |
11 | notice, this list of conditions and the following disclaimer in | |
12 | the documentation and/or other materials provided with the | |
13 | distribution. | |
14 | 3. The name of the author may not be used to endorse or promote | |
15 | products derived from this software without specific prior | |
16 | written permission. | |
6 | 1. Redistributions of source code must retain the above copyright notice, | |
7 | this list of conditions and the following disclaimer. | |
17 | 8 | |
18 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | |
19 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
21 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |
24 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
25 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | |
26 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
27 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | |
28 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
9 | 2. Redistributions in binary form must reproduce the above copyright notice, | |
10 | this list of conditions and the following disclaimer in the documentation | |
11 | and/or other materials provided with the distribution. | |
12 | ||
13 | 3. Neither the name of the copyright holder nor the names of its | |
14 | contributors may be used to endorse or promote products derived from this | |
15 | software without specific prior written permission. | |
16 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
18 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
19 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
20 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | |
21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
24 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
25 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
26 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | |
27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
0 | 0 | #!/usr/bin/env make |
1 | ||
2 | DATEANDTIME=$(shell date +%Y-%m-%dT%T%z) | |
1 | 3 | |
2 | 4 | # External commands |
3 | 5 | BLACK ?= black |
5 | 7 | FIND ?= find |
6 | 8 | PYTHON ?= python |
7 | 9 | PYTEST ?= $(PYTHON) -m pytest |
10 | SPHINX ?= $(PYTHON) -m sphinx | |
11 | BENCHMARK ?= py.test | |
8 | 12 | RM_R ?= rm -fr |
9 | 13 | SH ?= sh |
10 | 14 | TOX ?= tox |
33 | 37 | NUM_JOBS := $(shell printf %s "$(DASH_J)" | sed -e 's/-j//') |
34 | 38 | |
35 | 39 | TESTCMD ?= $(PYTEST) |
40 | BENCHMARKCMD ?= $(BENCHMARK) | |
36 | 41 | TOXCMD ?= $(TOX) |
37 | 42 | TOXCMD += --develop --skip-missing-interpreters |
38 | 43 | ifdef multi |
39 | 44 | TOXCMD += --parallel $(NUM_JOBS) |
40 | 45 | TOXCMD += -e |
41 | TOXCMD += 'clean,py{27,36,37,38,39},py{27,38,39}-sa{10,11,12,13},py{27,38,39}-libs' | |
46 | TOXCMD += 'clean,py{37,38,39,310},py{38,39,310}-sa{12,13},py{38,39,310}-libs' | |
42 | 47 | # Disable coverage when running in parallel |
43 | 48 | TOXCMD += -- --no-cov |
44 | 49 | endif |
45 | 50 | ifdef V |
46 | 51 | TESTCMD += --verbose |
47 | 52 | TOXCMD += -v |
53 | BENCHMARKCMD += --benchmark-verbose | |
48 | 54 | endif |
49 | 55 | |
50 | 56 | # Coverage |
51 | COVERAGE_ENV ?= py39 | |
57 | COVERAGE_ENV ?= py310 | |
52 | 58 | |
53 | 59 | # Data |
54 | 60 | ARTIFACTS := build |
63 | 69 | # The default target of this makefile is.... |
64 | 70 | all:: help |
65 | 71 | |
66 | help: | |
72 | help:: | |
67 | 73 | @echo "---- Makefile Targets ----" |
68 | @echo "make help - print this message" | |
69 | @echo "make test - run unit tests" | |
70 | @echo "make tox - run unit tests using tox" | |
71 | @echo "make tox multi=1 - run unit tests on multiple pythons using tox" | |
72 | @echo "make clean - remove cruft" | |
74 | @echo "make help - print this message" | |
75 | @echo "make test - run unit tests" | |
76 | @echo "make tox - run unit tests using tox" | |
77 | @echo "make tox multi=1 - run unit tests on multiple pythons using tox" | |
78 | @echo "make clean - remove cruft" | |
79 | @echo "make benchmark - run pytest benchmarking" | |
80 | @echo "make doc - generate documentation using sphinx" | |
73 | 81 | .PHONY: help |
74 | 82 | |
75 | test: | |
83 | test:: | |
76 | 84 | $(TESTCMD) $(flags) |
77 | 85 | .PHONY: test |
78 | 86 | |
79 | tox: | |
87 | tox:: | |
80 | 88 | $(TOXCMD) $(flags) |
81 | 89 | .PHONY: tox |
82 | 90 | |
83 | tags: | |
91 | benchmark:: | |
92 | $(BENCHMARKCMD) --benchmark-only --benchmark-histogram=./images/benchmark-$(DATEANDTIME) ./jsonpickle_benchmarks.py | |
93 | .PHONY: benchmark | |
94 | ||
95 | doc:: | |
96 | $(SPHINX) docs build/html | |
97 | ||
98 | tags:: | |
84 | 99 | $(FIND) $(PYTHON_DIRS) -name '*.py' -print0 | xargs -0 $(CTAGS) -f tags |
85 | 100 | |
86 | clean: | |
101 | clean:: | |
87 | 102 | $(FIND) $(PYTHON_DIRS) -name '*.py[cod]' -print0 | xargs -0 rm -f |
88 | 103 | $(FIND) $(PYTHON_DIRS) -name '__pycache__' -print0 | xargs -0 rm -fr |
89 | 104 | $(RM_R) $(ARTIFACTS) |
90 | 105 | .PHONY: clean |
91 | 106 | |
92 | 107 | format:: |
93 | $(BLACK) --skip-string-normalization --target-version py27 $(PYTHON_DIRS) | |
108 | $(BLACK) --skip-string-normalization --target-version py310 $(PYTHON_DIRS) | |
94 | 109 | .PHONY: format |
0 | 0 | Metadata-Version: 2.1 |
1 | 1 | Name: jsonpickle |
2 | Version: 2.0.0 | |
2 | Version: 3.0.0 | |
3 | 3 | Summary: Python library for serializing any arbitrary object graph into JSON |
4 | 4 | Home-page: https://github.com/jsonpickle/jsonpickle |
5 | 5 | Author: David Aguilar |
6 | 6 | Author-email: davvid@gmail.com |
7 | 7 | License: UNKNOWN |
8 | Description: .. image:: https://img.shields.io/pypi/v/jsonpickle.svg | |
9 | :target: `PyPI link`_ | |
10 | ||
11 | .. image:: https://img.shields.io/pypi/pyversions/jsonpickle.svg | |
12 | :target: `PyPI link`_ | |
13 | ||
14 | .. _PyPI link: https://pypi.org/project/jsonpickle | |
15 | ||
16 | .. image:: https://dev.azure.com/jaraco/jsonpickle/_apis/build/status/jaraco.jsonpickle?branchName=master | |
17 | :target: https://dev.azure.com/jaraco/jsonpickle/_build/latest?definitionId=1&branchName=master | |
18 | ||
19 | .. image:: https://readthedocs.org/projects/jsonpickle/badge/?version=latest | |
20 | :target: https://jsonpickle.readthedocs.io/en/latest/?badge=latest | |
21 | ||
22 | .. image:: https://travis-ci.org/jsonpickle/jsonpickle.svg?branch=master | |
23 | :target: https://travis-ci.org/jsonpickle/jsonpickle | |
24 | :alt: travis | |
25 | ||
26 | .. image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg | |
27 | :target: https://github.com/jsonpickle/jsonpickle/blob/master/COPYING | |
28 | :alt: BSD | |
29 | ||
30 | ||
31 | jsonpickle | |
32 | ========== | |
33 | jsonpickle is a library for the two-way conversion of complex Python objects | |
34 | and `JSON <http://json.org/>`_. jsonpickle builds upon the existing JSON | |
35 | encoders, such as simplejson, json, and demjson. | |
36 | ||
37 | For complete documentation, please visit the | |
38 | `jsonpickle documentation <http://jsonpickle.readthedocs.io/>`_. | |
39 | ||
40 | Bug reports and merge requests are encouraged at the | |
41 | `jsonpickle repository on github <https://github.com/jsonpickle/jsonpickle>`_. | |
42 | ||
43 | jsonpickle supports Python 2.7 and Python 3.4 or greater. | |
44 | ||
45 | **WARNING**: | |
46 | jsonpickle can execute arbitrary Python code. Do not load jsonpickles from untrusted / unauthenticated sources. | |
47 | ||
48 | Why jsonpickle? | |
49 | =============== | |
50 | Data serialized with python's pickle (or cPickle or dill) is not easily readable outside of python. Using the json format, jsonpickle allows simple data types to be stored in a human-readable format, and more complex data types such as numpy arrays and pandas dataframes, to be machine-readable on any platform that supports json. E.g., unlike pickled data, jsonpickled data stored in an Amazon S3 bucket is indexible by Amazon's Athena. | |
51 | ||
52 | Install | |
53 | ======= | |
54 | ||
55 | Install from pip for the latest stable release: | |
56 | ||
57 | :: | |
58 | ||
59 | pip install jsonpickle | |
60 | ||
61 | Install from github for the latest changes: | |
62 | ||
63 | :: | |
64 | ||
65 | pip install git+https://github.com/jsonpickle/jsonpickle.git | |
66 | ||
67 | If you have the files checked out for development: | |
68 | ||
69 | :: | |
70 | ||
71 | git clone https://github.com/jsonpickle/jsonpickle.git | |
72 | cd jsonpickle | |
73 | python setup.py develop | |
74 | ||
75 | ||
76 | Numpy Support | |
77 | ============= | |
78 | jsonpickle includes a built-in numpy extension. If would like to encode | |
79 | sklearn models, numpy arrays, and other numpy-based data then you must | |
80 | enable the numpy extension by registering its handlers:: | |
81 | ||
82 | >>> import jsonpickle.ext.numpy as jsonpickle_numpy | |
83 | >>> jsonpickle_numpy.register_handlers() | |
84 | ||
85 | Pandas Support | |
86 | ============== | |
87 | jsonpickle includes a built-in pandas extension. If would like to encode | |
88 | pandas DataFrame or Series objects then you must enable the pandas extension | |
89 | by registering its handlers:: | |
90 | ||
91 | >>> import jsonpickle.ext.pandas as jsonpickle_pandas | |
92 | >>> jsonpickle_pandas.register_handlers() | |
93 | ||
94 | jsonpickleJS | |
95 | ============ | |
96 | `jsonpickleJS <https://github.com/cuthbertLab/jsonpickleJS>`_ | |
97 | is a javascript implementation of jsonpickle by Michael Scott Cuthbert. | |
98 | jsonpickleJS can be extremely useful for projects that have parallel data | |
99 | structures between Python and Javascript. | |
100 | ||
101 | License | |
102 | ======= | |
103 | Licensed under the BSD License. See COPYING for details. | |
104 | See jsonpickleJS/LICENSE for details about the jsonpickleJS license. | |
105 | ||
106 | Development | |
107 | =========== | |
108 | ||
109 | Use `make` to run the unit tests:: | |
110 | ||
111 | make test | |
112 | ||
113 | `pytest` is used to run unit tests internally. | |
114 | ||
115 | A `tox` target is provided to run tests using tox. | |
116 | Setting ``multi=1`` tests using all installed and supported Python versions:: | |
117 | ||
118 | make tox | |
119 | make tox multi=1 | |
120 | ||
121 | `jsonpickle` itself has no dependencies beyond the Python stdlib. | |
122 | `tox` is required for testing when using the `tox` test runner only. | |
123 | ||
124 | The testing requirements are specified in `requirements-dev.txt`. | |
125 | It is recommended to create a virtualenv and run tests from within the | |
126 | virtualenv, or use a tool such as `vx <https://github.com/davvid/vx/>`_ | |
127 | to activate the virtualenv without polluting the shell environment:: | |
128 | ||
129 | python3 -mvenv env3x | |
130 | vx env3x pip install --requirement requirements-dev.txt | |
131 | vx env3x make test | |
132 | ||
133 | `jsonpickle` supports multiple Python versions, so using a combination of | |
134 | multiple virtualenvs and `tox` is useful in order to catch compatibility | |
135 | issues when developing. | |
136 | ||
137 | 8 | Keywords: json pickle,json,pickle,marshal,serialization,JavaScript Object Notation |
138 | 9 | Platform: POSIX |
139 | 10 | Platform: Windows |
141 | 12 | Classifier: Intended Audience :: Developers |
142 | 13 | Classifier: License :: OSI Approved :: BSD License |
143 | 14 | Classifier: Programming Language :: Python |
144 | Classifier: Programming Language :: Python :: 2 | |
145 | Classifier: Programming Language :: Python :: 2.7 | |
146 | 15 | Classifier: Programming Language :: Python :: 3 |
16 | Classifier: Programming Language :: Python :: 3.7 | |
17 | Classifier: Programming Language :: Python :: 3.8 | |
18 | Classifier: Programming Language :: Python :: 3.9 | |
19 | Classifier: Programming Language :: Python :: 3.10 | |
147 | 20 | Classifier: Programming Language :: JavaScript |
148 | 21 | Classifier: Operating System :: OS Independent |
149 | 22 | Classifier: Topic :: Software Development :: Libraries :: Python Modules |
150 | Requires-Python: >=2.7 | |
23 | Requires-Python: >=3.7 | |
151 | 24 | Provides-Extra: testing |
152 | 25 | Provides-Extra: testing.libs |
153 | 26 | Provides-Extra: docs |
27 | License-File: LICENSE | |
28 | ||
29 | .. image:: https://img.shields.io/pypi/v/jsonpickle.svg | |
30 | :target: `PyPI link`_ | |
31 | ||
32 | .. image:: https://img.shields.io/pypi/pyversions/jsonpickle.svg | |
33 | :target: `PyPI link`_ | |
34 | ||
35 | .. _PyPI link: https://pypi.org/project/jsonpickle | |
36 | ||
37 | .. image:: https://readthedocs.org/projects/jsonpickle/badge/?version=latest | |
38 | :target: https://jsonpickle.readthedocs.io/en/latest/?badge=latest | |
39 | ||
40 | .. image:: https://github.com/jsonpickle/jsonpickle/actions/workflows/test.yml/badge.svg | |
41 | :target: https://github.com/jsonpickle/jsonpickle/actions | |
42 | :alt: Github Actions | |
43 | ||
44 | .. image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg | |
45 | :target: https://github.com/jsonpickle/jsonpickle/blob/main/COPYING | |
46 | :alt: BSD | |
47 | ||
48 | ||
49 | jsonpickle | |
50 | ========== | |
51 | jsonpickle is a library for the two-way conversion of complex Python objects | |
52 | and `JSON <http://json.org/>`_. jsonpickle builds upon the existing JSON | |
53 | encoders, such as simplejson, json, and ujson. | |
54 | ||
55 | .. warning:: | |
56 | ||
57 | jsonpickle can execute arbitrary Python code. | |
58 | ||
59 | Please see the Security section for more details. | |
60 | ||
61 | ||
62 | For complete documentation, please visit the | |
63 | `jsonpickle documentation <http://jsonpickle.readthedocs.io/>`_. | |
64 | ||
65 | Bug reports and merge requests are encouraged at the | |
66 | `jsonpickle repository on github <https://github.com/jsonpickle/jsonpickle>`_. | |
67 | ||
68 | jsonpickle officially supports CPython 2.7 and CPython 3.6 or greater. Version support below CPython 3.7 will be dropped upon release of jsonpickle 3.0. | |
69 | ||
70 | Why jsonpickle? | |
71 | =============== | |
72 | Data serialized with python's pickle (or cPickle or dill) is not easily readable outside of python. Using the json format, jsonpickle allows simple data types to be stored in a human-readable format, and more complex data types such as numpy arrays and pandas dataframes, to be machine-readable on any platform that supports json. E.g., unlike pickled data, jsonpickled data stored in an Amazon S3 bucket is indexible by Amazon's Athena. | |
73 | ||
74 | Security | |
75 | ======== | |
76 | ||
77 | jsonpickle should be treated the same as the | |
78 | `Python stdlib pickle module <https://docs.python.org/3/library/pickle.html>`_ | |
79 | from a security perspective. | |
80 | ||
81 | .. warning:: | |
82 | ||
83 | The jsonpickle module **is not secure**. Only unpickle data you trust. | |
84 | ||
85 | It is possible to construct malicious pickle data which will **execute | |
86 | arbitrary code during unpickling**. Never unpickle data that could have come | |
87 | from an untrusted source, or that could have been tampered with. | |
88 | ||
89 | Consider signing data with an HMAC if you need to ensure that it has not | |
90 | been tampered with. | |
91 | ||
92 | Safer deserialization approaches, such as reading JSON directly, | |
93 | may be more appropriate if you are processing untrusted data. | |
94 | ||
95 | ||
96 | Install | |
97 | ======= | |
98 | ||
99 | Install from pip for the latest stable release: | |
100 | ||
101 | :: | |
102 | ||
103 | pip install jsonpickle | |
104 | ||
105 | Install from github for the latest changes: | |
106 | ||
107 | :: | |
108 | ||
109 | pip install git+https://github.com/jsonpickle/jsonpickle.git | |
110 | ||
111 | If you have the files checked out for development: | |
112 | ||
113 | :: | |
114 | ||
115 | git clone https://github.com/jsonpickle/jsonpickle.git | |
116 | cd jsonpickle | |
117 | python setup.py develop | |
118 | ||
119 | ||
120 | Numpy Support | |
121 | ============= | |
122 | jsonpickle includes a built-in numpy extension. If would like to encode | |
123 | sklearn models, numpy arrays, and other numpy-based data then you must | |
124 | enable the numpy extension by registering its handlers:: | |
125 | ||
126 | >>> import jsonpickle.ext.numpy as jsonpickle_numpy | |
127 | >>> jsonpickle_numpy.register_handlers() | |
128 | ||
129 | Pandas Support | |
130 | ============== | |
131 | jsonpickle includes a built-in pandas extension. If would like to encode | |
132 | pandas DataFrame or Series objects then you must enable the pandas extension | |
133 | by registering its handlers:: | |
134 | ||
135 | >>> import jsonpickle.ext.pandas as jsonpickle_pandas | |
136 | >>> jsonpickle_pandas.register_handlers() | |
137 | ||
138 | jsonpickleJS | |
139 | ============ | |
140 | `jsonpickleJS <https://github.com/cuthbertLab/jsonpickleJS>`_ | |
141 | is a javascript implementation of jsonpickle by Michael Scott Cuthbert. | |
142 | jsonpickleJS can be extremely useful for projects that have parallel data | |
143 | structures between Python and Javascript. | |
144 | ||
145 | License | |
146 | ======= | |
147 | Licensed under the BSD License. See COPYING for details. | |
148 | See jsonpickleJS/LICENSE for details about the jsonpickleJS license. | |
149 | ||
150 | Development | |
151 | =========== | |
152 | ||
153 | Use `make` to run the unit tests:: | |
154 | ||
155 | make test | |
156 | ||
157 | `pytest` is used to run unit tests internally. | |
158 | ||
159 | A `tox` target is provided to run tests using tox. | |
160 | Setting ``multi=1`` tests using all installed and supported Python versions:: | |
161 | ||
162 | make tox | |
163 | make tox multi=1 | |
164 | ||
165 | `jsonpickle` itself has no dependencies beyond the Python stdlib. | |
166 | `tox` is required for testing when using the `tox` test runner only. | |
167 | ||
168 | The testing requirements are specified in `requirements-dev.txt`. | |
169 | It is recommended to create a virtualenv and run tests from within the | |
170 | virtualenv, or use a tool such as `vx <https://github.com/davvid/vx/>`_ | |
171 | to activate the virtualenv without polluting the shell environment:: | |
172 | ||
173 | python3 -mvenv env3x | |
174 | vx env3x pip install --requirement requirements-dev.txt | |
175 | vx env3x make test | |
176 | ||
177 | `jsonpickle` supports multiple Python versions, so using a combination of | |
178 | multiple virtualenvs and `tox` is useful in order to catch compatibility | |
179 | issues when developing. | |
180 | ||
181 |
5 | 5 | |
6 | 6 | .. _PyPI link: https://pypi.org/project/jsonpickle |
7 | 7 | |
8 | .. image:: https://dev.azure.com/jaraco/jsonpickle/_apis/build/status/jaraco.jsonpickle?branchName=master | |
9 | :target: https://dev.azure.com/jaraco/jsonpickle/_build/latest?definitionId=1&branchName=master | |
10 | ||
11 | 8 | .. image:: https://readthedocs.org/projects/jsonpickle/badge/?version=latest |
12 | 9 | :target: https://jsonpickle.readthedocs.io/en/latest/?badge=latest |
13 | 10 | |
14 | .. image:: https://travis-ci.org/jsonpickle/jsonpickle.svg?branch=master | |
15 | :target: https://travis-ci.org/jsonpickle/jsonpickle | |
16 | :alt: travis | |
11 | .. image:: https://github.com/jsonpickle/jsonpickle/actions/workflows/test.yml/badge.svg | |
12 | :target: https://github.com/jsonpickle/jsonpickle/actions | |
13 | :alt: Github Actions | |
17 | 14 | |
18 | 15 | .. image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg |
19 | :target: https://github.com/jsonpickle/jsonpickle/blob/master/COPYING | |
16 | :target: https://github.com/jsonpickle/jsonpickle/blob/main/COPYING | |
20 | 17 | :alt: BSD |
21 | 18 | |
22 | 19 | |
24 | 21 | ========== |
25 | 22 | jsonpickle is a library for the two-way conversion of complex Python objects |
26 | 23 | and `JSON <http://json.org/>`_. jsonpickle builds upon the existing JSON |
27 | encoders, such as simplejson, json, and demjson. | |
24 | encoders, such as simplejson, json, and ujson. | |
25 | ||
26 | .. warning:: | |
27 | ||
28 | jsonpickle can execute arbitrary Python code. | |
29 | ||
30 | Please see the Security section for more details. | |
31 | ||
28 | 32 | |
29 | 33 | For complete documentation, please visit the |
30 | 34 | `jsonpickle documentation <http://jsonpickle.readthedocs.io/>`_. |
32 | 36 | Bug reports and merge requests are encouraged at the |
33 | 37 | `jsonpickle repository on github <https://github.com/jsonpickle/jsonpickle>`_. |
34 | 38 | |
35 | jsonpickle supports Python 2.7 and Python 3.4 or greater. | |
36 | ||
37 | **WARNING**: | |
38 | jsonpickle can execute arbitrary Python code. Do not load jsonpickles from untrusted / unauthenticated sources. | |
39 | jsonpickle officially supports CPython 2.7 and CPython 3.6 or greater. Version support below CPython 3.7 will be dropped upon release of jsonpickle 3.0. | |
39 | 40 | |
40 | 41 | Why jsonpickle? |
41 | 42 | =============== |
42 | 43 | Data serialized with python's pickle (or cPickle or dill) is not easily readable outside of python. Using the json format, jsonpickle allows simple data types to be stored in a human-readable format, and more complex data types such as numpy arrays and pandas dataframes, to be machine-readable on any platform that supports json. E.g., unlike pickled data, jsonpickled data stored in an Amazon S3 bucket is indexible by Amazon's Athena. |
44 | ||
45 | Security | |
46 | ======== | |
47 | ||
48 | jsonpickle should be treated the same as the | |
49 | `Python stdlib pickle module <https://docs.python.org/3/library/pickle.html>`_ | |
50 | from a security perspective. | |
51 | ||
52 | .. warning:: | |
53 | ||
54 | The jsonpickle module **is not secure**. Only unpickle data you trust. | |
55 | ||
56 | It is possible to construct malicious pickle data which will **execute | |
57 | arbitrary code during unpickling**. Never unpickle data that could have come | |
58 | from an untrusted source, or that could have been tampered with. | |
59 | ||
60 | Consider signing data with an HMAC if you need to ensure that it has not | |
61 | been tampered with. | |
62 | ||
63 | Safer deserialization approaches, such as reading JSON directly, | |
64 | may be more appropriate if you are processing untrusted data. | |
65 | ||
43 | 66 | |
44 | 67 | Install |
45 | 68 | ======= |
49 | 49 | - script: | |
50 | 50 | tox -- --junit-xml=test-results.xml |
51 | 51 | env: |
52 | TOXENV: {libs,sa10,sa11,sa12,sa13} | |
52 | TOXENV: {libs,sa12,sa13} | |
53 | 53 | displayName: 'run tests' |
54 | 54 | |
55 | 55 | - task: PublishTestResults@2 |
0 | 0 | collect_ignore = ['contrib'] |
1 | ||
2 | ||
3 | def pytest_addoption(parser): | |
4 | parser.addoption( | |
5 | '--repeat', action='store', help='Number of times to repeat each test' | |
6 | ) | |
7 | ||
8 | ||
9 | def pytest_generate_tests(metafunc): | |
10 | if metafunc.config.option.repeat is not None: | |
11 | count = int(metafunc.config.option.repeat) | |
12 | ||
13 | # We're going to duplicate these tests by parametrizing them, | |
14 | # which requires that each test has a fixture to accept the parameter. | |
15 | # We can add a new fixture like so: | |
16 | metafunc.fixturenames.append('tmp_ct') | |
17 | ||
18 | # Now we parametrize. This is what happens when we do e.g., | |
19 | # @pytest.mark.parametrize('tmp_ct', range(count)) | |
20 | # def test_foo(): pass | |
21 | metafunc.parametrize('tmp_ct', range(count)) |
36 | 36 | |
37 | 37 | jsonpickle allows the user to specify what JSON backend to use |
38 | 38 | when encoding and decoding. By default, jsonpickle will try to use, in |
39 | the following order: :mod:`simplejson`, :mod:`json`, and :mod:`demjson`. | |
40 | The prefered backend can be set via :func:`jsonpickle.set_preferred_backend`. | |
39 | the following order: :mod:`simplejson` and :mod:`json`. | |
40 | The preferred backend can be set via :func:`jsonpickle.set_preferred_backend`. | |
41 | 41 | Additional JSON backends can be used via :func:`jsonpickle.load_backend`. |
42 | 42 | |
43 | 43 | For example, users of `Django <http://www.djangoproject.com/>`_ can use the |
50 | 50 | |
51 | 51 | * :mod:`json` |
52 | 52 | * `simplejson <http://undefined.org/python/#simplejson>`_ |
53 | * `demjson <https://deron.meranda.us/python/demjson/>`_ | |
54 | 53 | |
55 | 54 | Experimental backends: |
56 | 55 | |
72 | 71 | ----------------------- |
73 | 72 | |
74 | 73 | jsonpickle supports the standard :mod:`pickle` `__getstate__` and `__setstate__` |
75 | protocol for representating object instances. | |
74 | protocol for representing object instances. | |
76 | 75 | |
77 | 76 | .. method:: object.__getstate__() |
78 | 77 |
11 | 11 | |
12 | 12 | :: |
13 | 13 | |
14 | git clone git://github.com/jsonpickle/jsonpickle.git | |
14 | git clone https://github.com/jsonpickle/jsonpickle.git | |
15 | 15 | |
16 | 16 | Run the Test Suite |
17 | 17 | ================== |
18 | 18 | |
19 | Before code is pulled into the master jsonpickle branch, all tests should pass. | |
19 | All tests should pass before before code is merged into the main repository. | |
20 | 20 | If you are contributing an addition or a change in behavior, we ask that you |
21 | 21 | document the change in the form of test cases. |
22 | 22 | |
42 | 42 | |
43 | 43 | tox -e py37-libs |
44 | 44 | |
45 | To create the enivornment without running tests:: | |
45 | To create the environment without running tests:: | |
46 | 46 | |
47 | 47 | tox -e libs --notest |
48 | 48 |
9 | 9 | |
10 | 10 | >>> import jsonpickle.ext.numpy as jsonpickle_numpy |
11 | 11 | >>> jsonpickle_numpy.register_handlers() |
12 | ||
13 | Ecdsa | |
14 | ----- | |
15 | For the ecdsa module's keys, when trying to serialize them with | |
16 | ``gmpy2`` installed, jsonpickle will error unless the ``gmpy`` | |
17 | handlers are registered: | |
18 | ||
19 | >>> import jsonpickle.ext.gmpy as jsonpickle_gmpy | |
20 | >>> jsonpickle_gmpy.register_handlers() |
4 | 4 | ``jsonpickle`` is a Python library for |
5 | 5 | serialization and deserialization of complex Python objects to and from |
6 | 6 | JSON. The standard Python libraries for encoding Python into JSON, such as |
7 | the stdlib's json, simplejson, and demjson, can only handle Python | |
7 | the stdlib's json and simplejson can only handle Python | |
8 | 8 | primitives that have a direct JSON equivalent (e.g. dicts, lists, strings, |
9 | 9 | ints, etc.). jsonpickle builds on top of these libraries and allows more |
10 | 10 | complex data structures to be serialized to JSON. jsonpickle is highly |
15 | 15 | |
16 | 16 | jsonpickle Usage |
17 | 17 | ================ |
18 | ||
19 | .. note:: | |
20 | ||
21 | Please see the note in the :ref:`api-docs` when serializing dictionaries | |
22 | that contain non-string dictionary keys. | |
23 | 18 | |
24 | 19 | .. automodule:: jsonpickle |
25 | 20 | |
78 | 73 | |
79 | 74 | * John Paulett - john -at- paulett.org - https://github.com/johnpaulett |
80 | 75 | * David Aguilar - davvid -at- gmail.com - https://github.com/davvid |
76 | * Theelx - https://github.com/Theelx | |
81 | 77 | * Dan Buch - https://github.com/meatballhat |
82 | 78 | * Ian Schenck - https://github.com/ianschenck |
83 | 79 | * David K. Hess - https://github.com/davidkhess |
98 | 94 | ======= |
99 | 95 | |
100 | 96 | jsonpickle is provided under a |
101 | `New BSD license <https://github.com/jsonpickle/jsonpickle/raw/master/COPYING>`_, | |
97 | `New BSD license <https://github.com/jsonpickle/jsonpickle/raw/main/COPYING>`_, | |
102 | 98 | |
103 | 99 | Copyright (C) 2008-2011 John Paulett (john -at- paulett.org) |
104 | Copyright (C) 2009-2016 David Aguilar (davvid -at- gmail.com) | |
100 | Copyright (C) 2009-2021 David Aguilar (davvid -at- gmail.com) |
0 | <?xml version='1.0' encoding='utf-8'?> | |
1 | <svg xmlns="http://www.w3.org/2000/svg" id="chart-83417b21-d81c-43db-a314-e3e737f00e1e" class="pygal-chart" viewBox="0 0 800 600"><!--Generated with pygal 3.0.0 (etree) ©Kozea 2012-2016 on 2022-06-20--><!--http://pygal.org--><!--http://github.com/Kozea/pygal--><defs><style type="text/css">#chart-83417b21-d81c-43db-a314-e3e737f00e1e{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .title{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .legends .legend text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis text.major{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay text.value{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay text.label{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-83417b21-d81c-43db-a314-e3e737f00e1e text.no_data{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:64px} | |
2 | #chart-83417b21-d81c-43db-a314-e3e737f00e1e{background-color:rgba(249,249,249,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e path,#chart-83417b21-d81c-43db-a314-e3e737f00e1e line,#chart-83417b21-d81c-43db-a314-e3e737f00e1e rect,#chart-83417b21-d81c-43db-a314-e3e737f00e1e circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .graph > .background{fill:rgba(249,249,249,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .plot > .background{fill:rgba(255,255,255,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .graph{fill:rgba(0,0,0,.87)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e text.no_data{fill:rgba(0,0,0,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .title{fill:rgba(0,0,0,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .legends .legend text{fill:rgba(0,0,0,.87)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis .line{stroke:rgba(0,0,0,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis text.major{fill:rgba(0,0,0,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.y .guides:hover .guide.line,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .line-graph .axis.x .guides:hover .guide.line,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .stackedline-graph .axis.x .guides:hover .guide.line,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .reactive{fill-opacity:.7;stroke-opacity:.8;stroke-width:1}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .ci{stroke:rgba(0,0,0,.87)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .reactive.active,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .ci .reactive.active{stroke-width:1.5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .series text{fill:rgba(0,0,0,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip .label{fill:rgba(0,0,0,.87)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip .label{fill:rgba(0,0,0,.87)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip .value{font-size:1.5em}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .bound{font-size:.5em}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-0,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-0 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-1,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-1 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-2,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-2 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-3,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-3 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-4,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-4 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-5,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-5 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-6,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-6 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-7,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-7 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-8,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-8 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-9,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-9 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-10,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-10 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-11,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-11 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-12,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-12 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-13,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-13 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-14,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-14 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-15,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-15 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-16,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-16 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-17,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-17 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-18,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-18 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-19,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-19 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-20,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-20 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-21,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-21 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-22,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-22 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-23,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-23 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-24,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-24 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-25,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-25 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-26,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-26 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-27,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-27 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-28,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-28 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-29,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .color-29 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-0 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-1 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-2 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-3 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-4 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-5 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-6 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-7 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-8 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-9 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-10 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-11 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-12 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-13 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-14 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-15 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-16 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-17 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-18 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-19 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-20 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-21 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-22 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-23 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-24 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-25 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-26 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-27 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-28 text{fill:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .text-overlay .color-29 text{fill:black} | |
3 | #chart-83417b21-d81c-43db-a314-e3e737f00e1e text.no_data{text-anchor:middle}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .guide.line{fill:none}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .centered{text-anchor:middle}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .title{text-anchor:middle}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .legends .legend text{fill-opacity:1}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.x text{text-anchor:middle}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.x:not(.web) text[transform]{text-anchor:start}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.y text{text-anchor:end}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.y text[transform].backwards{text-anchor:start}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.y2 text{text-anchor:start}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.y2 text[transform].backwards{text-anchor:end}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis .guide.line{stroke-dasharray:4,4;stroke:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis .major.guide.line{stroke-dasharray:6,6;stroke:black}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .horizontal .axis.y .guide.line,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .horizontal .axis.y2 .guide.line,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .vertical .axis.x .guide.line{opacity:0}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .horizontal .axis.always_show .guide.line,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.y .guides:hover .guide.line,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.y2 .guides:hover .guide.line,#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis.x .guides:hover .guide.line{opacity:1}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .axis .guides:hover text{opacity:1}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .nofill{fill:none}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .subtle-fill{fill-opacity:.2}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .dot{stroke-width:1px;fill-opacity:1;stroke-opacity:1}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .dot.active{stroke-width:5px}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .dot.negative{fill:transparent}#chart-83417b21-d81c-43db-a314-e3e737f00e1e text,#chart-83417b21-d81c-43db-a314-e3e737f00e1e tspan{stroke:none !important}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .series text.active{opacity:1}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .tooltip text{fill-opacity:1}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .showable{visibility:hidden}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .showable.shown{visibility:visible}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-83417b21-d81c-43db-a314-e3e737f00e1e .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px} | |
4 | .tooltip .value{font-size:1em !important}.axis text{font-size:9px !important}</style><script type="text/javascript">window.pygal = window.pygal || {};window.pygal.config = window.pygal.config || {};window.pygal.config['83417b21-d81c-43db-a314-e3e737f00e1e'] = {"allow_interruptions": false, "box_mode": "tukey", "classes": ["pygal-chart"], "css": ["file://style.css", "file://graph.css", "inline:\n .tooltip .value {\n font-size: 1em !important;\n }\n .axis text {\n font-size: 9px !important;\n }\n "], "defs": [], "disable_xml_declaration": false, "dots_size": 2.5, "dynamic_print_values": false, "explicit_size": false, "fill": false, "force_uri_protocol": "https", "formatter": null, "half_pie": false, "height": 600, "include_x_axis": false, "inner_radius": 0, "interpolate": null, "interpolation_parameters": {}, "interpolation_precision": 250, "inverse_y_axis": false, "js": ["file:///home/theel/.pyenv/versions/3.9.13/lib/python3.9/site-packages/pygaljs/static/2.0.x/pygal-tooltips.js"], "legend_at_bottom": false, "legend_at_bottom_columns": null, "legend_box_size": 12, "logarithmic": false, "margin": 20, "margin_bottom": null, "margin_left": null, "margin_right": null, "margin_top": null, "max_scale": 20, "min_scale": 20, "missing_value_fill_truncation": "x", "no_data_text": "No data", "no_prefix": false, "order_min": null, "pretty_print": false, "print_labels": false, "print_values": false, "print_values_position": "center", "print_zeroes": true, "range": [15, 344], "rounded_bars": null, "secondary_range": null, "show_dots": true, "show_legend": false, "show_minor_x_labels": true, "show_minor_y_labels": true, "show_only_major_dots": false, "show_x_guides": false, "show_x_labels": true, "show_y_guides": true, "show_y_labels": true, "spacing": 10, "stack_from_top": false, "strict": false, "stroke": true, "stroke_style": null, "style": {"background": "rgba(249, 249, 249, 1)", "ci_colors": [], "colors": ["#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5"], "dot_opacity": "1", "font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "foreground": "rgba(0, 0, 0, .87)", "foreground_strong": "rgba(0, 0, 0, 1)", "foreground_subtle": "rgba(0, 0, 0, .54)", "guide_stroke_color": "black", "guide_stroke_dasharray": "4,4", "label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "label_font_size": 10, "legend_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "legend_font_size": 14, "major_guide_stroke_color": "black", "major_guide_stroke_dasharray": "6,6", "major_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "major_label_font_size": 10, "no_data_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "no_data_font_size": 64, "opacity": ".7", "opacity_hover": ".8", "plot_background": "rgba(255, 255, 255, 1)", "stroke_opacity": ".8", "stroke_opacity_hover": ".9", "stroke_width": "1", "stroke_width_hover": "4", "title_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "title_font_size": 16, "tooltip_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "tooltip_font_size": 14, "transition": "150ms", "value_background": "rgba(229, 229, 229, 1)", "value_colors": [], "value_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_font_size": 16, "value_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_label_font_size": 10}, "title": "Speed in Microseconds (us)", "tooltip_border_radius": 0, "tooltip_fancy_mode": true, "truncate_label": 50, "truncate_legend": null, "width": 800, "x_label_rotation": 270, "x_labels": ["simple_list_e", "simple_tuple_e", "simple_set_e", "simple_dict_e", "simple_dict_d", "simple_tuple_d", "simple_set_d", "simple_list_d", "complex_homog_list_e", "complex_homog_dict_d", "complex_homog_set_e", "complex_homog_tuple_e", "complex_heterog_set_e", "complex_heterog_dict_d", "complex_homog_tuple_d", "complex_homog_set_d", "complex_heterog_set_d", "simple_cls_d", "complex_heterog_list_e", "complex_heterog_tuple_e", "complex_heterog_tuple_d", "complex_heterog_list_d", "complex_homog_list_d", "complex_homog_dict_e", "complex_heterog_dict_e", "simple_cls_e", "complex_cls_d", "state_cls_d", "complex_cls_e", "state_cls_e"], "x_labels_major": null, "x_labels_major_count": null, "x_labels_major_every": null, "x_title": "Trial", "xrange": null, "y_label_rotation": 0, "y_labels": null, "y_labels_major": null, "y_labels_major_count": null, "y_labels_major_every": null, "y_title": "Duration", "zero": 15, "legends": ["jsonpickle_benchmarks.py::simple_list_e - 15376 rounds", "jsonpickle_benchmarks.py::simple_tuple_e - 15926 rounds", "jsonpickle_benchmarks.py::simple_set_e - 13633 rounds", "jsonpickle_benchmarks.py::simple_dict_e - 6871 rounds", "jsonpickle_benchmarks.py::simple_dict_d - 9429 rounds", "jsonpickle_benchmarks.py::simple_tuple_d - 16865 rounds", "jsonpickle_benchmarks.py::simple_set_d - 12822 rounds", "jsonpickle_benchmarks.py::simple_list_d - 12937 rounds", "jsonpickle_benchmarks.py::complex_homog_list_e - 10564 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_d - 8157 rounds", "jsonpickle_benchmarks.py::complex_homog_set_e - 9634 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_e - 657 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_e - 8602 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_d - 8509 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_d - 9192 rounds", "jsonpickle_benchmarks.py::complex_homog_set_d - 9693 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_d - 9429 rounds", "jsonpickle_benchmarks.py::simple_cls_d - 6749 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_e - 8148 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_e - 8061 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_d - 7751 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_d - 8824 rounds", "jsonpickle_benchmarks.py::complex_homog_list_d - 8567 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_e - 6835 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_e - 6758 rounds", "jsonpickle_benchmarks.py::simple_cls_e - 5437 rounds", "jsonpickle_benchmarks.py::complex_cls_d - 2588 rounds", "jsonpickle_benchmarks.py::state_cls_d - 2439 rounds", "jsonpickle_benchmarks.py::complex_cls_e - 2161 rounds", "jsonpickle_benchmarks.py::state_cls_e - 2262 rounds"]}</script><script type="text/javascript">(function() { | |
5 | var $, get_translation, init, init_svg, matches, padding, r_translation, sibl, svg_ns, tooltip_timeout, xlink_ns; | |
6 | ||
7 | svg_ns = 'http://www.w3.org/2000/svg'; | |
8 | ||
9 | xlink_ns = 'http://www.w3.org/1999/xlink'; | |
10 | ||
11 | $ = function(sel, ctx) { | |
12 | if (ctx == null) { | |
13 | ctx = null; | |
14 | } | |
15 | ctx = ctx || document; | |
16 | return Array.prototype.slice.call(ctx.querySelectorAll(sel), 0).filter(function(e) { | |
17 | return e !== ctx; | |
18 | }); | |
19 | }; | |
20 | ||
21 | matches = function(el, selector) { | |
22 | return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector); | |
23 | }; | |
24 | ||
25 | sibl = function(el, match) { | |
26 | if (match == null) { | |
27 | match = null; | |
28 | } | |
29 | return Array.prototype.filter.call(el.parentElement.children, function(child) { | |
30 | return child !== el && (!match || matches(child, match)); | |
31 | }); | |
32 | }; | |
33 | ||
34 | Array.prototype.one = function() { | |
35 | return this.length > 0 && this[0] || {}; | |
36 | }; | |
37 | ||
38 | padding = 5; | |
39 | ||
40 | tooltip_timeout = null; | |
41 | ||
42 | r_translation = /translate\((\d+)[ ,]+(\d+)\)/; | |
43 | ||
44 | get_translation = function(el) { | |
45 | return (r_translation.exec(el.getAttribute('transform')) || []).slice(1).map(function(x) { | |
46 | return +x; | |
47 | }); | |
48 | }; | |
49 | ||
50 | init = function(ctx) { | |
51 | var bbox, box, config, el, graph, inner_svg, num, parent, tooltip, tooltip_el, tt, uid, untooltip, xconvert, yconvert, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; | |
52 | if ($('svg', ctx).length) { | |
53 | inner_svg = $('svg', ctx).one(); | |
54 | parent = inner_svg.parentElement; | |
55 | box = inner_svg.viewBox.baseVal; | |
56 | bbox = parent.getBBox(); | |
57 | xconvert = function(x) { | |
58 | return ((x - box.x) / box.width) * bbox.width; | |
59 | }; | |
60 | yconvert = function(y) { | |
61 | return ((y - box.y) / box.height) * bbox.height; | |
62 | }; | |
63 | } else { | |
64 | xconvert = yconvert = function(x) { | |
65 | return x; | |
66 | }; | |
67 | } | |
68 | if (((_ref = window.pygal) != null ? _ref.config : void 0) != null) { | |
69 | if (window.pygal.config.no_prefix != null) { | |
70 | config = window.pygal.config; | |
71 | } else { | |
72 | uid = ctx.id.replace('chart-', ''); | |
73 | config = window.pygal.config[uid]; | |
74 | } | |
75 | } else { | |
76 | config = window.config; | |
77 | } | |
78 | tooltip_el = null; | |
79 | graph = $('.graph').one(); | |
80 | tt = $('.tooltip', ctx).one(); | |
81 | _ref1 = $('.reactive', ctx); | |
82 | for (_i = 0, _len = _ref1.length; _i < _len; _i++) { | |
83 | el = _ref1[_i]; | |
84 | el.addEventListener('mouseenter', (function(el) { | |
85 | return function() { | |
86 | return el.classList.add('active'); | |
87 | }; | |
88 | })(el)); | |
89 | el.addEventListener('mouseleave', (function(el) { | |
90 | return function() { | |
91 | return el.classList.remove('active'); | |
92 | }; | |
93 | })(el)); | |
94 | } | |
95 | _ref2 = $('.activate-serie', ctx); | |
96 | for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { | |
97 | el = _ref2[_j]; | |
98 | num = el.id.replace('activate-serie-', ''); | |
99 | el.addEventListener('mouseenter', (function(num) { | |
100 | return function() { | |
101 | var re, _k, _len2, _ref3, _results; | |
102 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
103 | _results = []; | |
104 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
105 | re = _ref3[_k]; | |
106 | _results.push(re.classList.add('active')); | |
107 | } | |
108 | return _results; | |
109 | }; | |
110 | })(num)); | |
111 | el.addEventListener('mouseleave', (function(num) { | |
112 | return function() { | |
113 | var re, _k, _len2, _ref3, _results; | |
114 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
115 | _results = []; | |
116 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
117 | re = _ref3[_k]; | |
118 | _results.push(re.classList.remove('active')); | |
119 | } | |
120 | return _results; | |
121 | }; | |
122 | })(num)); | |
123 | el.addEventListener('click', (function(el, num) { | |
124 | return function() { | |
125 | var ov, re, rect, show, _k, _l, _len2, _len3, _ref3, _ref4, _results; | |
126 | rect = $('rect', el).one(); | |
127 | show = rect.style.fill !== ''; | |
128 | rect.style.fill = show ? '' : 'transparent'; | |
129 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
130 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
131 | re = _ref3[_k]; | |
132 | re.style.display = show ? '' : 'none'; | |
133 | } | |
134 | _ref4 = $('.text-overlay .serie-' + num, ctx); | |
135 | _results = []; | |
136 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
137 | ov = _ref4[_l]; | |
138 | _results.push(ov.style.display = show ? '' : 'none'); | |
139 | } | |
140 | return _results; | |
141 | }; | |
142 | })(el, num)); | |
143 | } | |
144 | _ref3 = $('.tooltip-trigger', ctx); | |
145 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
146 | el = _ref3[_k]; | |
147 | el.addEventListener('mouseenter', (function(el) { | |
148 | return function() { | |
149 | return tooltip_el = tooltip(el); | |
150 | }; | |
151 | })(el)); | |
152 | } | |
153 | tt.addEventListener('mouseenter', function() { | |
154 | return tooltip_el != null ? tooltip_el.classList.add('active') : void 0; | |
155 | }); | |
156 | tt.addEventListener('mouseleave', function() { | |
157 | return tooltip_el != null ? tooltip_el.classList.remove('active') : void 0; | |
158 | }); | |
159 | ctx.addEventListener('mouseleave', function() { | |
160 | if (tooltip_timeout) { | |
161 | clearTimeout(tooltip_timeout); | |
162 | } | |
163 | return untooltip(0); | |
164 | }); | |
165 | graph.addEventListener('mousemove', function(el) { | |
166 | if (tooltip_timeout) { | |
167 | return; | |
168 | } | |
169 | if (!matches(el.target, '.background')) { | |
170 | return; | |
171 | } | |
172 | return untooltip(1000); | |
173 | }); | |
174 | tooltip = function(el) { | |
175 | var a, baseline, cls, current_x, current_y, dy, h, i, key, keys, label, legend, name, plot_x, plot_y, rect, serie_index, subval, text, text_group, texts, traversal, value, w, x, x_elt, x_label, xlink, y, y_elt, _l, _len3, _len4, _len5, _m, _n, _ref4, _ref5, _ref6, _ref7, _ref8; | |
176 | clearTimeout(tooltip_timeout); | |
177 | tooltip_timeout = null; | |
178 | tt.style.opacity = 1; | |
179 | tt.style.display = ''; | |
180 | text_group = $('g.text', tt).one(); | |
181 | rect = $('rect', tt).one(); | |
182 | text_group.innerHTML = ''; | |
183 | label = sibl(el, '.label').one().textContent; | |
184 | x_label = sibl(el, '.x_label').one().textContent; | |
185 | value = sibl(el, '.value').one().textContent; | |
186 | xlink = sibl(el, '.xlink').one().textContent; | |
187 | serie_index = null; | |
188 | parent = el; | |
189 | traversal = []; | |
190 | while (parent) { | |
191 | traversal.push(parent); | |
192 | if (parent.classList.contains('series')) { | |
193 | break; | |
194 | } | |
195 | parent = parent.parentElement; | |
196 | } | |
197 | if (parent) { | |
198 | _ref4 = parent.classList; | |
199 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
200 | cls = _ref4[_l]; | |
201 | if (cls.indexOf('serie-') === 0) { | |
202 | serie_index = +cls.replace('serie-', ''); | |
203 | break; | |
204 | } | |
205 | } | |
206 | } | |
207 | legend = null; | |
208 | if (serie_index !== null) { | |
209 | legend = config.legends[serie_index]; | |
210 | } | |
211 | dy = 0; | |
212 | keys = [[label, 'label']]; | |
213 | _ref5 = value.split('\n'); | |
214 | for (i = _m = 0, _len4 = _ref5.length; _m < _len4; i = ++_m) { | |
215 | subval = _ref5[i]; | |
216 | keys.push([subval, 'value-' + i]); | |
217 | } | |
218 | if (config.tooltip_fancy_mode) { | |
219 | keys.push([xlink, 'xlink']); | |
220 | keys.unshift([x_label, 'x_label']); | |
221 | keys.unshift([legend, 'legend']); | |
222 | } | |
223 | texts = {}; | |
224 | for (_n = 0, _len5 = keys.length; _n < _len5; _n++) { | |
225 | _ref6 = keys[_n], key = _ref6[0], name = _ref6[1]; | |
226 | if (key) { | |
227 | text = document.createElementNS(svg_ns, 'text'); | |
228 | text.textContent = key; | |
229 | text.setAttribute('x', padding); | |
230 | text.setAttribute('dy', dy); | |
231 | text.classList.add(name.indexOf('value') === 0 ? 'value' : name); | |
232 | if (name.indexOf('value') === 0 && config.tooltip_fancy_mode) { | |
233 | text.classList.add('color-' + serie_index); | |
234 | } | |
235 | if (name === 'xlink') { | |
236 | a = document.createElementNS(svg_ns, 'a'); | |
237 | a.setAttributeNS(xlink_ns, 'href', key); | |
238 | a.textContent = void 0; | |
239 | a.appendChild(text); | |
240 | text.textContent = 'Link >'; | |
241 | text_group.appendChild(a); | |
242 | } else { | |
243 | text_group.appendChild(text); | |
244 | } | |
245 | dy += text.getBBox().height + padding / 2; | |
246 | baseline = padding; | |
247 | if (text.style.dominantBaseline !== void 0) { | |
248 | text.style.dominantBaseline = 'text-before-edge'; | |
249 | } else { | |
250 | baseline += text.getBBox().height * .8; | |
251 | } | |
252 | text.setAttribute('y', baseline); | |
253 | texts[name] = text; | |
254 | } | |
255 | } | |
256 | w = text_group.getBBox().width + 2 * padding; | |
257 | h = text_group.getBBox().height + 2 * padding; | |
258 | rect.setAttribute('width', w); | |
259 | rect.setAttribute('height', h); | |
260 | if (texts.value) { | |
261 | texts.value.setAttribute('dx', (w - texts.value.getBBox().width) / 2 - padding); | |
262 | } | |
263 | if (texts.x_label) { | |
264 | texts.x_label.setAttribute('dx', w - texts.x_label.getBBox().width - 2 * padding); | |
265 | } | |
266 | if (texts.xlink) { | |
267 | texts.xlink.setAttribute('dx', w - texts.xlink.getBBox().width - 2 * padding); | |
268 | } | |
269 | x_elt = sibl(el, '.x').one(); | |
270 | y_elt = sibl(el, '.y').one(); | |
271 | x = parseInt(x_elt.textContent); | |
272 | if (x_elt.classList.contains('centered')) { | |
273 | x -= w / 2; | |
274 | } else if (x_elt.classList.contains('left')) { | |
275 | x -= w; | |
276 | } else if (x_elt.classList.contains('auto')) { | |
277 | x = xconvert(el.getBBox().x + el.getBBox().width / 2) - w / 2; | |
278 | } | |
279 | y = parseInt(y_elt.textContent); | |
280 | if (y_elt.classList.contains('centered')) { | |
281 | y -= h / 2; | |
282 | } else if (y_elt.classList.contains('top')) { | |
283 | y -= h; | |
284 | } else if (y_elt.classList.contains('auto')) { | |
285 | y = yconvert(el.getBBox().y + el.getBBox().height / 2) - h / 2; | |
286 | } | |
287 | _ref7 = get_translation(tt.parentElement), plot_x = _ref7[0], plot_y = _ref7[1]; | |
288 | if (x + w + plot_x > config.width) { | |
289 | x = config.width - w - plot_x; | |
290 | } | |
291 | if (y + h + plot_y > config.height) { | |
292 | y = config.height - h - plot_y; | |
293 | } | |
294 | if (x + plot_x < 0) { | |
295 | x = -plot_x; | |
296 | } | |
297 | if (y + plot_y < 0) { | |
298 | y = -plot_y; | |
299 | } | |
300 | _ref8 = get_translation(tt), current_x = _ref8[0], current_y = _ref8[1]; | |
301 | if (current_x === x && current_y === y) { | |
302 | return el; | |
303 | } | |
304 | tt.setAttribute('transform', "translate(" + x + " " + y + ")"); | |
305 | return el; | |
306 | }; | |
307 | return untooltip = function(ms) { | |
308 | return tooltip_timeout = setTimeout(function() { | |
309 | tt.style.display = 'none'; | |
310 | tt.style.opacity = 0; | |
311 | if (tooltip_el != null) { | |
312 | tooltip_el.classList.remove('active'); | |
313 | } | |
314 | return tooltip_timeout = null; | |
315 | }, ms); | |
316 | }; | |
317 | }; | |
318 | ||
319 | init_svg = function() { | |
320 | var chart, charts, _i, _len, _results; | |
321 | charts = $('.pygal-chart'); | |
322 | if (charts.length) { | |
323 | _results = []; | |
324 | for (_i = 0, _len = charts.length; _i < _len; _i++) { | |
325 | chart = charts[_i]; | |
326 | _results.push(init(chart)); | |
327 | } | |
328 | return _results; | |
329 | } | |
330 | }; | |
331 | ||
332 | if (document.readyState !== 'loading') { | |
333 | init_svg(); | |
334 | } else { | |
335 | document.addEventListener('DOMContentLoaded', function() { | |
336 | return init_svg(); | |
337 | }); | |
338 | } | |
339 | ||
340 | window.pygal = window.pygal || {}; | |
341 | ||
342 | window.pygal.init = init; | |
343 | ||
344 | window.pygal.init_svg = init_svg; | |
345 | ||
346 | }).call(this); | |
347 | </script></defs><title>Speed in Microseconds (us)</title><g class="graph custombox-graph vertical"><rect x="0" y="0" width="800" height="600" class="background" /><g transform="translate(74, 46)" class="plot"><rect x="0" y="0" width="706.0" height="360.0" class="background" /><g class="axis y always_show"><path d="M0.000000 360.000000 h706.000000" class="line" /><g class="guides"><path d="M0.000000 347.816226 h706.000000" class="guide line" /><text x="-5" y="351.31622632686464" class="">20</text><title>20</title></g><g class="guides"><path d="M0.000000 326.773439 h706.000000" class="guide line" /><text x="-5" y="330.2734393266308" class="">40</text><title>40</title></g><g class="guides"><path d="M0.000000 305.730652 h706.000000" class="guide line" /><text x="-5" y="309.23065232639703" class="">60</text><title>60</title></g><g class="guides"><path d="M0.000000 284.687865 h706.000000" class="guide line" /><text x="-5" y="288.1878653261632" class="">80</text><title>80</title></g><g class="guides"><path d="M0.000000 263.645078 h706.000000" class="major guide line" /><text x="-5" y="267.1450783259294" class="major">100</text><title>100</title></g><g class="guides"><path d="M0.000000 242.602291 h706.000000" class="guide line" /><text x="-5" y="246.10229132569555" class="">120</text><title>120</title></g><g class="guides"><path d="M0.000000 221.559504 h706.000000" class="guide line" /><text x="-5" y="225.05950432546175" class="">140</text><title>140</title></g><g class="guides"><path d="M0.000000 200.516717 h706.000000" class="guide line" /><text x="-5" y="204.01671732522794" class="">160</text><title>160</title></g><g class="guides"><path d="M0.000000 179.473930 h706.000000" class="guide line" /><text x="-5" y="182.97393032499414" class="">180</text><title>180</title></g><g class="guides"><path d="M0.000000 158.431143 h706.000000" class="major guide line" /><text x="-5" y="161.9311433247603" class="major">200</text><title>200</title></g><g class="guides"><path d="M0.000000 137.388356 h706.000000" class="guide line" /><text x="-5" y="140.8883563245265" class="">220</text><title>220</title></g><g class="guides"><path d="M0.000000 116.345569 h706.000000" class="guide line" /><text x="-5" y="119.84556932429271" class="">240</text><title>240</title></g><g class="guides"><path d="M0.000000 95.302782 h706.000000" class="guide line" /><text x="-5" y="98.80278232405891" class="">260</text><title>260</title></g><g class="guides"><path d="M0.000000 74.259995 h706.000000" class="guide line" /><text x="-5" y="77.75999532382514" class="">280</text><title>280</title></g><g class="guides"><path d="M0.000000 53.217208 h706.000000" class="major guide line" /><text x="-5" y="56.71720832359131" class="major">300</text><title>300</title></g><g class="guides"><path d="M0.000000 32.174421 h706.000000" class="guide line" /><text x="-5" y="35.67442132335748" class="">320</text><title>320</title></g><g class="guides"><path d="M0.000000 11.131634 h706.000000" class="guide line" /><text x="-5" y="14.631634323123706" class="">340</text><title>340</title></g></g><g class="axis x"><path d="M0.000000 0.000000 v360.000000" class="line" /><g class="guides"><path d="M24.891026 0.000000 v360.000000" class="guide line" /><text x="24.89102564102564" y="375.0" class="backwards" transform="rotate(270 24.891026 375.000000)">simple_list_e</text></g><g class="guides"><path d="M47.519231 0.000000 v360.000000" class="guide line" /><text x="47.51923076923077" y="375.0" class="backwards" transform="rotate(270 47.519231 375.000000)">simple_tuple_e</text></g><g class="guides"><path d="M70.147436 0.000000 v360.000000" class="guide line" /><text x="70.1474358974359" y="375.0" class="backwards" transform="rotate(270 70.147436 375.000000)">simple_set_e</text></g><g class="guides"><path d="M92.775641 0.000000 v360.000000" class="guide line" /><text x="92.77564102564102" y="375.0" class="backwards" transform="rotate(270 92.775641 375.000000)">simple_dict_e</text></g><g class="guides"><path d="M115.403846 0.000000 v360.000000" class="guide line" /><text x="115.40384615384615" y="375.0" class="backwards" transform="rotate(270 115.403846 375.000000)">simple_dict_d</text></g><g class="guides"><path d="M138.032051 0.000000 v360.000000" class="guide line" /><text x="138.03205128205127" y="375.0" class="backwards" transform="rotate(270 138.032051 375.000000)">simple_tuple_d</text></g><g class="guides"><path d="M160.660256 0.000000 v360.000000" class="guide line" /><text x="160.6602564102564" y="375.0" class="backwards" transform="rotate(270 160.660256 375.000000)">simple_set_d</text></g><g class="guides"><path d="M183.288462 0.000000 v360.000000" class="guide line" /><text x="183.28846153846155" y="375.0" class="backwards" transform="rotate(270 183.288462 375.000000)">simple_list_d</text></g><g class="guides"><path d="M205.916667 0.000000 v360.000000" class="guide line" /><text x="205.91666666666666" y="375.0" class="backwards" transform="rotate(270 205.916667 375.000000)">complex_homog_list_e</text></g><g class="guides"><path d="M228.544872 0.000000 v360.000000" class="guide line" /><text x="228.5448717948718" y="375.0" class="backwards" transform="rotate(270 228.544872 375.000000)">complex_homog_dict_d</text></g><g class="guides"><path d="M251.173077 0.000000 v360.000000" class="guide line" /><text x="251.17307692307688" y="375.0" class="backwards" transform="rotate(270 251.173077 375.000000)">complex_homog_set_e</text></g><g class="guides"><path d="M273.801282 0.000000 v360.000000" class="guide line" /><text x="273.8012820512821" y="375.0" class="backwards" transform="rotate(270 273.801282 375.000000)">complex_homog_tuple_e</text></g><g class="guides"><path d="M296.429487 0.000000 v360.000000" class="guide line" /><text x="296.4294871794872" y="375.0" class="backwards" transform="rotate(270 296.429487 375.000000)">complex_heterog_set_e</text></g><g class="guides"><path d="M319.057692 0.000000 v360.000000" class="guide line" /><text x="319.05769230769226" y="375.0" class="backwards" transform="rotate(270 319.057692 375.000000)">complex_heterog_dict_d</text></g><g class="guides"><path d="M341.685897 0.000000 v360.000000" class="guide line" /><text x="341.6858974358974" y="375.0" class="backwards" transform="rotate(270 341.685897 375.000000)">complex_homog_tuple_d</text></g><g class="guides"><path d="M364.314103 0.000000 v360.000000" class="guide line" /><text x="364.3141025641026" y="375.0" class="backwards" transform="rotate(270 364.314103 375.000000)">complex_homog_set_d</text></g><g class="guides"><path d="M386.942308 0.000000 v360.000000" class="guide line" /><text x="386.9423076923077" y="375.0" class="backwards" transform="rotate(270 386.942308 375.000000)">complex_heterog_set_d</text></g><g class="guides"><path d="M409.570513 0.000000 v360.000000" class="guide line" /><text x="409.5705128205129" y="375.0" class="backwards" transform="rotate(270 409.570513 375.000000)">simple_cls_d</text></g><g class="guides"><path d="M432.198718 0.000000 v360.000000" class="guide line" /><text x="432.19871794871796" y="375.0" class="backwards" transform="rotate(270 432.198718 375.000000)">complex_heterog_list_e</text></g><g class="guides"><path d="M454.826923 0.000000 v360.000000" class="guide line" /><text x="454.8269230769231" y="375.0" class="backwards" transform="rotate(270 454.826923 375.000000)">complex_heterog_tuple_e</text></g><g class="guides"><path d="M477.455128 0.000000 v360.000000" class="guide line" /><text x="477.4551282051282" y="375.0" class="backwards" transform="rotate(270 477.455128 375.000000)">complex_heterog_tuple_d</text></g><g class="guides"><path d="M500.083333 0.000000 v360.000000" class="guide line" /><text x="500.08333333333337" y="375.0" class="backwards" transform="rotate(270 500.083333 375.000000)">complex_heterog_list_d</text></g><g class="guides"><path d="M522.711538 0.000000 v360.000000" class="guide line" /><text x="522.7115384615385" y="375.0" class="backwards" transform="rotate(270 522.711538 375.000000)">complex_homog_list_d</text></g><g class="guides"><path d="M545.339744 0.000000 v360.000000" class="guide line" /><text x="545.3397435897435" y="375.0" class="backwards" transform="rotate(270 545.339744 375.000000)">complex_homog_dict_e</text></g><g class="guides"><path d="M567.967949 0.000000 v360.000000" class="guide line" /><text x="567.9679487179487" y="375.0" class="backwards" transform="rotate(270 567.967949 375.000000)">complex_heterog_dict_e</text></g><g class="guides"><path d="M590.596154 0.000000 v360.000000" class="guide line" /><text x="590.5961538461538" y="375.0" class="backwards" transform="rotate(270 590.596154 375.000000)">simple_cls_e</text></g><g class="guides"><path d="M613.224359 0.000000 v360.000000" class="guide line" /><text x="613.224358974359" y="375.0" class="backwards" transform="rotate(270 613.224359 375.000000)">complex_cls_d</text></g><g class="guides"><path d="M635.852564 0.000000 v360.000000" class="guide line" /><text x="635.8525641025641" y="375.0" class="backwards" transform="rotate(270 635.852564 375.000000)">state_cls_d</text></g><g class="guides"><path d="M658.480769 0.000000 v360.000000" class="guide line" /><text x="658.4807692307692" y="375.0" class="backwards" transform="rotate(270 658.480769 375.000000)">complex_cls_e</text></g><g class="guides"><path d="M681.108974 0.000000 v360.000000" class="guide line" /><text x="681.1089743589743" y="375.0" class="backwards" transform="rotate(270 681.108974 375.000000)">state_cls_e</text></g></g><g class="series serie-0 color-0"><g class="boxes"><g class="box"><path stroke-width="3" d="M19.912821 352.294131 L29.869231 352.294131" class="reactive tooltip-trigger" /><path stroke-width="3" d="M14.934615 351.603931 L34.847436 351.603931" class="reactive tooltip-trigger" /><path stroke-width="3" d="M19.912821 350.886371 L29.869231 350.886371" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 352.294131 L24.891026 351.768061" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 350.886371 L24.891026 351.415594" class="reactive tooltip-trigger" /><rect x="14.934615384615384" y="351.4155943513076" height="0.35246630398063417" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="352.4193371161533" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="71.16144256592486" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 15.6250 | |
348 | Q1-1.5IQR: 15.7440 | |
349 | Q1: 16.2440 | |
350 | Median: 16.4000 | |
351 | Q3: 16.5790 | |
352 | Q3+1.5IQR: 17.0820 | |
353 | Max: 282.9450</desc><desc class="x centered">24.891025641025642</desc><desc class="y centered">351.5936173174214</desc><desc class="x_label" /></g></g></g><g class="series serie-1 color-1"><g class="boxes"><g class="box"><path stroke-width="3" d="M42.541026 351.494505 L52.497436 351.494505" class="reactive tooltip-trigger" /><path stroke-width="3" d="M37.562821 350.944237 L57.475641 350.944237" class="reactive tooltip-trigger" /><path stroke-width="3" d="M42.541026 350.366612 L52.497436 350.366612" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 351.494505 L47.519231 351.074703" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 350.366612 L47.519231 350.791678" class="reactive tooltip-trigger" /><rect x="37.562820512820515" y="350.79167800882203" height="0.28302488433314466" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="351.6491696876072" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="334.39092910676317" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.3570 | |
354 | Q1-1.5IQR: 16.5040 | |
355 | Q1: 16.9030 | |
356 | Median: 17.0270 | |
357 | Q3: 17.1720 | |
358 | Q3+1.5IQR: 17.5760 | |
359 | Max: 32.7600</desc><desc class="x centered">47.519230769230774</desc><desc class="y centered">350.93434717003925</desc><desc class="x_label" /></g></g></g><g class="series serie-2 color-2"><g class="boxes"><g class="box"><path stroke-width="3" d="M65.169231 351.309331 L75.125641 351.309331" class="reactive tooltip-trigger" /><path stroke-width="3" d="M60.191026 350.753799 L80.103846 350.753799" class="reactive tooltip-trigger" /><path stroke-width="3" d="M65.169231 350.179333 L75.125641 350.179333" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 351.309331 L70.147436 350.888472" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 350.179333 L70.147436 350.605447" class="reactive tooltip-trigger" /><rect x="60.19102564102564" y="350.60544700719447" height="0.28302488433314466" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="351.42190999139245" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="331.6595755318382" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.5730 | |
360 | Q1-1.5IQR: 16.6800 | |
361 | Q1: 17.0800 | |
362 | Median: 17.2080 | |
363 | Q3: 17.3490 | |
364 | Q3+1.5IQR: 17.7540 | |
365 | Max: 35.3560</desc><desc class="x centered">70.1474358974359</desc><desc class="y centered">350.74727637966345</desc><desc class="x_label" /></g></g></g><g class="series serie-3 color-3"><g class="boxes"><g class="box"><path stroke-width="3" d="M87.797436 349.709024 L97.753846 349.709024" class="reactive tooltip-trigger" /><path stroke-width="3" d="M82.819231 348.872573 L102.732051 348.872573" class="reactive tooltip-trigger" /><path stroke-width="3" d="M87.797436 347.682607 L97.753846 347.682607" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 349.709024 L92.775641 349.072480" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 347.682607 L92.775641 348.516950" class="reactive tooltip-trigger" /><rect x="82.81923076923077" y="348.51694999660333" height="0.5555304002644448" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="349.70902419186234" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="121.51367929534689" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 18.2010 | |
366 | Q1-1.5IQR: 18.2010 | |
367 | Q1: 18.8060 | |
368 | Median: 18.9960 | |
369 | Q3: 19.3340 | |
370 | Q3+1.5IQR: 20.1270 | |
371 | Max: 235.0880</desc><desc class="x centered">92.77564102564102</desc><desc class="y centered">348.77072696032076</desc><desc class="x_label" /></g></g></g><g class="series serie-4 color-4"><g class="boxes"><g class="box"><path stroke-width="3" d="M110.425641 343.922260 L120.382051 343.922260" class="reactive tooltip-trigger" /><path stroke-width="3" d="M105.447436 343.263619 L125.360256 343.263619" class="reactive tooltip-trigger" /><path stroke-width="3" d="M110.425641 342.555528 L120.382051 342.555528" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 343.922260 L115.403846 343.413024" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 342.555528 L115.403846 343.070027" class="reactive tooltip-trigger" /><rect x="105.4474358974359" y="343.0700271623895" height="0.3429966715140722" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="343.9222596354314" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="323.53600500573083" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 23.7010 | |
372 | Q1-1.5IQR: 23.7010 | |
373 | Q1: 24.1850 | |
374 | Median: 24.3270 | |
375 | Q3: 24.5110 | |
376 | Q3+1.5IQR: 25.0000 | |
377 | Max: 43.0770</desc><desc class="x centered">115.40384615384615</desc><desc class="y centered">343.2448915429287</desc><desc class="x_label" /></g></g></g><g class="series serie-5 color-5"><g class="boxes"><g class="box"><path stroke-width="3" d="M133.053846 339.908349 L143.010256 339.908349" class="reactive tooltip-trigger" /><path stroke-width="3" d="M128.075641 339.200255 L147.988462 339.200255" class="reactive tooltip-trigger" /><path stroke-width="3" d="M133.053846 338.478492 L143.010256 338.478492" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 339.908349 L138.032051 339.373862" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 338.478492 L138.032051 339.017185" class="reactive tooltip-trigger" /><rect x="128.07564102564103" y="339.0171852284619" height="0.356676730703839" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="340.0861589862319" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="120.16904124468806" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 27.3470 | |
378 | Q1-1.5IQR: 27.5160 | |
379 | Q1: 28.0240 | |
380 | Median: 28.1890 | |
381 | Q3: 28.3630 | |
382 | Q3+1.5IQR: 28.8750 | |
383 | Max: 236.3660</desc><desc class="x centered">138.0320512820513</desc><desc class="y centered">339.19562847171585</desc><desc class="x_label" /></g></g></g><g class="series serie-6 color-6"><g class="boxes"><g class="box"><path stroke-width="3" d="M155.682051 339.137129 L165.638462 339.137129" class="reactive tooltip-trigger" /><path stroke-width="3" d="M150.703846 338.421674 L170.616667 338.421674" class="reactive tooltip-trigger" /><path stroke-width="3" d="M155.682051 337.693595 L165.638462 337.693595" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 339.137129 L160.660256 338.599484" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 337.693595 L160.660256 338.237548" class="reactive tooltip-trigger" /><rect x="150.70384615384614" y="338.2375481674493" height="0.3619359364471393" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="339.28337606122363" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="72.87853496451748" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 28.1100 | |
384 | Q1-1.5IQR: 28.2490 | |
385 | Q1: 28.7600 | |
386 | Median: 28.9290 | |
387 | Q3: 29.1040 | |
388 | Q3+1.5IQR: 29.6210 | |
389 | Max: 281.3130</desc><desc class="x centered">160.6602564102564</desc><desc class="y centered">338.41788610272863</desc><desc class="x_label" /></g></g></g><g class="series serie-7 color-7"><g class="boxes"><g class="box"><path stroke-width="3" d="M178.310256 337.842997 L188.266667 337.842997" class="reactive tooltip-trigger" /><path stroke-width="3" d="M173.332051 337.019169 L193.244872 337.019169" class="reactive tooltip-trigger" /><path stroke-width="3" d="M178.310256 336.149054 L188.266667 336.149054" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 337.842997 L183.288462 337.210660" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 336.149054 L183.288462 336.787703" class="reactive tooltip-trigger" /><rect x="173.33205128205125" y="336.7877030359598" height="0.42295650264821916" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="337.9345314115023" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="122.70680322654121" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 29.3920 | |
390 | Q1-1.5IQR: 29.4790 | |
391 | Q1: 30.0800 | |
392 | Median: 30.2620 | |
393 | Q3: 30.4820 | |
394 | Q3+1.5IQR: 31.0890 | |
395 | Max: 233.9540</desc><desc class="x centered">183.28846153846152</desc><desc class="y centered">337.00191653358974</desc><desc class="x_label" /></g></g></g><g class="series serie-8 color-8"><g class="boxes"><g class="box"><path stroke-width="3" d="M200.938462 320.043954 L210.894872 320.043954" class="reactive tooltip-trigger" /><path stroke-width="3" d="M195.960256 318.446809 L215.873077 318.446809" class="reactive tooltip-trigger" /><path stroke-width="3" d="M200.938462 316.764437 L210.894872 316.764437" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 320.043954 L205.916667 318.830838" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 316.764437 L205.916667 318.005435" class="reactive tooltip-trigger" /><rect x="195.9602564102564" y="318.00543534625456" height="0.8254024856635169" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="320.0439536347262" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="36.15571364666221" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 46.3960 | |
396 | Q1-1.5IQR: 46.3960 | |
397 | Q1: 47.5490 | |
398 | Median: 47.9140 | |
399 | Q3: 48.3335 | |
400 | Q3+1.5IQR: 49.5130 | |
401 | Max: 316.2160</desc><desc class="x centered">205.91666666666666</desc><desc class="y centered">318.41829448008843</desc><desc class="x_label" /></g></g></g><g class="series serie-9 color-9"><g class="boxes"><g class="box"><path stroke-width="3" d="M223.566667 319.699904 L233.523077 319.699904" class="reactive tooltip-trigger" /><path stroke-width="3" d="M218.588462 318.779283 L238.501282 318.779283" class="reactive tooltip-trigger" /><path stroke-width="3" d="M223.566667 317.782909 L233.523077 317.782909" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 319.699904 L228.544872 318.990765" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 317.782909 L228.544872 318.507833" class="reactive tooltip-trigger" /><rect x="218.58846153846153" y="318.50783303201786" height="0.4829321174897814" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="319.78092062200693" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="38.68926902945282" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 46.6460 | |
402 | Q1-1.5IQR: 46.7230 | |
403 | Q1: 47.3970 | |
404 | Median: 47.5980 | |
405 | Q3: 47.8560 | |
406 | Q3+1.5IQR: 48.5450 | |
407 | Max: 313.8080</desc><desc class="x centered">228.5448717948718</desc><desc class="y centered">318.7521388322045</desc><desc class="x_label" /></g></g></g><g class="series serie-10 color-10"><g class="boxes"><g class="box"><path stroke-width="3" d="M246.194872 316.825461 L256.151282 316.825461" class="reactive tooltip-trigger" /><path stroke-width="3" d="M241.216667 315.421908 L261.129487 315.421908" class="reactive tooltip-trigger" /><path stroke-width="3" d="M246.194872 313.916294 L256.151282 313.916294" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 316.825461 L251.173077 315.768059" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 313.916294 L251.173077 315.029462" class="reactive tooltip-trigger" /><rect x="241.21666666666664" y="315.02946172020296" height="0.7385968834435062" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="317.2431586401538" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="151.76794548514488" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 49.0580 | |
408 | Q1-1.5IQR: 49.4550 | |
409 | Q1: 50.4600 | |
410 | Median: 50.7890 | |
411 | Q3: 51.1620 | |
412 | Q3+1.5IQR: 52.2200 | |
413 | Max: 206.3330</desc><desc class="x centered">251.1730769230769</desc><desc class="y centered">315.39223667986624</desc><desc class="x_label" /></g></g></g><g class="series serie-11 color-11"><g class="boxes"><g class="box"><path stroke-width="3" d="M268.823077 317.085340 L278.779487 317.085340" class="reactive tooltip-trigger" /><path stroke-width="3" d="M263.844872 315.614451 L283.757692 315.614451" class="reactive tooltip-trigger" /><path stroke-width="3" d="M268.823077 314.020460 L278.779487 314.020460" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 317.085340 L273.801282 315.952711" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 314.020460 L273.801282 315.195435" class="reactive tooltip-trigger" /><rect x="263.84487179487184" y="315.19543482780097" height="0.7572758674518241" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="317.17582243386795" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="293.9698411999832" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 49.1220 | |
414 | Q1-1.5IQR: 49.2080 | |
415 | Q1: 50.2845 | |
416 | Median: 50.6060 | |
417 | Q3: 51.0043 | |
418 | Q3+1.5IQR: 52.1210 | |
419 | Max: 71.1780</desc><desc class="x centered">273.8012820512821</desc><desc class="y centered">315.5736792780113</desc><desc class="x_label" /></g></g></g><g class="series serie-12 color-12"><g class="boxes"><g class="box"><path stroke-width="3" d="M291.451282 314.157234 L301.407692 314.157234" class="reactive tooltip-trigger" /><path stroke-width="3" d="M286.473077 312.689504 L306.385897 312.689504" class="reactive tooltip-trigger" /><path stroke-width="3" d="M291.451282 311.163900 L301.407692 311.163900" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 314.157234 L296.429487 313.036705" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 311.163900 L296.429487 312.287586" class="reactive tooltip-trigger" /><rect x="286.473076923077" y="312.28758590613063" height="0.7491191225908551" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="314.25297865157205" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="166.53998267319162" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 51.9000 | |
420 | Q1-1.5IQR: 51.9910 | |
421 | Q1: 53.0560 | |
422 | Median: 53.3860 | |
423 | Q3: 53.7680 | |
424 | Q3+1.5IQR: 54.8360 | |
425 | Max: 192.2930</desc><desc class="x centered">296.42948717948724</desc><desc class="y centered">312.6669855443274</desc><desc class="x_label" /></g></g></g><g class="series serie-13 color-13"><g class="boxes"><g class="box"><path stroke-width="3" d="M314.079487 310.134910 L324.035897 310.134910" class="reactive tooltip-trigger" /><path stroke-width="3" d="M309.101282 308.377837 L329.014103 308.377837" class="reactive tooltip-trigger" /><path stroke-width="3" d="M314.079487 306.556583 L324.035897 306.556583" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 310.134910 L319.057692 308.795535" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 306.556583 L319.057692 307.900164" class="reactive tooltip-trigger" /><rect x="309.1012820512821" y="307.90016432647474" height="0.8953702086513431" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="310.63888232050465" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="173.65138958100692" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 55.3350 | |
426 | Q1-1.5IQR: 55.8140 | |
427 | Q1: 57.0870 | |
428 | Median: 57.4840 | |
429 | Q3: 57.9380 | |
430 | Q3+1.5IQR: 59.2150 | |
431 | Max: 185.5340</desc><desc class="x centered">319.0576923076924</desc><desc class="y centered">308.3530056724721</desc><desc class="x_label" /></g></g></g><g class="series serie-14 color-14"><g class="boxes"><g class="box"><path stroke-width="3" d="M336.707692 308.566166 L346.664103 308.566166" class="reactive tooltip-trigger" /><path stroke-width="3" d="M331.729487 307.531913 L351.642308 307.531913" class="reactive tooltip-trigger" /><path stroke-width="3" d="M336.707692 306.446109 L346.664103 306.446109" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 308.566166 L341.685897 307.786533" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 306.446109 L341.685897 307.250467" class="reactive tooltip-trigger" /><rect x="331.7294871794872" y="307.25046677563085" height="0.5360657889061713" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="308.9102189037446" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="172.1373622356133" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 56.9780 | |
432 | Q1-1.5IQR: 57.3050 | |
433 | Q1: 58.0460 | |
434 | Median: 58.2880 | |
435 | Q3: 58.5555 | |
436 | Q3+1.5IQR: 59.3200 | |
437 | Max: 186.9730</desc><desc class="x centered">341.68589743589746</desc><desc class="y centered">307.5162373312524</desc><desc class="x_label" /></g></g></g><g class="series serie-15 color-15"><g class="boxes"><g class="box"><path stroke-width="3" d="M359.335897 307.552957 L369.292308 307.552957" class="reactive tooltip-trigger" /><path stroke-width="3" d="M354.357692 306.421906 L374.270513 306.421906" class="reactive tooltip-trigger" /><path stroke-width="3" d="M359.335897 305.224572 L369.292308 305.224572" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 307.552957 L364.314103 306.693357" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 305.224572 L364.314103 306.106266" class="reactive tooltip-trigger" /><rect x="354.35769230769233" y="306.10626608912975" height="0.5870913762154828" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="307.9148931646846" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="205.57856165476795" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 57.9240 | |
438 | Q1-1.5IQR: 58.2680 | |
439 | Q1: 59.0850 | |
440 | Median: 59.3430 | |
441 | Q3: 59.6430 | |
442 | Q3+1.5IQR: 60.4810 | |
443 | Max: 155.1890</desc><desc class="x centered">364.3141025641026</desc><desc class="y centered">306.399811872929</desc><desc class="x_label" /></g></g></g><g class="series serie-16 color-16"><g class="boxes"><g class="box"><path stroke-width="3" d="M381.964103 307.046879 L391.920513 307.046879" class="reactive tooltip-trigger" /><path stroke-width="3" d="M376.985897 305.812719 L396.898718 305.812719" class="reactive tooltip-trigger" /><path stroke-width="3" d="M381.964103 304.538579 L391.920513 304.538579" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 307.046879 L386.942308 306.108633" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 304.538579 L386.942308 305.481293" class="reactive tooltip-trigger" /><rect x="376.98589743589747" y="305.4812933123027" height="0.627340184943705" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="307.18891607842875" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="234.8911620802628" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 58.6140 | |
444 | Q1-1.5IQR: 58.7490 | |
445 | Q1: 59.6407 | |
446 | Median: 59.9220 | |
447 | Q3: 60.2370 | |
448 | Q3+1.5IQR: 61.1330 | |
449 | Max: 127.3290</desc><desc class="x centered">386.94230769230774</desc><desc class="y centered">305.79762075818593</desc><desc class="x_label" /></g></g></g><g class="series serie-17 color-17"><g class="boxes"><g class="box"><path stroke-width="3" d="M404.592308 306.305121 L414.548718 306.305121" class="reactive tooltip-trigger" /><path stroke-width="3" d="M399.614103 304.230299 L419.526923 304.230299" class="reactive tooltip-trigger" /><path stroke-width="3" d="M404.592308 302.112347 L414.548718 302.112347" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 306.305121 L409.570513 304.749268" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 302.112347 L409.570513 303.695550" class="reactive tooltip-trigger" /><rect x="399.6141025641026" y="303.69554990598834" height="1.053717659304482" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="307.14157174375674" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="281.7471370119571" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 58.6590 | |
450 | Q1-1.5IQR: 59.4540 | |
451 | Q1: 60.9328 | |
452 | Median: 61.4260 | |
453 | Q3: 61.9343 | |
454 | Q3+1.5IQR: 63.4390 | |
455 | Max: 82.7950</desc><desc class="x centered">409.5705128205129</desc><desc class="y centered">304.21851686597563</desc><desc class="x_label" /></g></g></g><g class="series serie-18 color-18"><g class="boxes"><g class="box"><path stroke-width="3" d="M427.220513 306.211477 L437.176923 306.211477" class="reactive tooltip-trigger" /><path stroke-width="3" d="M422.242308 303.826280 L442.155128 303.826280" class="reactive tooltip-trigger" /><path stroke-width="3" d="M427.220513 301.335864 L437.176923 301.335864" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 306.211477 L432.198718 304.388649" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 301.335864 L432.198718 303.173428" class="reactive tooltip-trigger" /><rect x="422.24230769230775" y="303.17342828485727" height="1.215221016169778" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="306.8543364327004" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="70.42705228154392" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 58.9320 | |
456 | Q1-1.5IQR: 59.5430 | |
457 | Q1: 61.2755 | |
458 | Median: 61.8100 | |
459 | Q3: 62.4305 | |
460 | Q3+1.5IQR: 64.1770 | |
461 | Max: 283.6430</desc><desc class="x centered">432.198717948718</desc><desc class="y centered">303.78713970126404</desc><desc class="x_label" /></g></g></g><g class="series serie-19 color-19"><g class="boxes"><g class="box"><path stroke-width="3" d="M449.848718 305.209843 L459.805128 305.209843" class="reactive tooltip-trigger" /><path stroke-width="3" d="M444.870513 303.121345 L464.783333 303.121345" class="reactive tooltip-trigger" /><path stroke-width="3" d="M449.848718 300.953940 L459.805128 300.953940" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 305.209843 L454.826923 303.618221" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 300.953940 L454.826923 302.557138" class="reactive tooltip-trigger" /><rect x="444.87051282051283" y="302.55713759931643" height="1.0610830353246001" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="305.65384808240117" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="197.03518861839413" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 60.0730 | |
462 | Q1-1.5IQR: 60.4950 | |
463 | Q1: 62.0077 | |
464 | Median: 62.4800 | |
465 | Q3: 63.0162 | |
466 | Q3+1.5IQR: 64.5400 | |
467 | Max: 163.3090</desc><desc class="x centered">454.8269230769231</desc><desc class="y centered">303.09209738567563</desc><desc class="x_label" /></g></g></g><g class="series serie-20 color-20"><g class="boxes"><g class="box"><path stroke-width="3" d="M472.476923 304.609069 L482.433333 304.609069" class="reactive tooltip-trigger" /><path stroke-width="3" d="M467.498718 303.138183 L487.411538 303.138183" class="reactive tooltip-trigger" /><path stroke-width="3" d="M472.476923 301.594691 L482.433333 301.594691" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 304.609069 L477.455128 303.495909" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 301.594691 L477.455128 302.739421" class="reactive tooltip-trigger" /><rect x="467.49871794871797" y="302.739421325891" height="0.7564873693564209" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="304.83949031156476" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="209.16845568749827" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 60.8470 | |
468 | Q1-1.5IQR: 61.0660 | |
469 | Q1: 62.1240 | |
470 | Median: 62.4640 | |
471 | Q3: 62.8430 | |
472 | Q3+1.5IQR: 63.9310 | |
473 | Max: 151.7770</desc><desc class="x centered">477.45512820512823</desc><desc class="y centered">303.1154545365395</desc><desc class="x_label" /></g></g></g><g class="series serie-21 color-21"><g class="boxes"><g class="box"><path stroke-width="3" d="M495.105128 302.476384 L505.061538 302.476384" class="reactive tooltip-trigger" /><path stroke-width="3" d="M490.126923 300.710895 L510.039744 300.710895" class="reactive tooltip-trigger" /><path stroke-width="3" d="M495.105128 298.868600 L505.061538 298.868600" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 302.476384 L500.083333 301.135432" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 298.868600 L500.083333 300.229016" class="reactive tooltip-trigger" /><rect x="490.1269230769231" y="300.22901563475665" height="0.9064168373087114" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="302.734158292487" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="117.16729023793886" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 62.8480 | |
474 | Q1-1.5IQR: 63.0930 | |
475 | Q1: 64.3675 | |
476 | Median: 64.7710 | |
477 | Q3: 65.2290 | |
478 | Q3+1.5IQR: 66.5220 | |
479 | Max: 239.2190</desc><desc class="x centered">500.08333333333337</desc><desc class="y centered">300.68406554095327</desc><desc class="x_label" /></g></g></g><g class="series serie-22 color-22"><g class="boxes"><g class="box"><path stroke-width="3" d="M517.733333 302.208092 L527.689744 302.208092" class="reactive tooltip-trigger" /><path stroke-width="3" d="M512.755128 300.832944 L532.667949 300.832944" class="reactive tooltip-trigger" /><path stroke-width="3" d="M517.733333 299.324176 L527.689744 299.324176" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 302.208092 L522.711538 301.165418" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 299.324176 L522.711538 300.429185" class="reactive tooltip-trigger" /><rect x="512.7551282051282" y="300.4291850626683" height="0.7362333029875003" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="302.4395585623257" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="-27.67863097392467" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 63.1280 | |
480 | Q1-1.5IQR: 63.3480 | |
481 | Q1: 64.3390 | |
482 | Median: 64.6550 | |
483 | Q3: 65.0388 | |
484 | Q3+1.5IQR: 66.0890 | |
485 | Max: 376.8870</desc><desc class="x centered">522.7115384615385</desc><desc class="y centered">300.79196308446006</desc><desc class="x_label" /></g></g></g><g class="series serie-23 color-23"><g class="boxes"><g class="box"><path stroke-width="3" d="M540.361538 300.234275 L550.317949 300.234275" class="reactive tooltip-trigger" /><path stroke-width="3" d="M535.383333 297.865910 L555.296154 297.865910" class="reactive tooltip-trigger" /><path stroke-width="3" d="M540.361538 295.472294 L550.317949 295.472294" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 300.234275 L545.339744 298.455896" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 295.472294 L545.339744 297.266192" class="reactive tooltip-trigger" /><rect x="535.3833333333333" y="297.2661919368937" height="1.1897039163969225" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="301.0833533211601" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="251.80851120295435" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 64.4170 | |
486 | Q1-1.5IQR: 65.2240 | |
487 | Q1: 66.9143 | |
488 | Median: 67.4750 | |
489 | Q3: 68.0450 | |
490 | Q3+1.5IQR: 69.7500 | |
491 | Max: 111.2500</desc><desc class="x centered">545.3397435897435</desc><desc class="y centered">297.8589132277872</desc><desc class="x_label" /></g></g></g><g class="series serie-24 color-24"><g class="boxes"><g class="box"><path stroke-width="3" d="M562.989744 297.604982 L572.946154 297.604982" class="reactive tooltip-trigger" /><path stroke-width="3" d="M558.011538 295.098785 L577.924359 295.098785" class="reactive tooltip-trigger" /><path stroke-width="3" d="M562.989744 292.597847 L572.946154 292.597847" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 297.604982 L567.967949 295.744800" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 292.597847 L567.967949 294.487490" class="reactive tooltip-trigger" /><rect x="558.0115384615385" y="294.48749019963606" height="1.257309972759117" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="298.4256477649451" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="266.24281092523034" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 66.9430 | |
492 | Q1-1.5IQR: 67.7230 | |
493 | Q1: 69.4910 | |
494 | Median: 70.1050 | |
495 | Q3: 70.6860 | |
496 | Q3+1.5IQR: 72.4820 | |
497 | Max: 97.5310</desc><desc class="x centered">567.9679487179487</desc><desc class="y centered">295.10678081421713</desc><desc class="x_label" /></g></g></g><g class="series serie-25 color-25"><g class="boxes"><g class="box"><path stroke-width="3" d="M585.617949 285.832594 L595.574359 285.832594" class="reactive tooltip-trigger" /><path stroke-width="3" d="M580.639744 283.334812 L600.552564 283.334812" class="reactive tooltip-trigger" /><path stroke-width="3" d="M585.617949 280.710779 L595.574359 280.710779" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 285.832594 L590.596154 283.932429" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 280.710779 L590.596154 282.649872" class="reactive tooltip-trigger" /><rect x="580.6397435897436" y="282.64987163971335" height="1.2825572224556367" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="285.88099138369955" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="157.19382671180955" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 78.8660 | |
498 | Q1-1.5IQR: 78.9120 | |
499 | Q1: 80.7180 | |
500 | Median: 81.2860 | |
501 | Q3: 81.9370 | |
502 | Q3+1.5IQR: 83.7800 | |
503 | Max: 201.1760</desc><desc class="x centered">590.5961538461538</desc><desc class="y centered">283.29209721418783</desc><desc class="x_label" /></g></g></g><g class="series serie-26 color-26"><g class="boxes"><g class="box"><path stroke-width="3" d="M608.246154 57.653027 L618.202564 57.653027" class="reactive tooltip-trigger" /><path stroke-width="3" d="M603.267949 53.035188 L623.180769 53.035188" class="reactive tooltip-trigger" /><path stroke-width="3" d="M608.246154 48.265839 L618.202564 48.265839" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 57.653027 L613.224359 54.149403" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 48.265839 L613.224359 51.799451" class="reactive tooltip-trigger" /><rect x="603.2679487179488" y="51.799450789854575" height="2.349952070204381" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="59.18915159343044" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="-218.04220087924796" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 294.3240 | |
504 | Q1-1.5IQR: 295.7840 | |
505 | Q1: 299.1140 | |
506 | Median: 300.1730 | |
507 | Q3: 301.3475 | |
508 | Q3+1.5IQR: 304.7060 | |
509 | Max: 557.8170</desc><desc class="x centered">613.224358974359</desc><desc class="y centered">52.98058151191094</desc><desc class="x_label" /></g></g></g><g class="series serie-27 color-27"><g class="boxes"><g class="box"><path stroke-width="3" d="M630.874359 50.724690 L640.830769 50.724690" class="reactive tooltip-trigger" /><path stroke-width="3" d="M625.896154 45.601821 L645.808974 45.601821" class="reactive tooltip-trigger" /><path stroke-width="3" d="M630.874359 39.336335 L640.830769 39.336335" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 50.724690 L635.852564 46.765752" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 39.336335 L635.852564 43.798719" class="reactive tooltip-trigger" /><rect x="625.8961538461539" y="43.798719463396424" height="2.9670322107558036" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="50.72468960917058" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="-311.24806893349046" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 302.3690 | |
510 | Q1-1.5IQR: 302.3690 | |
511 | Q1: 306.1318 | |
512 | Median: 307.2380 | |
513 | Q3: 308.9518 | |
514 | Q3+1.5IQR: 313.1930 | |
515 | Max: 646.4040</desc><desc class="x centered">635.8525641025641</desc><desc class="y centered">45.24546342422127</desc><desc class="x_label" /></g></g></g><g class="series serie-28 color-28"><g class="boxes"><g class="box"><path stroke-width="3" d="M653.502564 28.092123 L663.458974 28.092123" class="reactive tooltip-trigger" /><path stroke-width="3" d="M648.524359 22.547347 L668.437179 22.547347" class="reactive tooltip-trigger" /><path stroke-width="3" d="M653.502564 16.595395 L663.458974 16.595395" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 28.092123 L658.480769 23.802024" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 16.595395 L658.480769 20.930210" class="reactive tooltip-trigger" /><rect x="648.524358974359" y="20.930209672866738" height="2.8718143673259533" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="28.092122563057103" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="-208.7981056616361" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 323.8800 | |
516 | Q1-1.5IQR: 323.8800 | |
517 | Q1: 327.9575 | |
518 | Median: 329.1500 | |
519 | Q3: 330.6870 | |
520 | Q3+1.5IQR: 334.8070 | |
521 | Max: 549.0310</desc><desc class="x centered">658.4807692307692</desc><desc class="y centered">22.39341965569082</desc><desc class="x_label" /></g></g></g><g class="series serie-29 color-29"><g class="boxes"><g class="box"><path stroke-width="3" d="M676.130769 17.980010 L686.087179 17.980010" class="reactive tooltip-trigger" /><path stroke-width="3" d="M671.152564 12.853459 L691.065385 12.853459" class="reactive tooltip-trigger" /><path stroke-width="3" d="M676.130769 7.089316 L686.087179 7.089316" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 17.980010 L681.108974 14.104978" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 7.089316 L681.108974 11.311547" class="reactive tooltip-trigger" /><rect x="671.1525641025642" y="11.311547238638184" height="2.7934305754675393" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="18.467148316404405" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="-252.52291255209218" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 333.0280 | |
522 | Q1-1.5IQR: 333.4910 | |
523 | Q1: 337.1740 | |
524 | Median: 338.3635 | |
525 | Q3: 339.8290 | |
526 | Q3+1.5IQR: 343.8420 | |
527 | Max: 590.5890</desc><desc class="x centered">681.1089743589744</desc><desc class="y centered">12.667861950898612</desc><desc class="x_label" /></g></g></g></g><g class="titles"><text x="400.0" y="26" class="title plot_title">Speed in Microseconds (us)</text><text x="427.0" y="580.0" class="title">Trial</text><text x="0" y="252.0" class="title" transform="rotate(-90 0.000000 226.000000)">Duration</text></g><g transform="translate(74, 46)" class="plot overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot text-overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot tooltip-overlay"><g transform="translate(0 0)" style="opacity: 0" class="tooltip"><rect rx="0" ry="0" width="0" height="0" class="tooltip-box" /><g class="text" /></g></g></g></svg>⏎ |
0 | <?xml version='1.0' encoding='utf-8'?> | |
1 | <svg xmlns="http://www.w3.org/2000/svg" id="chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969" class="pygal-chart" viewBox="0 0 800 600"><!--Generated with pygal 3.0.0 (etree) ©Kozea 2012-2016 on 2022-06-20--><!--http://pygal.org--><!--http://github.com/Kozea/pygal--><defs><style type="text/css">#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .title{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .legends .legend text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis text.major{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay text.value{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay text.label{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 text.no_data{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:64px} | |
2 | #chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969{background-color:rgba(249,249,249,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 path,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 line,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 rect,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .graph > .background{fill:rgba(249,249,249,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .plot > .background{fill:rgba(255,255,255,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .graph{fill:rgba(0,0,0,.87)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 text.no_data{fill:rgba(0,0,0,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .title{fill:rgba(0,0,0,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .legends .legend text{fill:rgba(0,0,0,.87)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis .line{stroke:rgba(0,0,0,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis text.major{fill:rgba(0,0,0,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.y .guides:hover .guide.line,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .line-graph .axis.x .guides:hover .guide.line,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .stackedline-graph .axis.x .guides:hover .guide.line,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .reactive{fill-opacity:.7;stroke-opacity:.8;stroke-width:1}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .ci{stroke:rgba(0,0,0,.87)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .reactive.active,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .ci .reactive.active{stroke-width:1.5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .series text{fill:rgba(0,0,0,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip .value{font-size:1.5em}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .bound{font-size:.5em}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-0,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-0 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-1,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-1 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-2,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-2 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-3,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-3 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-4,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-4 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-5,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-5 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-6,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-6 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-7,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-7 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-8,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-8 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-9,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-9 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-10,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-10 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-11,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-11 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-12,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-12 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-13,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-13 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-14,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-14 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-15,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-15 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-16,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-16 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-17,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-17 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-18,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-18 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-19,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-19 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-20,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-20 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-21,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-21 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-22,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-22 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-23,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-23 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-24,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-24 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-25,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-25 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-26,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-26 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-27,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-27 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-28,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-28 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-29,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .color-29 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-0 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-1 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-2 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-3 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-4 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-5 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-6 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-7 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-8 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-9 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-10 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-11 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-12 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-13 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-14 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-15 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-16 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-17 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-18 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-19 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-20 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-21 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-22 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-23 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-24 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-25 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-26 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-27 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-28 text{fill:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .text-overlay .color-29 text{fill:black} | |
3 | #chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 text.no_data{text-anchor:middle}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .guide.line{fill:none}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .centered{text-anchor:middle}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .title{text-anchor:middle}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .legends .legend text{fill-opacity:1}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.x text{text-anchor:middle}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.x:not(.web) text[transform]{text-anchor:start}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.y text{text-anchor:end}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.y text[transform].backwards{text-anchor:start}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.y2 text{text-anchor:start}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.y2 text[transform].backwards{text-anchor:end}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis .guide.line{stroke-dasharray:4,4;stroke:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis .major.guide.line{stroke-dasharray:6,6;stroke:black}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .horizontal .axis.y .guide.line,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .horizontal .axis.y2 .guide.line,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .vertical .axis.x .guide.line{opacity:0}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .horizontal .axis.always_show .guide.line,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.y .guides:hover .guide.line,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.y2 .guides:hover .guide.line,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis.x .guides:hover .guide.line{opacity:1}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .axis .guides:hover text{opacity:1}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .nofill{fill:none}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .subtle-fill{fill-opacity:.2}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .dot{stroke-width:1px;fill-opacity:1;stroke-opacity:1}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .dot.active{stroke-width:5px}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .dot.negative{fill:transparent}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 text,#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 tspan{stroke:none !important}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .series text.active{opacity:1}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .tooltip text{fill-opacity:1}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .showable{visibility:hidden}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .showable.shown{visibility:visible}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-3d1f86d5-6953-4507-b5f9-1ad1b0395969 .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px} | |
4 | .tooltip .value{font-size:1em !important}.axis text{font-size:9px !important}</style><script type="text/javascript">window.pygal = window.pygal || {};window.pygal.config = window.pygal.config || {};window.pygal.config['3d1f86d5-6953-4507-b5f9-1ad1b0395969'] = {"allow_interruptions": false, "box_mode": "tukey", "classes": ["pygal-chart"], "css": ["file://style.css", "file://graph.css", "inline:\n .tooltip .value {\n font-size: 1em !important;\n }\n .axis text {\n font-size: 9px !important;\n }\n "], "defs": [], "disable_xml_declaration": false, "dots_size": 2.5, "dynamic_print_values": false, "explicit_size": false, "fill": false, "force_uri_protocol": "https", "formatter": null, "half_pie": false, "height": 600, "include_x_axis": false, "inner_radius": 0, "interpolate": null, "interpolation_parameters": {}, "interpolation_precision": 250, "inverse_y_axis": false, "js": ["file:///home/theel/.pyenv/versions/3.9.13/lib/python3.9/site-packages/pygaljs/static/2.0.x/pygal-tooltips.js"], "legend_at_bottom": false, "legend_at_bottom_columns": null, "legend_box_size": 12, "logarithmic": false, "margin": 20, "margin_bottom": null, "margin_left": null, "margin_right": null, "margin_top": null, "max_scale": 20, "min_scale": 20, "missing_value_fill_truncation": "x", "no_data_text": "No data", "no_prefix": false, "order_min": null, "pretty_print": false, "print_labels": false, "print_values": false, "print_values_position": "center", "print_zeroes": true, "range": [14, 155], "rounded_bars": null, "secondary_range": null, "show_dots": true, "show_legend": false, "show_minor_x_labels": true, "show_minor_y_labels": true, "show_only_major_dots": false, "show_x_guides": false, "show_x_labels": true, "show_y_guides": true, "show_y_labels": true, "spacing": 10, "stack_from_top": false, "strict": false, "stroke": true, "stroke_style": null, "style": {"background": "rgba(249, 249, 249, 1)", "ci_colors": [], "colors": ["#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5"], "dot_opacity": "1", "font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "foreground": "rgba(0, 0, 0, .87)", "foreground_strong": "rgba(0, 0, 0, 1)", "foreground_subtle": "rgba(0, 0, 0, .54)", "guide_stroke_color": "black", "guide_stroke_dasharray": "4,4", "label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "label_font_size": 10, "legend_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "legend_font_size": 14, "major_guide_stroke_color": "black", "major_guide_stroke_dasharray": "6,6", "major_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "major_label_font_size": 10, "no_data_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "no_data_font_size": 64, "opacity": ".7", "opacity_hover": ".8", "plot_background": "rgba(255, 255, 255, 1)", "stroke_opacity": ".8", "stroke_opacity_hover": ".9", "stroke_width": "1", "stroke_width_hover": "4", "title_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "title_font_size": 16, "tooltip_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "tooltip_font_size": 14, "transition": "150ms", "value_background": "rgba(229, 229, 229, 1)", "value_colors": [], "value_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_font_size": 16, "value_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_label_font_size": 10}, "title": "Speed in Microseconds (us)", "tooltip_border_radius": 0, "tooltip_fancy_mode": true, "truncate_label": 50, "truncate_legend": null, "width": 800, "x_label_rotation": 270, "x_labels": ["simple_list_e", "simple_tuple_e", "simple_set_e", "simple_tuple_d", "simple_set_d", "simple_dict_d", "simple_dict_e", "simple_list_d", "complex_homog_list_e", "complex_homog_tuple_d", "complex_homog_set_d", "complex_homog_tuple_e", "complex_homog_set_e", "complex_heterog_set_d", "complex_homog_dict_d", "complex_heterog_set_e", "complex_homog_list_d", "complex_heterog_tuple_d", "complex_heterog_dict_d", "complex_heterog_list_e", "complex_heterog_tuple_e", "complex_heterog_list_d", "complex_homog_dict_e", "simple_cls_d", "complex_heterog_dict_e", "simple_cls_e", "complex_cls_e", "complex_cls_d", "state_cls_d", "state_cls_e"], "x_labels_major": null, "x_labels_major_count": null, "x_labels_major_every": null, "x_title": "Trial", "xrange": null, "y_label_rotation": 0, "y_labels": null, "y_labels_major": null, "y_labels_major_count": null, "y_labels_major_every": null, "y_title": "Duration", "zero": 14, "legends": ["jsonpickle_benchmarks.py::simple_list_e - 16106 rounds", "jsonpickle_benchmarks.py::simple_tuple_e - 14375 rounds", "jsonpickle_benchmarks.py::simple_set_e - 15376 rounds", "jsonpickle_benchmarks.py::simple_tuple_d - 15959 rounds", "jsonpickle_benchmarks.py::simple_set_d - 15954 rounds", "jsonpickle_benchmarks.py::simple_dict_d - 11231 rounds", "jsonpickle_benchmarks.py::simple_dict_e - 7872 rounds", "jsonpickle_benchmarks.py::simple_list_d - 15533 rounds", "jsonpickle_benchmarks.py::complex_homog_list_e - 10981 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_d - 10620 rounds", "jsonpickle_benchmarks.py::complex_homog_set_d - 10385 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_e - 8312 rounds", "jsonpickle_benchmarks.py::complex_homog_set_e - 10361 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_d - 11168 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_d - 9421 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_e - 10165 rounds", "jsonpickle_benchmarks.py::complex_homog_list_d - 9762 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_d - 8956 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_d - 8725 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_e - 7798 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_e - 8356 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_d - 9295 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_e - 6419 rounds", "jsonpickle_benchmarks.py::simple_cls_d - 6577 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_e - 7613 rounds", "jsonpickle_benchmarks.py::simple_cls_e - 6312 rounds", "jsonpickle_benchmarks.py::complex_cls_e - 3978 rounds", "jsonpickle_benchmarks.py::complex_cls_d - 4349 rounds", "jsonpickle_benchmarks.py::state_cls_d - 4188 rounds", "jsonpickle_benchmarks.py::state_cls_e - 4007 rounds"]}</script><script type="text/javascript">(function() { | |
5 | var $, get_translation, init, init_svg, matches, padding, r_translation, sibl, svg_ns, tooltip_timeout, xlink_ns; | |
6 | ||
7 | svg_ns = 'http://www.w3.org/2000/svg'; | |
8 | ||
9 | xlink_ns = 'http://www.w3.org/1999/xlink'; | |
10 | ||
11 | $ = function(sel, ctx) { | |
12 | if (ctx == null) { | |
13 | ctx = null; | |
14 | } | |
15 | ctx = ctx || document; | |
16 | return Array.prototype.slice.call(ctx.querySelectorAll(sel), 0).filter(function(e) { | |
17 | return e !== ctx; | |
18 | }); | |
19 | }; | |
20 | ||
21 | matches = function(el, selector) { | |
22 | return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector); | |
23 | }; | |
24 | ||
25 | sibl = function(el, match) { | |
26 | if (match == null) { | |
27 | match = null; | |
28 | } | |
29 | return Array.prototype.filter.call(el.parentElement.children, function(child) { | |
30 | return child !== el && (!match || matches(child, match)); | |
31 | }); | |
32 | }; | |
33 | ||
34 | Array.prototype.one = function() { | |
35 | return this.length > 0 && this[0] || {}; | |
36 | }; | |
37 | ||
38 | padding = 5; | |
39 | ||
40 | tooltip_timeout = null; | |
41 | ||
42 | r_translation = /translate\((\d+)[ ,]+(\d+)\)/; | |
43 | ||
44 | get_translation = function(el) { | |
45 | return (r_translation.exec(el.getAttribute('transform')) || []).slice(1).map(function(x) { | |
46 | return +x; | |
47 | }); | |
48 | }; | |
49 | ||
50 | init = function(ctx) { | |
51 | var bbox, box, config, el, graph, inner_svg, num, parent, tooltip, tooltip_el, tt, uid, untooltip, xconvert, yconvert, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; | |
52 | if ($('svg', ctx).length) { | |
53 | inner_svg = $('svg', ctx).one(); | |
54 | parent = inner_svg.parentElement; | |
55 | box = inner_svg.viewBox.baseVal; | |
56 | bbox = parent.getBBox(); | |
57 | xconvert = function(x) { | |
58 | return ((x - box.x) / box.width) * bbox.width; | |
59 | }; | |
60 | yconvert = function(y) { | |
61 | return ((y - box.y) / box.height) * bbox.height; | |
62 | }; | |
63 | } else { | |
64 | xconvert = yconvert = function(x) { | |
65 | return x; | |
66 | }; | |
67 | } | |
68 | if (((_ref = window.pygal) != null ? _ref.config : void 0) != null) { | |
69 | if (window.pygal.config.no_prefix != null) { | |
70 | config = window.pygal.config; | |
71 | } else { | |
72 | uid = ctx.id.replace('chart-', ''); | |
73 | config = window.pygal.config[uid]; | |
74 | } | |
75 | } else { | |
76 | config = window.config; | |
77 | } | |
78 | tooltip_el = null; | |
79 | graph = $('.graph').one(); | |
80 | tt = $('.tooltip', ctx).one(); | |
81 | _ref1 = $('.reactive', ctx); | |
82 | for (_i = 0, _len = _ref1.length; _i < _len; _i++) { | |
83 | el = _ref1[_i]; | |
84 | el.addEventListener('mouseenter', (function(el) { | |
85 | return function() { | |
86 | return el.classList.add('active'); | |
87 | }; | |
88 | })(el)); | |
89 | el.addEventListener('mouseleave', (function(el) { | |
90 | return function() { | |
91 | return el.classList.remove('active'); | |
92 | }; | |
93 | })(el)); | |
94 | } | |
95 | _ref2 = $('.activate-serie', ctx); | |
96 | for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { | |
97 | el = _ref2[_j]; | |
98 | num = el.id.replace('activate-serie-', ''); | |
99 | el.addEventListener('mouseenter', (function(num) { | |
100 | return function() { | |
101 | var re, _k, _len2, _ref3, _results; | |
102 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
103 | _results = []; | |
104 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
105 | re = _ref3[_k]; | |
106 | _results.push(re.classList.add('active')); | |
107 | } | |
108 | return _results; | |
109 | }; | |
110 | })(num)); | |
111 | el.addEventListener('mouseleave', (function(num) { | |
112 | return function() { | |
113 | var re, _k, _len2, _ref3, _results; | |
114 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
115 | _results = []; | |
116 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
117 | re = _ref3[_k]; | |
118 | _results.push(re.classList.remove('active')); | |
119 | } | |
120 | return _results; | |
121 | }; | |
122 | })(num)); | |
123 | el.addEventListener('click', (function(el, num) { | |
124 | return function() { | |
125 | var ov, re, rect, show, _k, _l, _len2, _len3, _ref3, _ref4, _results; | |
126 | rect = $('rect', el).one(); | |
127 | show = rect.style.fill !== ''; | |
128 | rect.style.fill = show ? '' : 'transparent'; | |
129 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
130 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
131 | re = _ref3[_k]; | |
132 | re.style.display = show ? '' : 'none'; | |
133 | } | |
134 | _ref4 = $('.text-overlay .serie-' + num, ctx); | |
135 | _results = []; | |
136 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
137 | ov = _ref4[_l]; | |
138 | _results.push(ov.style.display = show ? '' : 'none'); | |
139 | } | |
140 | return _results; | |
141 | }; | |
142 | })(el, num)); | |
143 | } | |
144 | _ref3 = $('.tooltip-trigger', ctx); | |
145 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
146 | el = _ref3[_k]; | |
147 | el.addEventListener('mouseenter', (function(el) { | |
148 | return function() { | |
149 | return tooltip_el = tooltip(el); | |
150 | }; | |
151 | })(el)); | |
152 | } | |
153 | tt.addEventListener('mouseenter', function() { | |
154 | return tooltip_el != null ? tooltip_el.classList.add('active') : void 0; | |
155 | }); | |
156 | tt.addEventListener('mouseleave', function() { | |
157 | return tooltip_el != null ? tooltip_el.classList.remove('active') : void 0; | |
158 | }); | |
159 | ctx.addEventListener('mouseleave', function() { | |
160 | if (tooltip_timeout) { | |
161 | clearTimeout(tooltip_timeout); | |
162 | } | |
163 | return untooltip(0); | |
164 | }); | |
165 | graph.addEventListener('mousemove', function(el) { | |
166 | if (tooltip_timeout) { | |
167 | return; | |
168 | } | |
169 | if (!matches(el.target, '.background')) { | |
170 | return; | |
171 | } | |
172 | return untooltip(1000); | |
173 | }); | |
174 | tooltip = function(el) { | |
175 | var a, baseline, cls, current_x, current_y, dy, h, i, key, keys, label, legend, name, plot_x, plot_y, rect, serie_index, subval, text, text_group, texts, traversal, value, w, x, x_elt, x_label, xlink, y, y_elt, _l, _len3, _len4, _len5, _m, _n, _ref4, _ref5, _ref6, _ref7, _ref8; | |
176 | clearTimeout(tooltip_timeout); | |
177 | tooltip_timeout = null; | |
178 | tt.style.opacity = 1; | |
179 | tt.style.display = ''; | |
180 | text_group = $('g.text', tt).one(); | |
181 | rect = $('rect', tt).one(); | |
182 | text_group.innerHTML = ''; | |
183 | label = sibl(el, '.label').one().textContent; | |
184 | x_label = sibl(el, '.x_label').one().textContent; | |
185 | value = sibl(el, '.value').one().textContent; | |
186 | xlink = sibl(el, '.xlink').one().textContent; | |
187 | serie_index = null; | |
188 | parent = el; | |
189 | traversal = []; | |
190 | while (parent) { | |
191 | traversal.push(parent); | |
192 | if (parent.classList.contains('series')) { | |
193 | break; | |
194 | } | |
195 | parent = parent.parentElement; | |
196 | } | |
197 | if (parent) { | |
198 | _ref4 = parent.classList; | |
199 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
200 | cls = _ref4[_l]; | |
201 | if (cls.indexOf('serie-') === 0) { | |
202 | serie_index = +cls.replace('serie-', ''); | |
203 | break; | |
204 | } | |
205 | } | |
206 | } | |
207 | legend = null; | |
208 | if (serie_index !== null) { | |
209 | legend = config.legends[serie_index]; | |
210 | } | |
211 | dy = 0; | |
212 | keys = [[label, 'label']]; | |
213 | _ref5 = value.split('\n'); | |
214 | for (i = _m = 0, _len4 = _ref5.length; _m < _len4; i = ++_m) { | |
215 | subval = _ref5[i]; | |
216 | keys.push([subval, 'value-' + i]); | |
217 | } | |
218 | if (config.tooltip_fancy_mode) { | |
219 | keys.push([xlink, 'xlink']); | |
220 | keys.unshift([x_label, 'x_label']); | |
221 | keys.unshift([legend, 'legend']); | |
222 | } | |
223 | texts = {}; | |
224 | for (_n = 0, _len5 = keys.length; _n < _len5; _n++) { | |
225 | _ref6 = keys[_n], key = _ref6[0], name = _ref6[1]; | |
226 | if (key) { | |
227 | text = document.createElementNS(svg_ns, 'text'); | |
228 | text.textContent = key; | |
229 | text.setAttribute('x', padding); | |
230 | text.setAttribute('dy', dy); | |
231 | text.classList.add(name.indexOf('value') === 0 ? 'value' : name); | |
232 | if (name.indexOf('value') === 0 && config.tooltip_fancy_mode) { | |
233 | text.classList.add('color-' + serie_index); | |
234 | } | |
235 | if (name === 'xlink') { | |
236 | a = document.createElementNS(svg_ns, 'a'); | |
237 | a.setAttributeNS(xlink_ns, 'href', key); | |
238 | a.textContent = void 0; | |
239 | a.appendChild(text); | |
240 | text.textContent = 'Link >'; | |
241 | text_group.appendChild(a); | |
242 | } else { | |
243 | text_group.appendChild(text); | |
244 | } | |
245 | dy += text.getBBox().height + padding / 2; | |
246 | baseline = padding; | |
247 | if (text.style.dominantBaseline !== void 0) { | |
248 | text.style.dominantBaseline = 'text-before-edge'; | |
249 | } else { | |
250 | baseline += text.getBBox().height * .8; | |
251 | } | |
252 | text.setAttribute('y', baseline); | |
253 | texts[name] = text; | |
254 | } | |
255 | } | |
256 | w = text_group.getBBox().width + 2 * padding; | |
257 | h = text_group.getBBox().height + 2 * padding; | |
258 | rect.setAttribute('width', w); | |
259 | rect.setAttribute('height', h); | |
260 | if (texts.value) { | |
261 | texts.value.setAttribute('dx', (w - texts.value.getBBox().width) / 2 - padding); | |
262 | } | |
263 | if (texts.x_label) { | |
264 | texts.x_label.setAttribute('dx', w - texts.x_label.getBBox().width - 2 * padding); | |
265 | } | |
266 | if (texts.xlink) { | |
267 | texts.xlink.setAttribute('dx', w - texts.xlink.getBBox().width - 2 * padding); | |
268 | } | |
269 | x_elt = sibl(el, '.x').one(); | |
270 | y_elt = sibl(el, '.y').one(); | |
271 | x = parseInt(x_elt.textContent); | |
272 | if (x_elt.classList.contains('centered')) { | |
273 | x -= w / 2; | |
274 | } else if (x_elt.classList.contains('left')) { | |
275 | x -= w; | |
276 | } else if (x_elt.classList.contains('auto')) { | |
277 | x = xconvert(el.getBBox().x + el.getBBox().width / 2) - w / 2; | |
278 | } | |
279 | y = parseInt(y_elt.textContent); | |
280 | if (y_elt.classList.contains('centered')) { | |
281 | y -= h / 2; | |
282 | } else if (y_elt.classList.contains('top')) { | |
283 | y -= h; | |
284 | } else if (y_elt.classList.contains('auto')) { | |
285 | y = yconvert(el.getBBox().y + el.getBBox().height / 2) - h / 2; | |
286 | } | |
287 | _ref7 = get_translation(tt.parentElement), plot_x = _ref7[0], plot_y = _ref7[1]; | |
288 | if (x + w + plot_x > config.width) { | |
289 | x = config.width - w - plot_x; | |
290 | } | |
291 | if (y + h + plot_y > config.height) { | |
292 | y = config.height - h - plot_y; | |
293 | } | |
294 | if (x + plot_x < 0) { | |
295 | x = -plot_x; | |
296 | } | |
297 | if (y + plot_y < 0) { | |
298 | y = -plot_y; | |
299 | } | |
300 | _ref8 = get_translation(tt), current_x = _ref8[0], current_y = _ref8[1]; | |
301 | if (current_x === x && current_y === y) { | |
302 | return el; | |
303 | } | |
304 | tt.setAttribute('transform', "translate(" + x + " " + y + ")"); | |
305 | return el; | |
306 | }; | |
307 | return untooltip = function(ms) { | |
308 | return tooltip_timeout = setTimeout(function() { | |
309 | tt.style.display = 'none'; | |
310 | tt.style.opacity = 0; | |
311 | if (tooltip_el != null) { | |
312 | tooltip_el.classList.remove('active'); | |
313 | } | |
314 | return tooltip_timeout = null; | |
315 | }, ms); | |
316 | }; | |
317 | }; | |
318 | ||
319 | init_svg = function() { | |
320 | var chart, charts, _i, _len, _results; | |
321 | charts = $('.pygal-chart'); | |
322 | if (charts.length) { | |
323 | _results = []; | |
324 | for (_i = 0, _len = charts.length; _i < _len; _i++) { | |
325 | chart = charts[_i]; | |
326 | _results.push(init(chart)); | |
327 | } | |
328 | return _results; | |
329 | } | |
330 | }; | |
331 | ||
332 | if (document.readyState !== 'loading') { | |
333 | init_svg(); | |
334 | } else { | |
335 | document.addEventListener('DOMContentLoaded', function() { | |
336 | return init_svg(); | |
337 | }); | |
338 | } | |
339 | ||
340 | window.pygal = window.pygal || {}; | |
341 | ||
342 | window.pygal.init = init; | |
343 | ||
344 | window.pygal.init_svg = init_svg; | |
345 | ||
346 | }).call(this); | |
347 | </script></defs><title>Speed in Microseconds (us)</title><g class="graph custombox-graph vertical"><rect x="0" y="0" width="800" height="600" class="background" /><g transform="translate(74, 46)" class="plot"><rect x="0" y="0" width="706.0" height="360.0" class="background" /><g class="axis y always_show"><path d="M0.000000 360.000000 h706.000000" class="line" /><g class="guides"><path d="M0.000000 348.166939 h706.000000" class="guide line" /><text x="-5" y="351.66693944353517" class="">16</text><title>16</title></g><g class="guides"><path d="M0.000000 328.527005 h706.000000" class="guide line" /><text x="-5" y="332.02700490998365" class="">24</text><title>24</title></g><g class="guides"><path d="M0.000000 308.887070 h706.000000" class="guide line" /><text x="-5" y="312.38707037643206" class="">32</text><title>32</title></g><g class="guides"><path d="M0.000000 289.247136 h706.000000" class="guide line" /><text x="-5" y="292.74713584288054" class="">40</text><title>40</title></g><g class="guides"><path d="M0.000000 269.607201 h706.000000" class="guide line" /><text x="-5" y="273.10720130932896" class="">48</text><title>48</title></g><g class="guides"><path d="M0.000000 249.967267 h706.000000" class="guide line" /><text x="-5" y="253.4672667757774" class="">56</text><title>56</title></g><g class="guides"><path d="M0.000000 230.327332 h706.000000" class="guide line" /><text x="-5" y="233.82733224222585" class="">64</text><title>64</title></g><g class="guides"><path d="M0.000000 210.687398 h706.000000" class="guide line" /><text x="-5" y="214.1873977086743" class="">72</text><title>72</title></g><g class="guides"><path d="M0.000000 191.047463 h706.000000" class="guide line" /><text x="-5" y="194.54746317512274" class="">80</text><title>80</title></g><g class="guides"><path d="M0.000000 171.407529 h706.000000" class="guide line" /><text x="-5" y="174.9075286415712" class="">88</text><title>88</title></g><g class="guides"><path d="M0.000000 151.767594 h706.000000" class="guide line" /><text x="-5" y="155.26759410801964" class="">96</text><title>96</title></g><g class="guides"><path d="M0.000000 132.127660 h706.000000" class="guide line" /><text x="-5" y="135.62765957446808" class="">104</text><title>104</title></g><g class="guides"><path d="M0.000000 112.487725 h706.000000" class="guide line" /><text x="-5" y="115.98772504091653" class="">112</text><title>112</title></g><g class="guides"><path d="M0.000000 92.847791 h706.000000" class="guide line" /><text x="-5" y="96.34779050736495" class="">120</text><title>120</title></g><g class="guides"><path d="M0.000000 73.207856 h706.000000" class="guide line" /><text x="-5" y="76.70785597381342" class="">128</text><title>128</title></g><g class="guides"><path d="M0.000000 53.567921 h706.000000" class="guide line" /><text x="-5" y="57.06792144026184" class="">136</text><title>136</title></g><g class="guides"><path d="M0.000000 33.927987 h706.000000" class="guide line" /><text x="-5" y="37.427986906710316" class="">144</text><title>144</title></g><g class="guides"><path d="M0.000000 14.288052 h706.000000" class="guide line" /><text x="-5" y="17.788052373158735" class="">152</text><title>152</title></g></g><g class="axis x"><path d="M0.000000 0.000000 v360.000000" class="line" /><g class="guides"><path d="M24.891026 0.000000 v360.000000" class="guide line" /><text x="24.89102564102564" y="375.0" class="backwards" transform="rotate(270 24.891026 375.000000)">simple_list_e</text></g><g class="guides"><path d="M47.519231 0.000000 v360.000000" class="guide line" /><text x="47.51923076923077" y="375.0" class="backwards" transform="rotate(270 47.519231 375.000000)">simple_tuple_e</text></g><g class="guides"><path d="M70.147436 0.000000 v360.000000" class="guide line" /><text x="70.1474358974359" y="375.0" class="backwards" transform="rotate(270 70.147436 375.000000)">simple_set_e</text></g><g class="guides"><path d="M92.775641 0.000000 v360.000000" class="guide line" /><text x="92.77564102564102" y="375.0" class="backwards" transform="rotate(270 92.775641 375.000000)">simple_tuple_d</text></g><g class="guides"><path d="M115.403846 0.000000 v360.000000" class="guide line" /><text x="115.40384615384615" y="375.0" class="backwards" transform="rotate(270 115.403846 375.000000)">simple_set_d</text></g><g class="guides"><path d="M138.032051 0.000000 v360.000000" class="guide line" /><text x="138.03205128205127" y="375.0" class="backwards" transform="rotate(270 138.032051 375.000000)">simple_dict_d</text></g><g class="guides"><path d="M160.660256 0.000000 v360.000000" class="guide line" /><text x="160.6602564102564" y="375.0" class="backwards" transform="rotate(270 160.660256 375.000000)">simple_dict_e</text></g><g class="guides"><path d="M183.288462 0.000000 v360.000000" class="guide line" /><text x="183.28846153846155" y="375.0" class="backwards" transform="rotate(270 183.288462 375.000000)">simple_list_d</text></g><g class="guides"><path d="M205.916667 0.000000 v360.000000" class="guide line" /><text x="205.91666666666666" y="375.0" class="backwards" transform="rotate(270 205.916667 375.000000)">complex_homog_list_e</text></g><g class="guides"><path d="M228.544872 0.000000 v360.000000" class="guide line" /><text x="228.5448717948718" y="375.0" class="backwards" transform="rotate(270 228.544872 375.000000)">complex_homog_tuple_d</text></g><g class="guides"><path d="M251.173077 0.000000 v360.000000" class="guide line" /><text x="251.17307692307688" y="375.0" class="backwards" transform="rotate(270 251.173077 375.000000)">complex_homog_set_d</text></g><g class="guides"><path d="M273.801282 0.000000 v360.000000" class="guide line" /><text x="273.8012820512821" y="375.0" class="backwards" transform="rotate(270 273.801282 375.000000)">complex_homog_tuple_e</text></g><g class="guides"><path d="M296.429487 0.000000 v360.000000" class="guide line" /><text x="296.4294871794872" y="375.0" class="backwards" transform="rotate(270 296.429487 375.000000)">complex_homog_set_e</text></g><g class="guides"><path d="M319.057692 0.000000 v360.000000" class="guide line" /><text x="319.05769230769226" y="375.0" class="backwards" transform="rotate(270 319.057692 375.000000)">complex_heterog_set_d</text></g><g class="guides"><path d="M341.685897 0.000000 v360.000000" class="guide line" /><text x="341.6858974358974" y="375.0" class="backwards" transform="rotate(270 341.685897 375.000000)">complex_homog_dict_d</text></g><g class="guides"><path d="M364.314103 0.000000 v360.000000" class="guide line" /><text x="364.3141025641026" y="375.0" class="backwards" transform="rotate(270 364.314103 375.000000)">complex_heterog_set_e</text></g><g class="guides"><path d="M386.942308 0.000000 v360.000000" class="guide line" /><text x="386.9423076923077" y="375.0" class="backwards" transform="rotate(270 386.942308 375.000000)">complex_homog_list_d</text></g><g class="guides"><path d="M409.570513 0.000000 v360.000000" class="guide line" /><text x="409.5705128205129" y="375.0" class="backwards" transform="rotate(270 409.570513 375.000000)">complex_heterog_tuple_d</text></g><g class="guides"><path d="M432.198718 0.000000 v360.000000" class="guide line" /><text x="432.19871794871796" y="375.0" class="backwards" transform="rotate(270 432.198718 375.000000)">complex_heterog_dict_d</text></g><g class="guides"><path d="M454.826923 0.000000 v360.000000" class="guide line" /><text x="454.8269230769231" y="375.0" class="backwards" transform="rotate(270 454.826923 375.000000)">complex_heterog_list_e</text></g><g class="guides"><path d="M477.455128 0.000000 v360.000000" class="guide line" /><text x="477.4551282051282" y="375.0" class="backwards" transform="rotate(270 477.455128 375.000000)">complex_heterog_tuple_e</text></g><g class="guides"><path d="M500.083333 0.000000 v360.000000" class="guide line" /><text x="500.08333333333337" y="375.0" class="backwards" transform="rotate(270 500.083333 375.000000)">complex_heterog_list_d</text></g><g class="guides"><path d="M522.711538 0.000000 v360.000000" class="guide line" /><text x="522.7115384615385" y="375.0" class="backwards" transform="rotate(270 522.711538 375.000000)">complex_homog_dict_e</text></g><g class="guides"><path d="M545.339744 0.000000 v360.000000" class="guide line" /><text x="545.3397435897435" y="375.0" class="backwards" transform="rotate(270 545.339744 375.000000)">simple_cls_d</text></g><g class="guides"><path d="M567.967949 0.000000 v360.000000" class="guide line" /><text x="567.9679487179487" y="375.0" class="backwards" transform="rotate(270 567.967949 375.000000)">complex_heterog_dict_e</text></g><g class="guides"><path d="M590.596154 0.000000 v360.000000" class="guide line" /><text x="590.5961538461538" y="375.0" class="backwards" transform="rotate(270 590.596154 375.000000)">simple_cls_e</text></g><g class="guides"><path d="M613.224359 0.000000 v360.000000" class="guide line" /><text x="613.224358974359" y="375.0" class="backwards" transform="rotate(270 613.224359 375.000000)">complex_cls_e</text></g><g class="guides"><path d="M635.852564 0.000000 v360.000000" class="guide line" /><text x="635.8525641025641" y="375.0" class="backwards" transform="rotate(270 635.852564 375.000000)">complex_cls_d</text></g><g class="guides"><path d="M658.480769 0.000000 v360.000000" class="guide line" /><text x="658.4807692307692" y="375.0" class="backwards" transform="rotate(270 658.480769 375.000000)">state_cls_d</text></g><g class="guides"><path d="M681.108974 0.000000 v360.000000" class="guide line" /><text x="681.1089743589743" y="375.0" class="backwards" transform="rotate(270 681.108974 375.000000)">state_cls_e</text></g></g><g class="series serie-0 color-0"><g class="boxes"><g class="box"><path stroke-width="3" d="M19.912821 350.747134 L29.869231 350.747134" class="reactive tooltip-trigger" /><path stroke-width="3" d="M14.934615 349.455807 L34.847436 349.455807" class="reactive tooltip-trigger" /><path stroke-width="3" d="M19.912821 348.135024 L29.869231 348.135024" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 350.747134 L24.891026 349.770051" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 348.135024 L24.891026 349.117019" class="reactive tooltip-trigger" /><rect x="14.934615384615384" y="349.117019143079" height="0.6530320812199761" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="351.0932901001089" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="320.4918180879605" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 14.8080 | |
348 | Q1-1.5IQR: 14.9490 | |
349 | Q1: 15.3470 | |
350 | Median: 15.4750 | |
351 | Q3: 15.6130 | |
352 | Q3+1.5IQR: 16.0130 | |
353 | Max: 27.2730</desc><desc class="x centered">24.891025641025642</desc><desc class="y centered">349.44500704680047</desc><desc class="x_label" /></g></g></g><g class="series serie-1 color-1"><g class="boxes"><g class="box"><path stroke-width="3" d="M42.541026 349.725860 L52.497436 349.725860" class="reactive tooltip-trigger" /><path stroke-width="3" d="M37.562821 348.088385 L57.475641 348.088385" class="reactive tooltip-trigger" /><path stroke-width="3" d="M42.541026 346.360062 L52.497436 346.360062" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 349.725860 L47.519231 348.498363" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 346.360062 L47.519231 347.644031" class="reactive tooltip-trigger" /><rect x="37.562820512820515" y="347.6440306993677" height="0.854332582855875" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="349.94435268354414" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="297.78314056144734" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 15.2760 | |
354 | Q1-1.5IQR: 15.3650 | |
355 | Q1: 15.8650 | |
356 | Median: 16.0320 | |
357 | Q3: 16.2130 | |
358 | Q3+1.5IQR: 16.7360 | |
359 | Max: 36.5230</desc><desc class="x centered">47.519230769230774</desc><desc class="y centered">348.06334020694146</desc><desc class="x_label" /></g></g></g><g class="series serie-2 color-2"><g class="boxes"><g class="box"><path stroke-width="3" d="M65.169231 349.534375 L75.125641 349.534375" class="reactive tooltip-trigger" /><path stroke-width="3" d="M60.191026 348.112928 L80.103846 348.112928" class="reactive tooltip-trigger" /><path stroke-width="3" d="M65.169231 346.657114 L75.125641 346.657114" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 349.534375 L70.147436 348.456628" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 346.657114 L70.147436 347.737317" class="reactive tooltip-trigger" /><rect x="60.19102564102564" y="347.73731716902415" height="0.719310577277497" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="349.77987555331975" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="299.06464390133533" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 15.3430 | |
360 | Q1-1.5IQR: 15.4430 | |
361 | Q1: 15.8820 | |
362 | Median: 16.0220 | |
363 | Q3: 16.1750 | |
364 | Q3+1.5IQR: 16.6150 | |
365 | Max: 36.0010</desc><desc class="x centered">70.1474358974359</desc><desc class="y centered">348.099672361902</desc><desc class="x_label" /></g></g></g><g class="series serie-3 color-3"><g class="boxes"><g class="box"><path stroke-width="3" d="M87.797436 346.318327 L97.753846 346.318327" class="reactive tooltip-trigger" /><path stroke-width="3" d="M82.819231 345.380523 L102.732051 345.380523" class="reactive tooltip-trigger" /><path stroke-width="3" d="M87.797436 344.415712 L97.753846 344.415712" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 346.318327 L92.775641 345.605764" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 344.415712 L92.775641 345.130110" class="reactive tooltip-trigger" /><rect x="82.81923076923077" y="345.1301099398629" height="0.4756538207496419" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="346.68413123557934" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="268.3158694723325" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.6040 | |
366 | Q1-1.5IQR: 16.7530 | |
367 | Q1: 17.0433 | |
368 | Median: 17.1350 | |
369 | Q3: 17.2370 | |
370 | Q3+1.5IQR: 17.5280 | |
371 | Max: 48.5260</desc><desc class="x centered">92.77564102564102</desc><desc class="y centered">345.37008703861204</desc><desc class="x_label" /></g></g></g><g class="series serie-4 color-4"><g class="boxes"><g class="box"><path stroke-width="3" d="M110.425641 345.027008 L120.382051 345.027008" class="reactive tooltip-trigger" /><path stroke-width="3" d="M105.447436 344.074468 L125.360256 344.074468" class="reactive tooltip-trigger" /><path stroke-width="3" d="M110.425641 343.112112 L120.382051 343.112112" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 345.027008 L115.403846 344.310145" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 343.112112 L115.403846 343.831423" class="reactive tooltip-trigger" /><rect x="105.4474358974359" y="343.83142295539676" height="0.47872169076657656" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="345.4075311289936" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="297.24058752567026" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 17.1240 | |
372 | Q1-1.5IQR: 17.2790 | |
373 | Q1: 17.5710 | |
374 | Median: 17.6670 | |
375 | Q3: 17.7660 | |
376 | Q3+1.5IQR: 18.0590 | |
377 | Max: 36.7440</desc><desc class="x centered">115.40384615384615</desc><desc class="y centered">344.0710311952472</desc><desc class="x_label" /></g></g></g><g class="series serie-5 color-5"><g class="boxes"><g class="box"><path stroke-width="3" d="M133.053846 344.992632 L143.010256 344.992632" class="reactive tooltip-trigger" /><path stroke-width="3" d="M128.075641 343.733224 L147.988462 343.733224" class="reactive tooltip-trigger" /><path stroke-width="3" d="M133.053846 342.306866 L143.010256 342.306866" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 344.992632 L138.032051 344.037645" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 342.306866 L138.032051 343.347789" class="reactive tooltip-trigger" /><rect x="128.07564102564103" y="343.34778910011977" height="0.6898554526315479" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="345.20622169614944" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="294.44681628840425" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 17.2060 | |
378 | Q1-1.5IQR: 17.2930 | |
379 | Q1: 17.6820 | |
380 | Median: 17.8060 | |
381 | Q3: 17.9630 | |
382 | Q3+1.5IQR: 18.3870 | |
383 | Max: 37.8820</desc><desc class="x centered">138.0320512820513</desc><desc class="y centered">343.683631108333</desc><desc class="x_label" /></g></g></g><g class="series serie-6 color-6"><g class="boxes"><g class="box"><path stroke-width="3" d="M155.682051 345.044192 L165.638462 345.044192" class="reactive tooltip-trigger" /><path stroke-width="3" d="M150.703846 343.117025 L170.616667 343.117025" class="reactive tooltip-trigger" /><path stroke-width="3" d="M155.682051 340.504914 L165.638462 340.504914" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 345.044192 L160.660256 343.600654" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 340.504914 L160.660256 342.363338" class="reactive tooltip-trigger" /><rect x="150.70384615384614" y="342.36333774498763" height="1.2373161873149456" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="345.044191716972" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="286.56382826937335" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 17.2720 | |
384 | Q1-1.5IQR: 17.2720 | |
385 | Q1: 17.8600 | |
386 | Median: 18.0570 | |
387 | Q3: 18.3640 | |
388 | Q3+1.5IQR: 19.1210 | |
389 | Max: 41.0930</desc><desc class="x centered">160.6602564102564</desc><desc class="y centered">342.92602440341165</desc><desc class="x_label" /></g></g></g><g class="series serie-7 color-7"><g class="boxes"><g class="box"><path stroke-width="3" d="M178.310256 340.900156 L188.266667 340.900156" class="reactive tooltip-trigger" /><path stroke-width="3" d="M173.332051 339.584285 L193.244872 339.584285" class="reactive tooltip-trigger" /><path stroke-width="3" d="M178.310256 338.202127 L188.266667 338.202127" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 340.900156 L183.288462 339.891161" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 338.202127 L183.288462 339.216034" class="reactive tooltip-trigger" /><rect x="173.33205128205125" y="339.21603356230446" height="0.6751278903085449" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="341.1505689834124" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="286.01636306908586" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 18.8580 | |
390 | Q1-1.5IQR: 18.9600 | |
391 | Q1: 19.3710 | |
392 | Median: 19.4960 | |
393 | Q3: 19.6460 | |
394 | Q3+1.5IQR: 20.0590 | |
395 | Max: 41.3160</desc><desc class="x centered">183.28846153846152</desc><desc class="y centered">339.55875260083224</desc><desc class="x_label" /></g></g></g><g class="series serie-8 color-8"><g class="boxes"><g class="box"><path stroke-width="3" d="M200.938462 302.717678 L210.894872 302.717678" class="reactive tooltip-trigger" /><path stroke-width="3" d="M195.960256 298.225039 L215.873077 298.225039" class="reactive tooltip-trigger" /><path stroke-width="3" d="M200.938462 293.526187 L210.894872 293.526187" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 302.717678 L205.916667 299.415712" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 293.526187 L205.916667 297.071198" class="reactive tooltip-trigger" /><rect x="195.9602564102564" y="297.07119823093547" height="2.3445136023536293" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="303.058921351317" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="208.63257052338759" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 34.3740 | |
396 | Q1-1.5IQR: 34.5130 | |
397 | Q1: 35.8580 | |
398 | Median: 36.3430 | |
399 | Q3: 36.8130 | |
400 | Q3+1.5IQR: 38.2570 | |
401 | Max: 72.8370</desc><desc class="x centered">205.91666666666666</desc><desc class="y centered">298.1911628080971</desc><desc class="x_label" /></g></g></g><g class="series serie-9 color-9"><g class="boxes"><g class="box"><path stroke-width="3" d="M223.566667 299.835514 L233.523077 299.835514" class="reactive tooltip-trigger" /><path stroke-width="3" d="M218.588462 297.463993 L238.501282 297.463993" class="reactive tooltip-trigger" /><path stroke-width="3" d="M223.566667 294.807691 L233.523077 294.807691" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 299.835514 L228.544872 297.974635" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 294.807691 L228.544872 296.707859" class="reactive tooltip-trigger" /><rect x="218.58846153846153" y="296.70785881891396" height="1.2667757775649875" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="300.0687349833008" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="204.50572715008266" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 35.5920 | |
402 | Q1-1.5IQR: 35.6870 | |
403 | Q1: 36.4450 | |
404 | Median: 36.6530 | |
405 | Q3: 36.9610 | |
406 | Q3+1.5IQR: 37.7350 | |
407 | Max: 74.5180</desc><desc class="x centered">228.5448717948718</desc><desc class="y centered">297.35793824270274</desc><desc class="x_label" /></g></g></g><g class="series serie-10 color-10"><g class="boxes"><g class="box"><path stroke-width="3" d="M246.194872 298.566291 L256.151282 298.566291" class="reactive tooltip-trigger" /><path stroke-width="3" d="M241.216667 296.091659 L261.129487 296.091659" class="reactive tooltip-trigger" /><path stroke-width="3" d="M246.194872 293.364157 L256.151282 293.364157" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 298.566291 L251.173077 296.653843" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 293.364157 L251.173077 295.337972" class="reactive tooltip-trigger" /><rect x="241.21666666666664" y="295.3379722426717" height="1.3158706290442979" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="298.8387825771474" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="203.32487852661677" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 36.0930 | |
408 | Q1-1.5IQR: 36.2040 | |
409 | Q1: 36.9830 | |
410 | Median: 37.2120 | |
411 | Q3: 37.5190 | |
412 | Q3+1.5IQR: 38.3230 | |
413 | Max: 74.9990</desc><desc class="x centered">251.1730769230769</desc><desc class="y centered">296.0027845875084</desc><desc class="x_label" /></g></g></g><g class="series serie-11 color-11"><g class="boxes"><g class="box"><path stroke-width="3" d="M268.823077 297.525377 L278.779487 297.525377" class="reactive tooltip-trigger" /><path stroke-width="3" d="M263.844872 294.362113 L283.757692 294.362113" class="reactive tooltip-trigger" /><path stroke-width="3" d="M268.823077 290.884613 L278.779487 290.884613" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 297.525377 L273.801282 295.140342" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 290.884613 L273.801282 293.445172" class="reactive tooltip-trigger" /><rect x="263.84487179487184" y="293.4451723574857" height="1.6951701101205572" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="297.5253769615665" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="218.19722466573953" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 36.6280 | |
414 | Q1-1.5IQR: 36.6280 | |
415 | Q1: 37.5995 | |
416 | Median: 37.9165 | |
417 | Q3: 38.2900 | |
418 | Q3+1.5IQR: 39.3330 | |
419 | Max: 68.9410</desc><desc class="x centered">273.8012820512821</desc><desc class="y centered">294.2715234650488</desc><desc class="x_label" /></g></g></g><g class="series serie-12 color-12"><g class="boxes"><g class="box"><path stroke-width="3" d="M291.451282 296.371527 L301.407692 296.371527" class="reactive tooltip-trigger" /><path stroke-width="3" d="M286.473077 292.404258 L306.385897 292.404258" class="reactive tooltip-trigger" /><path stroke-width="3" d="M291.451282 288.216039 L301.407692 288.216039" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 296.371527 L296.429487 293.373973" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 288.216039 L296.429487 291.311784" class="reactive tooltip-trigger" /><rect x="286.473076923077" y="291.3117835857889" height="2.062189179920722" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="296.7888738085027" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="205.4901785052148" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 36.9280 | |
420 | Q1-1.5IQR: 37.0980 | |
421 | Q1: 38.3190 | |
422 | Median: 38.7140 | |
423 | Q3: 39.1590 | |
424 | Q3+1.5IQR: 40.4200 | |
425 | Max: 74.1170</desc><desc class="x centered">296.42948717948724</desc><desc class="y centered">292.33551618082936</desc><desc class="x_label" /></g></g></g><g class="series serie-13 color-13"><g class="boxes"><g class="box"><path stroke-width="3" d="M314.079487 289.276593 L324.035897 289.276593" class="reactive tooltip-trigger" /><path stroke-width="3" d="M309.101282 287.275780 L329.014103 287.275780" class="reactive tooltip-trigger" /><path stroke-width="3" d="M314.079487 285.159574 L324.035897 285.159574" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 289.276593 L319.057692 287.744686" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 285.159574 L319.057692 286.711131" class="reactive tooltip-trigger" /><rect x="309.1012820512821" y="286.71113068622776" height="1.0335551378196897" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="289.5147351837228" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="215.9484446840894" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 39.8910 | |
426 | Q1-1.5IQR: 39.9880 | |
427 | Q1: 40.6120 | |
428 | Median: 40.8030 | |
429 | Q3: 41.0330 | |
430 | Q3+1.5IQR: 41.6650 | |
431 | Max: 69.8570</desc><desc class="x centered">319.0576923076924</desc><desc class="y centered">287.2335527787204</desc><desc class="x_label" /></g></g></g><g class="series serie-14 color-14"><g class="boxes"><g class="box"><path stroke-width="3" d="M336.707692 288.095745 L346.664103 288.095745" class="reactive tooltip-trigger" /><path stroke-width="3" d="M331.729487 284.481990 L351.642308 284.481990" class="reactive tooltip-trigger" /><path stroke-width="3" d="M336.707692 280.716039 L346.664103 280.716039" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 288.095745 L341.685897 285.385436" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 280.716039 L341.685897 283.519635" class="reactive tooltip-trigger" /><rect x="331.7294871794872" y="283.51963488536745" height="1.8658008427951813" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="288.2995103398923" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="185.33469226066507" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 40.3860 | |
432 | Q1-1.5IQR: 40.4690 | |
433 | Q1: 41.5730 | |
434 | Median: 41.9410 | |
435 | Q3: 42.3330 | |
436 | Q3+1.5IQR: 43.4750 | |
437 | Max: 82.3270</desc><desc class="x centered">341.68589743589746</desc><desc class="y centered">284.43976903776297</desc><desc class="x_label" /></g></g></g><g class="series serie-15 color-15"><g class="boxes"><g class="box"><path stroke-width="3" d="M359.335897 286.917343 L369.292308 286.917343" class="reactive tooltip-trigger" /><path stroke-width="3" d="M354.357692 282.829788 L374.270513 282.829788" class="reactive tooltip-trigger" /><path stroke-width="3" d="M359.335897 278.575291 L369.292308 278.575291" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 286.917343 L364.314103 283.804415" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 278.575291 L364.314103 281.717063" class="reactive tooltip-trigger" /><rect x="354.35769230769233" y="281.7170625310292" height="2.0873528590262254" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="287.02536631556177" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="225.50573057967577" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 40.9050 | |
438 | Q1-1.5IQR: 40.9490 | |
439 | Q1: 42.2170 | |
440 | Median: 42.6140 | |
441 | Q3: 43.0672 | |
442 | Q3+1.5IQR: 44.3470 | |
443 | Max: 65.9640</desc><desc class="x centered">364.3141025641026</desc><desc class="y centered">282.76878017384587</desc><desc class="x_label" /></g></g></g><g class="series serie-16 color-16"><g class="boxes"><g class="box"><path stroke-width="3" d="M381.964103 279.915714 L391.920513 279.915714" class="reactive tooltip-trigger" /><path stroke-width="3" d="M376.985897 276.036828 L396.898718 276.036828" class="reactive tooltip-trigger" /><path stroke-width="3" d="M381.964103 272.010639 L391.920513 272.010639" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 279.915714 L386.942308 276.957448" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 272.010639 L386.942308 274.981177" class="reactive tooltip-trigger" /><rect x="376.98589743589747" y="274.9811765652778" height="1.9762709570298398" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="280.13911899414717" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="136.93207193534127" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 43.7100 | |
444 | Q1-1.5IQR: 43.8010 | |
445 | Q1: 45.0060 | |
446 | Median: 45.3810 | |
447 | Q3: 45.8110 | |
448 | Q3+1.5IQR: 47.0210 | |
449 | Max: 102.0430</desc><desc class="x centered">386.94230769230774</desc><desc class="y centered">275.9803608414578</desc><desc class="x_label" /></g></g></g><g class="series serie-17 color-17"><g class="boxes"><g class="box"><path stroke-width="3" d="M404.592308 276.336336 L414.548718 276.336336" class="reactive tooltip-trigger" /><path stroke-width="3" d="M399.614103 271.914887 L419.526923 271.914887" class="reactive tooltip-trigger" /><path stroke-width="3" d="M404.592308 267.402627 L414.548718 267.402627" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 276.336336 L409.570513 272.990183" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 267.402627 L409.570513 270.756139" class="reactive tooltip-trigger" /><rect x="399.6141025641026" y="270.75613902341007" height="2.234043488118971" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="276.88133576602115" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="144.6211098370854" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 45.0370 | |
450 | Q1-1.5IQR: 45.2590 | |
451 | Q1: 46.6220 | |
452 | Median: 47.0600 | |
453 | Q3: 47.5320 | |
454 | Q3+1.5IQR: 48.8980 | |
455 | Max: 98.9110</desc><desc class="x centered">409.5705128205129</desc><desc class="y centered">271.88003422530085</desc><desc class="x_label" /></g></g></g><g class="series serie-18 color-18"><g class="boxes"><g class="box"><path stroke-width="3" d="M427.220513 272.756957 L437.176923 272.756957" class="reactive tooltip-trigger" /><path stroke-width="3" d="M422.242308 267.810149 L442.155128 267.810149" class="reactive tooltip-trigger" /><path stroke-width="3" d="M427.220513 262.630111 L437.176923 262.630111" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 272.756957 L432.198718 269.030277" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 262.630111 L432.198718 266.472173" class="reactive tooltip-trigger" /><rect x="422.24230769230775" y="266.4721733698341" height="2.5581034464737513" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="273.0196331705709" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="173.61947463324626" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 46.6100 | |
456 | Q1-1.5IQR: 46.7170 | |
457 | Q1: 48.2350 | |
458 | Median: 48.7320 | |
459 | Q3: 49.2770 | |
460 | Q3+1.5IQR: 50.8420 | |
461 | Max: 87.0990</desc><desc class="x centered">432.198717948718</desc><desc class="y centered">267.7399333665428</desc><desc class="x_label" /></g></g></g><g class="series serie-19 color-19"><g class="boxes"><g class="box"><path stroke-width="3" d="M449.848718 269.450079 L459.805128 269.450079" class="reactive tooltip-trigger" /><path stroke-width="3" d="M444.870513 264.294593 L464.783333 264.294593" class="reactive tooltip-trigger" /><path stroke-width="3" d="M449.848718 258.918166 L459.805128 258.918166" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 269.450079 L454.826923 265.578561" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 258.918166 L454.826923 262.919803" class="reactive tooltip-trigger" /><rect x="444.87051282051283" y="262.91980317041566" height="2.658758162895765" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="271.55401297362516" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="177.260228069019" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 47.2070 | |
462 | Q1-1.5IQR: 48.0640 | |
463 | Q1: 49.6410 | |
464 | Median: 50.1640 | |
465 | Q3: 50.7240 | |
466 | Q3+1.5IQR: 52.3540 | |
467 | Max: 85.6160</desc><desc class="x centered">454.8269230769231</desc><desc class="y centered">264.2322406430276</desc><desc class="x_label" /></g></g></g><g class="series serie-20 color-20"><g class="boxes"><g class="box"><path stroke-width="3" d="M472.476923 268.075290 L482.433333 268.075290" class="reactive tooltip-trigger" /><path stroke-width="3" d="M467.498718 263.285599 L487.411538 263.285599" class="reactive tooltip-trigger" /><path stroke-width="3" d="M472.476923 258.382973 L482.433333 258.382973" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 268.075290 L477.455128 264.451720" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 258.382973 L477.455128 262.026182" class="reactive tooltip-trigger" /><rect x="467.49871794871797" y="262.02618220268477" height="2.4255375231504672" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="269.4132559551627" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="178.24713550640632" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 48.0790 | |
468 | Q1-1.5IQR: 48.6240 | |
469 | Q1: 50.1000 | |
470 | Median: 50.5750 | |
471 | Q3: 51.0880 | |
472 | Q3+1.5IQR: 52.5720 | |
473 | Max: 85.2140</desc><desc class="x centered">477.45512820512823</desc><desc class="y centered">263.2443525589798</desc><desc class="x_label" /></g></g></g><g class="series serie-21 color-21"><g class="boxes"><g class="box"><path stroke-width="3" d="M495.105128 267.591656 L505.061538 267.591656" class="reactive tooltip-trigger" /><path stroke-width="3" d="M490.126923 263.094105 L510.039744 263.094105" class="reactive tooltip-trigger" /><path stroke-width="3" d="M495.105128 258.486083 L505.061538 258.486083" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 267.591656 L500.083333 264.191491" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 258.486083 L500.083333 261.913877" class="reactive tooltip-trigger" /><rect x="490.1269230769231" y="261.91387672516487" height="2.277614387326139" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="268.4091648731972" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="137.7545022425042" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 48.4880 | |
474 | Q1-1.5IQR: 48.8210 | |
475 | Q1: 50.2060 | |
476 | Median: 50.6530 | |
477 | Q3: 51.1337 | |
478 | Q3+1.5IQR: 52.5300 | |
479 | Max: 101.7080</desc><desc class="x centered">500.08333333333337</desc><desc class="y centered">263.05544232248076</desc><desc class="x_label" /></g></g></g><g class="series serie-22 color-22"><g class="boxes"><g class="box"><path stroke-width="3" d="M517.733333 262.225036 L527.689744 262.225036" class="reactive tooltip-trigger" /><path stroke-width="3" d="M512.755128 256.227497 L532.667949 256.227497" class="reactive tooltip-trigger" /><path stroke-width="3" d="M517.733333 250.188223 L527.689744 250.188223" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 262.225036 L522.711538 257.764324" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 250.188223 L522.711538 254.734860" class="reactive tooltip-trigger" /><rect x="512.7551282051282" y="254.73485993332673" height="3.0294635888808443" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="264.1522116588243" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="172.5687358508484" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 50.2220 | |
480 | Q1-1.5IQR: 51.0070 | |
481 | Q1: 52.8240 | |
482 | Median: 53.4500 | |
483 | Q3: 54.0580 | |
484 | Q3+1.5IQR: 55.9100 | |
485 | Max: 87.5270</desc><desc class="x centered">522.7115384615385</desc><desc class="y centered">256.2279878049702</desc><desc class="x_label" /></g></g></g><g class="series serie-23 color-23"><g class="boxes"><g class="box"><path stroke-width="3" d="M540.361538 255.505730 L550.317949 255.505730" class="reactive tooltip-trigger" /><path stroke-width="3" d="M535.383333 249.724220 L555.296154 249.724220" class="reactive tooltip-trigger" /><path stroke-width="3" d="M540.361538 243.606378 L550.317949 243.606378" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 255.505730 L545.339744 251.190470" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 243.606378 L545.339744 248.166526" class="reactive tooltip-trigger" /><rect x="535.3833333333333" y="248.16652566622278" height="3.0239441022128233" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="257.06218989110215" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="84.9328987236301" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 53.1100 | |
486 | Q1-1.5IQR: 53.7440 | |
487 | Q1: 55.5017 | |
488 | Median: 56.0990 | |
489 | Q3: 56.7335 | |
490 | Q3+1.5IQR: 58.5910 | |
491 | Max: 123.2240</desc><desc class="x centered">545.3397435897435</desc><desc class="y centered">249.6386647520342</desc><desc class="x_label" /></g></g></g><g class="series serie-24 color-24"><g class="boxes"><g class="box"><path stroke-width="3" d="M562.989744 253.414077 L572.946154 253.414077" class="reactive tooltip-trigger" /><path stroke-width="3" d="M558.011538 247.477905 L577.924359 247.477905" class="reactive tooltip-trigger" /><path stroke-width="3" d="M562.989744 241.497541 L572.946154 241.497541" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 253.414077 L567.967949 248.955806" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 241.497541 L567.967949 245.977909" class="reactive tooltip-trigger" /><rect x="558.0115384615385" y="245.97790853581472" height="2.977897025532002" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="254.99754462892616" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="157.17348533399013" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 53.9510 | |
492 | Q1-1.5IQR: 54.5960 | |
493 | Q1: 56.4120 | |
494 | Median: 57.0140 | |
495 | Q3: 57.6250 | |
496 | Q3+1.5IQR: 59.4500 | |
497 | Max: 93.7980</desc><desc class="x centered">567.9679487179487</desc><desc class="y centered">247.46464746767185</desc><desc class="x_label" /></g></g></g><g class="series serie-25 color-25"><g class="boxes"><g class="box"><path stroke-width="3" d="M585.617949 244.288865 L595.574359 244.288865" class="reactive tooltip-trigger" /><path stroke-width="3" d="M580.639744 238.318326 L600.552564 238.318326" class="reactive tooltip-trigger" /><path stroke-width="3" d="M585.617949 231.837153 L595.574359 231.837153" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 244.288865 L590.596154 239.709085" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 231.837153 L590.596154 236.563013" class="reactive tooltip-trigger" /><rect x="580.6397435897436" y="236.5630128925724" height="3.146071675951447" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="244.72340423831753" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="167.2659649497962" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 58.1360 | |
498 | Q1-1.5IQR: 58.3130 | |
499 | Q1: 60.1785 | |
500 | Median: 60.7450 | |
501 | Q3: 61.4600 | |
502 | Q3+1.5IQR: 63.3850 | |
503 | Max: 89.6870</desc><desc class="x centered">590.5961538461538</desc><desc class="y centered">238.14328836791563</desc><desc class="x_label" /></g></g></g><g class="series serie-26 color-26"><g class="boxes"><g class="box"><path stroke-width="3" d="M608.246154 44.926355 L618.202564 44.926355" class="reactive tooltip-trigger" /><path stroke-width="3" d="M603.267949 37.608025 L623.180769 37.608025" class="reactive tooltip-trigger" /><path stroke-width="3" d="M608.246154 29.963179 L618.202564 29.963179" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 44.926355 L613.224359 39.400170" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 29.963179 L613.224359 35.629289" class="reactive tooltip-trigger" /><rect x="603.2679487179488" y="35.62928918380982" height="3.770881139257199" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="47.499177474848636" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="-121.4042506026068" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 138.4720 | |
504 | Q1-1.5IQR: 139.5200 | |
505 | Q1: 141.7710 | |
506 | Median: 142.5010 | |
507 | Q3: 143.3070 | |
508 | Q3+1.5IQR: 145.6150 | |
509 | Max: 207.2720</desc><desc class="x centered">613.224358974359</desc><desc class="y centered">37.505403785835256</desc><desc class="x_label" /></g></g></g><g class="series serie-27 color-27"><g class="boxes"><g class="box"><path stroke-width="3" d="M630.874359 43.858424 L640.830769 43.858424" class="reactive tooltip-trigger" /><path stroke-width="3" d="M625.896154 36.694764 L645.808974 36.694764" class="reactive tooltip-trigger" /><path stroke-width="3" d="M630.874359 29.305235 L640.830769 29.305235" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 43.858424 L635.852564 38.455604" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 29.305235 L635.852564 34.816699" class="reactive tooltip-trigger" /><rect x="625.8961538461539" y="34.81669883528201" height="3.638904675675235" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="46.38461627864848" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="-101.24631720701001" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 138.9260 | |
510 | Q1-1.5IQR: 139.9550 | |
511 | Q1: 142.1558 | |
512 | Median: 142.8730 | |
513 | Q3: 143.6380 | |
514 | Q3+1.5IQR: 145.8830 | |
515 | Max: 199.0610</desc><desc class="x centered">635.8525641025641</desc><desc class="y centered">36.626145094011974</desc><desc class="x_label" /></g></g></g><g class="series serie-28 color-28"><g class="boxes"><g class="box"><path stroke-width="3" d="M653.502564 29.140757 L663.458974 29.140757" class="reactive tooltip-trigger" /><path stroke-width="3" d="M648.524359 21.678804 L668.437179 21.678804" class="reactive tooltip-trigger" /><path stroke-width="3" d="M653.502564 13.990999 L663.458974 13.990999" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 29.140757 L658.480769 23.540917" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 13.990999 L658.480769 19.746725" class="reactive tooltip-trigger" /><rect x="648.524358974359" y="19.74672515389591" height="3.7941915926610363" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="30.098200876314536" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="-238.5662869306483" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 145.5600 | |
516 | Q1-1.5IQR: 145.9500 | |
517 | Q1: 148.2310 | |
518 | Median: 148.9895 | |
519 | Q3: 149.7765 | |
520 | Q3+1.5IQR: 152.1210 | |
521 | Max: 254.9960</desc><desc class="x centered">658.4807692307692</desc><desc class="y centered">21.619640597143814</desc><desc class="x_label" /></g></g></g><g class="series serie-29 color-29"><g class="boxes"><g class="box"><path stroke-width="3" d="M676.130769 22.576105 L686.087179 22.576105" class="reactive tooltip-trigger" /><path stroke-width="3" d="M671.152564 15.171848 L691.065385 15.171848" class="reactive tooltip-trigger" /><path stroke-width="3" d="M676.130769 7.274141 L686.087179 7.274141" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 22.576105 L681.108974 17.029052" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 7.274141 L681.108974 13.129298" class="reactive tooltip-trigger" /><rect x="671.1525641025642" y="13.129298268114667" height="3.8997540079894293" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="23.160393689957232" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="-92.4279905467427" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 148.3860 | |
522 | Q1-1.5IQR: 148.6240 | |
523 | Q1: 150.8835 | |
524 | Median: 151.6400 | |
525 | Q3: 152.4720 | |
526 | Q3+1.5IQR: 154.8570 | |
527 | Max: 195.4690</desc><desc class="x centered">681.1089743589744</desc><desc class="y centered">15.036088890947042</desc><desc class="x_label" /></g></g></g></g><g class="titles"><text x="400.0" y="26" class="title plot_title">Speed in Microseconds (us)</text><text x="427.0" y="580.0" class="title">Trial</text><text x="0" y="252.0" class="title" transform="rotate(-90 0.000000 226.000000)">Duration</text></g><g transform="translate(74, 46)" class="plot overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot text-overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot tooltip-overlay"><g transform="translate(0 0)" style="opacity: 0" class="tooltip"><rect rx="0" ry="0" width="0" height="0" class="tooltip-box" /><g class="text" /></g></g></g></svg>⏎ |
0 | <?xml version='1.0' encoding='utf-8'?> | |
1 | <svg xmlns="http://www.w3.org/2000/svg" id="chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7" class="pygal-chart" viewBox="0 0 800 600"><!--Generated with pygal 3.0.0 (etree) ©Kozea 2012-2016 on 2022-06-20--><!--http://pygal.org--><!--http://github.com/Kozea/pygal--><defs><style type="text/css">#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .title{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .legends .legend text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis text.major{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay text.value{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay text.label{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 text.no_data{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:64px} | |
2 | #chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7{background-color:rgba(249,249,249,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 path,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 line,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 rect,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .graph > .background{fill:rgba(249,249,249,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .plot > .background{fill:rgba(255,255,255,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .graph{fill:rgba(0,0,0,.87)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 text.no_data{fill:rgba(0,0,0,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .title{fill:rgba(0,0,0,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .legends .legend text{fill:rgba(0,0,0,.87)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis .line{stroke:rgba(0,0,0,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis text.major{fill:rgba(0,0,0,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.y .guides:hover .guide.line,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .line-graph .axis.x .guides:hover .guide.line,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .stackedline-graph .axis.x .guides:hover .guide.line,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .reactive{fill-opacity:.7;stroke-opacity:.8;stroke-width:1}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .ci{stroke:rgba(0,0,0,.87)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .reactive.active,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .ci .reactive.active{stroke-width:1.5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .series text{fill:rgba(0,0,0,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip .value{font-size:1.5em}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .bound{font-size:.5em}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-0,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-0 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-1,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-1 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-2,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-2 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-3,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-3 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-4,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-4 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-5,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-5 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-6,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-6 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-7,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-7 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-8,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-8 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-9,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-9 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-10,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-10 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-11,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-11 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-12,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-12 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-13,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-13 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-14,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-14 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-15,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-15 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-16,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-16 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-17,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-17 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-18,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-18 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-19,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-19 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-20,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-20 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-21,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-21 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-22,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-22 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-23,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-23 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-24,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-24 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-25,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-25 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-26,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-26 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-27,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-27 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-28,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-28 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-29,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .color-29 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-0 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-1 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-2 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-3 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-4 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-5 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-6 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-7 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-8 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-9 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-10 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-11 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-12 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-13 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-14 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-15 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-16 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-17 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-18 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-19 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-20 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-21 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-22 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-23 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-24 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-25 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-26 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-27 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-28 text{fill:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .text-overlay .color-29 text{fill:black} | |
3 | #chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 text.no_data{text-anchor:middle}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .guide.line{fill:none}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .centered{text-anchor:middle}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .title{text-anchor:middle}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .legends .legend text{fill-opacity:1}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.x text{text-anchor:middle}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.x:not(.web) text[transform]{text-anchor:start}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.y text{text-anchor:end}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.y text[transform].backwards{text-anchor:start}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.y2 text{text-anchor:start}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.y2 text[transform].backwards{text-anchor:end}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis .guide.line{stroke-dasharray:4,4;stroke:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis .major.guide.line{stroke-dasharray:6,6;stroke:black}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .horizontal .axis.y .guide.line,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .horizontal .axis.y2 .guide.line,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .vertical .axis.x .guide.line{opacity:0}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .horizontal .axis.always_show .guide.line,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.y .guides:hover .guide.line,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.y2 .guides:hover .guide.line,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis.x .guides:hover .guide.line{opacity:1}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .axis .guides:hover text{opacity:1}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .nofill{fill:none}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .subtle-fill{fill-opacity:.2}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .dot{stroke-width:1px;fill-opacity:1;stroke-opacity:1}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .dot.active{stroke-width:5px}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .dot.negative{fill:transparent}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 text,#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 tspan{stroke:none !important}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .series text.active{opacity:1}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .tooltip text{fill-opacity:1}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .showable{visibility:hidden}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .showable.shown{visibility:visible}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-8f9f7849-cd2f-4204-bbbe-15c3a18b94d7 .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px} | |
4 | .tooltip .value{font-size:1em !important}.axis text{font-size:9px !important}</style><script type="text/javascript">window.pygal = window.pygal || {};window.pygal.config = window.pygal.config || {};window.pygal.config['8f9f7849-cd2f-4204-bbbe-15c3a18b94d7'] = {"allow_interruptions": false, "box_mode": "tukey", "classes": ["pygal-chart"], "css": ["file://style.css", "file://graph.css", "inline:\n .tooltip .value {\n font-size: 1em !important;\n }\n .axis text {\n font-size: 9px !important;\n }\n "], "defs": [], "disable_xml_declaration": false, "dots_size": 2.5, "dynamic_print_values": false, "explicit_size": false, "fill": false, "force_uri_protocol": "https", "formatter": null, "half_pie": false, "height": 600, "include_x_axis": false, "inner_radius": 0, "interpolate": null, "interpolation_parameters": {}, "interpolation_precision": 250, "inverse_y_axis": false, "js": ["file:///home/theel/.pyenv/versions/3.9.13/lib/python3.9/site-packages/pygaljs/static/2.0.x/pygal-tooltips.js"], "legend_at_bottom": false, "legend_at_bottom_columns": null, "legend_box_size": 12, "logarithmic": false, "margin": 20, "margin_bottom": null, "margin_left": null, "margin_right": null, "margin_top": null, "max_scale": 20, "min_scale": 20, "missing_value_fill_truncation": "x", "no_data_text": "No data", "no_prefix": false, "order_min": null, "pretty_print": false, "print_labels": false, "print_values": false, "print_values_position": "center", "print_zeroes": true, "range": [15, 269], "rounded_bars": null, "secondary_range": null, "show_dots": true, "show_legend": false, "show_minor_x_labels": true, "show_minor_y_labels": true, "show_only_major_dots": false, "show_x_guides": false, "show_x_labels": true, "show_y_guides": true, "show_y_labels": true, "spacing": 10, "stack_from_top": false, "strict": false, "stroke": true, "stroke_style": null, "style": {"background": "rgba(249, 249, 249, 1)", "ci_colors": [], "colors": ["#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5"], "dot_opacity": "1", "font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "foreground": "rgba(0, 0, 0, .87)", "foreground_strong": "rgba(0, 0, 0, 1)", "foreground_subtle": "rgba(0, 0, 0, .54)", "guide_stroke_color": "black", "guide_stroke_dasharray": "4,4", "label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "label_font_size": 10, "legend_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "legend_font_size": 14, "major_guide_stroke_color": "black", "major_guide_stroke_dasharray": "6,6", "major_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "major_label_font_size": 10, "no_data_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "no_data_font_size": 64, "opacity": ".7", "opacity_hover": ".8", "plot_background": "rgba(255, 255, 255, 1)", "stroke_opacity": ".8", "stroke_opacity_hover": ".9", "stroke_width": "1", "stroke_width_hover": "4", "title_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "title_font_size": 16, "tooltip_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "tooltip_font_size": 14, "transition": "150ms", "value_background": "rgba(229, 229, 229, 1)", "value_colors": [], "value_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_font_size": 16, "value_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_label_font_size": 10}, "title": "Speed in Microseconds (us)", "tooltip_border_radius": 0, "tooltip_fancy_mode": true, "truncate_label": 50, "truncate_legend": null, "width": 800, "x_label_rotation": 270, "x_labels": ["simple_list_e", "simple_dict_d", "simple_tuple_e", "simple_set_e", "simple_tuple_d", "simple_dict_e", "simple_set_d", "simple_list_d", "complex_homog_dict_d", "complex_homog_tuple_d", "complex_homog_set_d", "complex_homog_list_e", "complex_heterog_set_d", "complex_homog_tuple_e", "complex_homog_set_e", "complex_heterog_dict_d", "complex_homog_list_d", "complex_heterog_tuple_d", "complex_heterog_set_e", "complex_heterog_list_d", "complex_homog_dict_e", "simple_cls_d", "complex_heterog_list_e", "complex_heterog_tuple_e", "complex_heterog_dict_e", "simple_cls_e", "complex_cls_d", "state_cls_d", "complex_cls_e", "state_cls_e"], "x_labels_major": null, "x_labels_major_count": null, "x_labels_major_every": null, "x_title": "Trial", "xrange": null, "y_label_rotation": 0, "y_labels": null, "y_labels_major": null, "y_labels_major_count": null, "y_labels_major_every": null, "y_title": "Duration", "zero": 15, "legends": ["jsonpickle_benchmarks.py::simple_list_e - 14108 rounds", "jsonpickle_benchmarks.py::simple_dict_d - 14121 rounds", "jsonpickle_benchmarks.py::simple_tuple_e - 15463 rounds", "jsonpickle_benchmarks.py::simple_set_e - 15102 rounds", "jsonpickle_benchmarks.py::simple_tuple_d - 15101 rounds", "jsonpickle_benchmarks.py::simple_dict_e - 7215 rounds", "jsonpickle_benchmarks.py::simple_set_d - 14699 rounds", "jsonpickle_benchmarks.py::simple_list_d - 12255 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_d - 10336 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_d - 12163 rounds", "jsonpickle_benchmarks.py::complex_homog_set_d - 11444 rounds", "jsonpickle_benchmarks.py::complex_homog_list_e - 718 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_d - 9036 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_e - 8484 rounds", "jsonpickle_benchmarks.py::complex_homog_set_e - 9909 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_d - 9757 rounds", "jsonpickle_benchmarks.py::complex_homog_list_d - 10957 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_d - 9166 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_e - 8286 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_d - 9015 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_e - 8195 rounds", "jsonpickle_benchmarks.py::simple_cls_d - 7972 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_e - 6428 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_e - 6701 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_e - 7204 rounds", "jsonpickle_benchmarks.py::simple_cls_e - 5783 rounds", "jsonpickle_benchmarks.py::complex_cls_d - 3008 rounds", "jsonpickle_benchmarks.py::state_cls_d - 3015 rounds", "jsonpickle_benchmarks.py::complex_cls_e - 2652 rounds", "jsonpickle_benchmarks.py::state_cls_e - 2718 rounds"]}</script><script type="text/javascript">(function() { | |
5 | var $, get_translation, init, init_svg, matches, padding, r_translation, sibl, svg_ns, tooltip_timeout, xlink_ns; | |
6 | ||
7 | svg_ns = 'http://www.w3.org/2000/svg'; | |
8 | ||
9 | xlink_ns = 'http://www.w3.org/1999/xlink'; | |
10 | ||
11 | $ = function(sel, ctx) { | |
12 | if (ctx == null) { | |
13 | ctx = null; | |
14 | } | |
15 | ctx = ctx || document; | |
16 | return Array.prototype.slice.call(ctx.querySelectorAll(sel), 0).filter(function(e) { | |
17 | return e !== ctx; | |
18 | }); | |
19 | }; | |
20 | ||
21 | matches = function(el, selector) { | |
22 | return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector); | |
23 | }; | |
24 | ||
25 | sibl = function(el, match) { | |
26 | if (match == null) { | |
27 | match = null; | |
28 | } | |
29 | return Array.prototype.filter.call(el.parentElement.children, function(child) { | |
30 | return child !== el && (!match || matches(child, match)); | |
31 | }); | |
32 | }; | |
33 | ||
34 | Array.prototype.one = function() { | |
35 | return this.length > 0 && this[0] || {}; | |
36 | }; | |
37 | ||
38 | padding = 5; | |
39 | ||
40 | tooltip_timeout = null; | |
41 | ||
42 | r_translation = /translate\((\d+)[ ,]+(\d+)\)/; | |
43 | ||
44 | get_translation = function(el) { | |
45 | return (r_translation.exec(el.getAttribute('transform')) || []).slice(1).map(function(x) { | |
46 | return +x; | |
47 | }); | |
48 | }; | |
49 | ||
50 | init = function(ctx) { | |
51 | var bbox, box, config, el, graph, inner_svg, num, parent, tooltip, tooltip_el, tt, uid, untooltip, xconvert, yconvert, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; | |
52 | if ($('svg', ctx).length) { | |
53 | inner_svg = $('svg', ctx).one(); | |
54 | parent = inner_svg.parentElement; | |
55 | box = inner_svg.viewBox.baseVal; | |
56 | bbox = parent.getBBox(); | |
57 | xconvert = function(x) { | |
58 | return ((x - box.x) / box.width) * bbox.width; | |
59 | }; | |
60 | yconvert = function(y) { | |
61 | return ((y - box.y) / box.height) * bbox.height; | |
62 | }; | |
63 | } else { | |
64 | xconvert = yconvert = function(x) { | |
65 | return x; | |
66 | }; | |
67 | } | |
68 | if (((_ref = window.pygal) != null ? _ref.config : void 0) != null) { | |
69 | if (window.pygal.config.no_prefix != null) { | |
70 | config = window.pygal.config; | |
71 | } else { | |
72 | uid = ctx.id.replace('chart-', ''); | |
73 | config = window.pygal.config[uid]; | |
74 | } | |
75 | } else { | |
76 | config = window.config; | |
77 | } | |
78 | tooltip_el = null; | |
79 | graph = $('.graph').one(); | |
80 | tt = $('.tooltip', ctx).one(); | |
81 | _ref1 = $('.reactive', ctx); | |
82 | for (_i = 0, _len = _ref1.length; _i < _len; _i++) { | |
83 | el = _ref1[_i]; | |
84 | el.addEventListener('mouseenter', (function(el) { | |
85 | return function() { | |
86 | return el.classList.add('active'); | |
87 | }; | |
88 | })(el)); | |
89 | el.addEventListener('mouseleave', (function(el) { | |
90 | return function() { | |
91 | return el.classList.remove('active'); | |
92 | }; | |
93 | })(el)); | |
94 | } | |
95 | _ref2 = $('.activate-serie', ctx); | |
96 | for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { | |
97 | el = _ref2[_j]; | |
98 | num = el.id.replace('activate-serie-', ''); | |
99 | el.addEventListener('mouseenter', (function(num) { | |
100 | return function() { | |
101 | var re, _k, _len2, _ref3, _results; | |
102 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
103 | _results = []; | |
104 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
105 | re = _ref3[_k]; | |
106 | _results.push(re.classList.add('active')); | |
107 | } | |
108 | return _results; | |
109 | }; | |
110 | })(num)); | |
111 | el.addEventListener('mouseleave', (function(num) { | |
112 | return function() { | |
113 | var re, _k, _len2, _ref3, _results; | |
114 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
115 | _results = []; | |
116 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
117 | re = _ref3[_k]; | |
118 | _results.push(re.classList.remove('active')); | |
119 | } | |
120 | return _results; | |
121 | }; | |
122 | })(num)); | |
123 | el.addEventListener('click', (function(el, num) { | |
124 | return function() { | |
125 | var ov, re, rect, show, _k, _l, _len2, _len3, _ref3, _ref4, _results; | |
126 | rect = $('rect', el).one(); | |
127 | show = rect.style.fill !== ''; | |
128 | rect.style.fill = show ? '' : 'transparent'; | |
129 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
130 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
131 | re = _ref3[_k]; | |
132 | re.style.display = show ? '' : 'none'; | |
133 | } | |
134 | _ref4 = $('.text-overlay .serie-' + num, ctx); | |
135 | _results = []; | |
136 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
137 | ov = _ref4[_l]; | |
138 | _results.push(ov.style.display = show ? '' : 'none'); | |
139 | } | |
140 | return _results; | |
141 | }; | |
142 | })(el, num)); | |
143 | } | |
144 | _ref3 = $('.tooltip-trigger', ctx); | |
145 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
146 | el = _ref3[_k]; | |
147 | el.addEventListener('mouseenter', (function(el) { | |
148 | return function() { | |
149 | return tooltip_el = tooltip(el); | |
150 | }; | |
151 | })(el)); | |
152 | } | |
153 | tt.addEventListener('mouseenter', function() { | |
154 | return tooltip_el != null ? tooltip_el.classList.add('active') : void 0; | |
155 | }); | |
156 | tt.addEventListener('mouseleave', function() { | |
157 | return tooltip_el != null ? tooltip_el.classList.remove('active') : void 0; | |
158 | }); | |
159 | ctx.addEventListener('mouseleave', function() { | |
160 | if (tooltip_timeout) { | |
161 | clearTimeout(tooltip_timeout); | |
162 | } | |
163 | return untooltip(0); | |
164 | }); | |
165 | graph.addEventListener('mousemove', function(el) { | |
166 | if (tooltip_timeout) { | |
167 | return; | |
168 | } | |
169 | if (!matches(el.target, '.background')) { | |
170 | return; | |
171 | } | |
172 | return untooltip(1000); | |
173 | }); | |
174 | tooltip = function(el) { | |
175 | var a, baseline, cls, current_x, current_y, dy, h, i, key, keys, label, legend, name, plot_x, plot_y, rect, serie_index, subval, text, text_group, texts, traversal, value, w, x, x_elt, x_label, xlink, y, y_elt, _l, _len3, _len4, _len5, _m, _n, _ref4, _ref5, _ref6, _ref7, _ref8; | |
176 | clearTimeout(tooltip_timeout); | |
177 | tooltip_timeout = null; | |
178 | tt.style.opacity = 1; | |
179 | tt.style.display = ''; | |
180 | text_group = $('g.text', tt).one(); | |
181 | rect = $('rect', tt).one(); | |
182 | text_group.innerHTML = ''; | |
183 | label = sibl(el, '.label').one().textContent; | |
184 | x_label = sibl(el, '.x_label').one().textContent; | |
185 | value = sibl(el, '.value').one().textContent; | |
186 | xlink = sibl(el, '.xlink').one().textContent; | |
187 | serie_index = null; | |
188 | parent = el; | |
189 | traversal = []; | |
190 | while (parent) { | |
191 | traversal.push(parent); | |
192 | if (parent.classList.contains('series')) { | |
193 | break; | |
194 | } | |
195 | parent = parent.parentElement; | |
196 | } | |
197 | if (parent) { | |
198 | _ref4 = parent.classList; | |
199 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
200 | cls = _ref4[_l]; | |
201 | if (cls.indexOf('serie-') === 0) { | |
202 | serie_index = +cls.replace('serie-', ''); | |
203 | break; | |
204 | } | |
205 | } | |
206 | } | |
207 | legend = null; | |
208 | if (serie_index !== null) { | |
209 | legend = config.legends[serie_index]; | |
210 | } | |
211 | dy = 0; | |
212 | keys = [[label, 'label']]; | |
213 | _ref5 = value.split('\n'); | |
214 | for (i = _m = 0, _len4 = _ref5.length; _m < _len4; i = ++_m) { | |
215 | subval = _ref5[i]; | |
216 | keys.push([subval, 'value-' + i]); | |
217 | } | |
218 | if (config.tooltip_fancy_mode) { | |
219 | keys.push([xlink, 'xlink']); | |
220 | keys.unshift([x_label, 'x_label']); | |
221 | keys.unshift([legend, 'legend']); | |
222 | } | |
223 | texts = {}; | |
224 | for (_n = 0, _len5 = keys.length; _n < _len5; _n++) { | |
225 | _ref6 = keys[_n], key = _ref6[0], name = _ref6[1]; | |
226 | if (key) { | |
227 | text = document.createElementNS(svg_ns, 'text'); | |
228 | text.textContent = key; | |
229 | text.setAttribute('x', padding); | |
230 | text.setAttribute('dy', dy); | |
231 | text.classList.add(name.indexOf('value') === 0 ? 'value' : name); | |
232 | if (name.indexOf('value') === 0 && config.tooltip_fancy_mode) { | |
233 | text.classList.add('color-' + serie_index); | |
234 | } | |
235 | if (name === 'xlink') { | |
236 | a = document.createElementNS(svg_ns, 'a'); | |
237 | a.setAttributeNS(xlink_ns, 'href', key); | |
238 | a.textContent = void 0; | |
239 | a.appendChild(text); | |
240 | text.textContent = 'Link >'; | |
241 | text_group.appendChild(a); | |
242 | } else { | |
243 | text_group.appendChild(text); | |
244 | } | |
245 | dy += text.getBBox().height + padding / 2; | |
246 | baseline = padding; | |
247 | if (text.style.dominantBaseline !== void 0) { | |
248 | text.style.dominantBaseline = 'text-before-edge'; | |
249 | } else { | |
250 | baseline += text.getBBox().height * .8; | |
251 | } | |
252 | text.setAttribute('y', baseline); | |
253 | texts[name] = text; | |
254 | } | |
255 | } | |
256 | w = text_group.getBBox().width + 2 * padding; | |
257 | h = text_group.getBBox().height + 2 * padding; | |
258 | rect.setAttribute('width', w); | |
259 | rect.setAttribute('height', h); | |
260 | if (texts.value) { | |
261 | texts.value.setAttribute('dx', (w - texts.value.getBBox().width) / 2 - padding); | |
262 | } | |
263 | if (texts.x_label) { | |
264 | texts.x_label.setAttribute('dx', w - texts.x_label.getBBox().width - 2 * padding); | |
265 | } | |
266 | if (texts.xlink) { | |
267 | texts.xlink.setAttribute('dx', w - texts.xlink.getBBox().width - 2 * padding); | |
268 | } | |
269 | x_elt = sibl(el, '.x').one(); | |
270 | y_elt = sibl(el, '.y').one(); | |
271 | x = parseInt(x_elt.textContent); | |
272 | if (x_elt.classList.contains('centered')) { | |
273 | x -= w / 2; | |
274 | } else if (x_elt.classList.contains('left')) { | |
275 | x -= w; | |
276 | } else if (x_elt.classList.contains('auto')) { | |
277 | x = xconvert(el.getBBox().x + el.getBBox().width / 2) - w / 2; | |
278 | } | |
279 | y = parseInt(y_elt.textContent); | |
280 | if (y_elt.classList.contains('centered')) { | |
281 | y -= h / 2; | |
282 | } else if (y_elt.classList.contains('top')) { | |
283 | y -= h; | |
284 | } else if (y_elt.classList.contains('auto')) { | |
285 | y = yconvert(el.getBBox().y + el.getBBox().height / 2) - h / 2; | |
286 | } | |
287 | _ref7 = get_translation(tt.parentElement), plot_x = _ref7[0], plot_y = _ref7[1]; | |
288 | if (x + w + plot_x > config.width) { | |
289 | x = config.width - w - plot_x; | |
290 | } | |
291 | if (y + h + plot_y > config.height) { | |
292 | y = config.height - h - plot_y; | |
293 | } | |
294 | if (x + plot_x < 0) { | |
295 | x = -plot_x; | |
296 | } | |
297 | if (y + plot_y < 0) { | |
298 | y = -plot_y; | |
299 | } | |
300 | _ref8 = get_translation(tt), current_x = _ref8[0], current_y = _ref8[1]; | |
301 | if (current_x === x && current_y === y) { | |
302 | return el; | |
303 | } | |
304 | tt.setAttribute('transform', "translate(" + x + " " + y + ")"); | |
305 | return el; | |
306 | }; | |
307 | return untooltip = function(ms) { | |
308 | return tooltip_timeout = setTimeout(function() { | |
309 | tt.style.display = 'none'; | |
310 | tt.style.opacity = 0; | |
311 | if (tooltip_el != null) { | |
312 | tooltip_el.classList.remove('active'); | |
313 | } | |
314 | return tooltip_timeout = null; | |
315 | }, ms); | |
316 | }; | |
317 | }; | |
318 | ||
319 | init_svg = function() { | |
320 | var chart, charts, _i, _len, _results; | |
321 | charts = $('.pygal-chart'); | |
322 | if (charts.length) { | |
323 | _results = []; | |
324 | for (_i = 0, _len = charts.length; _i < _len; _i++) { | |
325 | chart = charts[_i]; | |
326 | _results.push(init(chart)); | |
327 | } | |
328 | return _results; | |
329 | } | |
330 | }; | |
331 | ||
332 | if (document.readyState !== 'loading') { | |
333 | init_svg(); | |
334 | } else { | |
335 | document.addEventListener('DOMContentLoaded', function() { | |
336 | return init_svg(); | |
337 | }); | |
338 | } | |
339 | ||
340 | window.pygal = window.pygal || {}; | |
341 | ||
342 | window.pygal.init = init; | |
343 | ||
344 | window.pygal.init_svg = init_svg; | |
345 | ||
346 | }).call(this); | |
347 | </script></defs><title>Speed in Microseconds (us)</title><g class="graph custombox-graph vertical"><rect x="0" y="0" width="800" height="600" class="background" /><g transform="translate(74, 46)" class="plot"><rect x="0" y="0" width="706.0" height="360.0" class="background" /><g class="axis y always_show"><path d="M0.000000 360.000000 h706.000000" class="line" /><g class="guides"><path d="M0.000000 346.262871 h706.000000" class="guide line" /><text x="-5" y="349.76287098728045" class="">20</text><title>20</title></g><g class="guides"><path d="M0.000000 319.006663 h706.000000" class="guide line" /><text x="-5" y="322.5066626287099" class="">40</text><title>40</title></g><g class="guides"><path d="M0.000000 291.750454 h706.000000" class="guide line" /><text x="-5" y="295.2504542701393" class="">60</text><title>60</title></g><g class="guides"><path d="M0.000000 264.494246 h706.000000" class="guide line" /><text x="-5" y="267.9942459115687" class="">80</text><title>80</title></g><g class="guides"><path d="M0.000000 237.238038 h706.000000" class="major guide line" /><text x="-5" y="240.73803755299815" class="major">100</text><title>100</title></g><g class="guides"><path d="M0.000000 209.981829 h706.000000" class="guide line" /><text x="-5" y="213.4818291944276" class="">120</text><title>120</title></g><g class="guides"><path d="M0.000000 182.725621 h706.000000" class="guide line" /><text x="-5" y="186.22562083585703" class="">140</text><title>140</title></g><g class="guides"><path d="M0.000000 155.469412 h706.000000" class="guide line" /><text x="-5" y="158.96941247728645" class="">160</text><title>160</title></g><g class="guides"><path d="M0.000000 128.213204 h706.000000" class="guide line" /><text x="-5" y="131.71320411871588" class="">180</text><title>180</title></g><g class="guides"><path d="M0.000000 100.956996 h706.000000" class="major guide line" /><text x="-5" y="104.45699576014533" class="major">200</text><title>200</title></g><g class="guides"><path d="M0.000000 73.700787 h706.000000" class="guide line" /><text x="-5" y="77.20078740157476" class="">220</text><title>220</title></g><g class="guides"><path d="M0.000000 46.444579 h706.000000" class="guide line" /><text x="-5" y="49.94457904300418" class="">240</text><title>240</title></g><g class="guides"><path d="M0.000000 19.188371 h706.000000" class="guide line" /><text x="-5" y="22.688370684433607" class="">260</text><title>260</title></g></g><g class="axis x"><path d="M0.000000 0.000000 v360.000000" class="line" /><g class="guides"><path d="M24.891026 0.000000 v360.000000" class="guide line" /><text x="24.89102564102564" y="375.0" class="backwards" transform="rotate(270 24.891026 375.000000)">simple_list_e</text></g><g class="guides"><path d="M47.519231 0.000000 v360.000000" class="guide line" /><text x="47.51923076923077" y="375.0" class="backwards" transform="rotate(270 47.519231 375.000000)">simple_dict_d</text></g><g class="guides"><path d="M70.147436 0.000000 v360.000000" class="guide line" /><text x="70.1474358974359" y="375.0" class="backwards" transform="rotate(270 70.147436 375.000000)">simple_tuple_e</text></g><g class="guides"><path d="M92.775641 0.000000 v360.000000" class="guide line" /><text x="92.77564102564102" y="375.0" class="backwards" transform="rotate(270 92.775641 375.000000)">simple_set_e</text></g><g class="guides"><path d="M115.403846 0.000000 v360.000000" class="guide line" /><text x="115.40384615384615" y="375.0" class="backwards" transform="rotate(270 115.403846 375.000000)">simple_tuple_d</text></g><g class="guides"><path d="M138.032051 0.000000 v360.000000" class="guide line" /><text x="138.03205128205127" y="375.0" class="backwards" transform="rotate(270 138.032051 375.000000)">simple_dict_e</text></g><g class="guides"><path d="M160.660256 0.000000 v360.000000" class="guide line" /><text x="160.6602564102564" y="375.0" class="backwards" transform="rotate(270 160.660256 375.000000)">simple_set_d</text></g><g class="guides"><path d="M183.288462 0.000000 v360.000000" class="guide line" /><text x="183.28846153846155" y="375.0" class="backwards" transform="rotate(270 183.288462 375.000000)">simple_list_d</text></g><g class="guides"><path d="M205.916667 0.000000 v360.000000" class="guide line" /><text x="205.91666666666666" y="375.0" class="backwards" transform="rotate(270 205.916667 375.000000)">complex_homog_dict_d</text></g><g class="guides"><path d="M228.544872 0.000000 v360.000000" class="guide line" /><text x="228.5448717948718" y="375.0" class="backwards" transform="rotate(270 228.544872 375.000000)">complex_homog_tuple_d</text></g><g class="guides"><path d="M251.173077 0.000000 v360.000000" class="guide line" /><text x="251.17307692307688" y="375.0" class="backwards" transform="rotate(270 251.173077 375.000000)">complex_homog_set_d</text></g><g class="guides"><path d="M273.801282 0.000000 v360.000000" class="guide line" /><text x="273.8012820512821" y="375.0" class="backwards" transform="rotate(270 273.801282 375.000000)">complex_homog_list_e</text></g><g class="guides"><path d="M296.429487 0.000000 v360.000000" class="guide line" /><text x="296.4294871794872" y="375.0" class="backwards" transform="rotate(270 296.429487 375.000000)">complex_heterog_set_d</text></g><g class="guides"><path d="M319.057692 0.000000 v360.000000" class="guide line" /><text x="319.05769230769226" y="375.0" class="backwards" transform="rotate(270 319.057692 375.000000)">complex_homog_tuple_e</text></g><g class="guides"><path d="M341.685897 0.000000 v360.000000" class="guide line" /><text x="341.6858974358974" y="375.0" class="backwards" transform="rotate(270 341.685897 375.000000)">complex_homog_set_e</text></g><g class="guides"><path d="M364.314103 0.000000 v360.000000" class="guide line" /><text x="364.3141025641026" y="375.0" class="backwards" transform="rotate(270 364.314103 375.000000)">complex_heterog_dict_d</text></g><g class="guides"><path d="M386.942308 0.000000 v360.000000" class="guide line" /><text x="386.9423076923077" y="375.0" class="backwards" transform="rotate(270 386.942308 375.000000)">complex_homog_list_d</text></g><g class="guides"><path d="M409.570513 0.000000 v360.000000" class="guide line" /><text x="409.5705128205129" y="375.0" class="backwards" transform="rotate(270 409.570513 375.000000)">complex_heterog_tuple_d</text></g><g class="guides"><path d="M432.198718 0.000000 v360.000000" class="guide line" /><text x="432.19871794871796" y="375.0" class="backwards" transform="rotate(270 432.198718 375.000000)">complex_heterog_set_e</text></g><g class="guides"><path d="M454.826923 0.000000 v360.000000" class="guide line" /><text x="454.8269230769231" y="375.0" class="backwards" transform="rotate(270 454.826923 375.000000)">complex_heterog_list_d</text></g><g class="guides"><path d="M477.455128 0.000000 v360.000000" class="guide line" /><text x="477.4551282051282" y="375.0" class="backwards" transform="rotate(270 477.455128 375.000000)">complex_homog_dict_e</text></g><g class="guides"><path d="M500.083333 0.000000 v360.000000" class="guide line" /><text x="500.08333333333337" y="375.0" class="backwards" transform="rotate(270 500.083333 375.000000)">simple_cls_d</text></g><g class="guides"><path d="M522.711538 0.000000 v360.000000" class="guide line" /><text x="522.7115384615385" y="375.0" class="backwards" transform="rotate(270 522.711538 375.000000)">complex_heterog_list_e</text></g><g class="guides"><path d="M545.339744 0.000000 v360.000000" class="guide line" /><text x="545.3397435897435" y="375.0" class="backwards" transform="rotate(270 545.339744 375.000000)">complex_heterog_tuple_e</text></g><g class="guides"><path d="M567.967949 0.000000 v360.000000" class="guide line" /><text x="567.9679487179487" y="375.0" class="backwards" transform="rotate(270 567.967949 375.000000)">complex_heterog_dict_e</text></g><g class="guides"><path d="M590.596154 0.000000 v360.000000" class="guide line" /><text x="590.5961538461538" y="375.0" class="backwards" transform="rotate(270 590.596154 375.000000)">simple_cls_e</text></g><g class="guides"><path d="M613.224359 0.000000 v360.000000" class="guide line" /><text x="613.224358974359" y="375.0" class="backwards" transform="rotate(270 613.224359 375.000000)">complex_cls_d</text></g><g class="guides"><path d="M635.852564 0.000000 v360.000000" class="guide line" /><text x="635.8525641025641" y="375.0" class="backwards" transform="rotate(270 635.852564 375.000000)">state_cls_d</text></g><g class="guides"><path d="M658.480769 0.000000 v360.000000" class="guide line" /><text x="658.4807692307692" y="375.0" class="backwards" transform="rotate(270 658.480769 375.000000)">complex_cls_e</text></g><g class="guides"><path d="M681.108974 0.000000 v360.000000" class="guide line" /><text x="681.1089743589743" y="375.0" class="backwards" transform="rotate(270 681.108974 375.000000)">state_cls_e</text></g></g><g class="series serie-0 color-0"><g class="boxes"><g class="box"><path stroke-width="3" d="M19.912821 352.203358 L29.869231 352.203358" class="reactive tooltip-trigger" /><path stroke-width="3" d="M14.934615 351.406117 L34.847436 351.406117" class="reactive tooltip-trigger" /><path stroke-width="3" d="M19.912821 350.565266 L29.869231 350.565266" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 352.203358 L24.891026 351.591457" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 350.565266 L24.891026 351.181258" class="reactive tooltip-trigger" /><rect x="14.934615384615384" y="351.1812576166295" height="0.4101997385010918" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="352.3273795928768" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="198.33525347498144" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 15.5500 | |
348 | Q1-1.5IQR: 15.6410 | |
349 | Q1: 16.0900 | |
350 | Median: 16.2260 | |
351 | Q3: 16.3910 | |
352 | Q3+1.5IQR: 16.8430 | |
353 | Max: 128.5460</desc><desc class="x centered">24.891025641025642</desc><desc class="y centered">351.3894913589321</desc><desc class="x_label" /></g></g></g><g class="series serie-1 color-1"><g class="boxes"><g class="box"><path stroke-width="3" d="M42.541026 351.324347 L52.497436 351.324347" class="reactive tooltip-trigger" /><path stroke-width="3" d="M37.562821 350.664746 L57.475641 350.664746" class="reactive tooltip-trigger" /><path stroke-width="3" d="M42.541026 349.966990 L52.497436 349.966990" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 351.324347 L47.519231 350.816021" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 349.966990 L47.519231 350.476679" class="reactive tooltip-trigger" /><rect x="37.562820512820515" y="350.4766790672791" height="0.33934178301979046" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="351.44699973906154" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="330.9762246506926" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.1960 | |
354 | Q1-1.5IQR: 16.2860 | |
355 | Q1: 16.6590 | |
356 | Median: 16.7700 | |
357 | Q3: 16.9080 | |
358 | Q3+1.5IQR: 17.2820 | |
359 | Max: 31.2170</desc><desc class="x centered">47.519230769230774</desc><desc class="y centered">350.64975651498906</desc><desc class="x_label" /></g></g></g><g class="series serie-2 color-2"><g class="boxes"><g class="box"><path stroke-width="3" d="M65.169231 351.313449 L75.125641 351.313449" class="reactive tooltip-trigger" /><path stroke-width="3" d="M60.191026 350.558449 L80.103846 350.558449" class="reactive tooltip-trigger" /><path stroke-width="3" d="M65.169231 349.773474 L75.125641 349.773474" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 351.313449 L70.147436 350.738341" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 349.773474 L70.147436 350.352663" class="reactive tooltip-trigger" /><rect x="60.19102564102564" y="350.3526627715606" height="0.3856780866811391" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="351.42383654510627" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="279.4633536861007" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.2130 | |
360 | Q1-1.5IQR: 16.2940 | |
361 | Q1: 16.7160 | |
362 | Median: 16.8480 | |
363 | Q3: 16.9990 | |
364 | Q3+1.5IQR: 17.4240 | |
365 | Max: 69.0160</desc><desc class="x centered">70.1474358974359</desc><desc class="y centered">350.54727524693834</desc><desc class="x_label" /></g></g></g><g class="series serie-3 color-3"><g class="boxes"><g class="box"><path stroke-width="3" d="M87.797436 350.978193 L97.753846 350.978193" class="reactive tooltip-trigger" /><path stroke-width="3" d="M82.819231 350.126437 L102.732051 350.126437" class="reactive tooltip-trigger" /><path stroke-width="3" d="M87.797436 349.228346 L97.753846 349.228346" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 350.978193 L92.775641 350.326773" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 349.228346 L92.775641 349.887946" class="reactive tooltip-trigger" /><rect x="82.81923076923077" y="349.8879462349576" height="0.4388265111675196" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="351.1444602652734" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="307.47183466699795" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.4180 | |
366 | Q1-1.5IQR: 16.5400 | |
367 | Q1: 17.0180 | |
368 | Median: 17.1650 | |
369 | Q3: 17.3400 | |
370 | Q3+1.5IQR: 17.8240 | |
371 | Max: 48.4640</desc><desc class="x centered">92.77564102564102</desc><desc class="y centered">350.10953897257536</desc><desc class="x_label" /></g></g></g><g class="series serie-4 color-4"><g class="boxes"><g class="box"><path stroke-width="3" d="M110.425641 350.679739 L120.382051 350.679739" class="reactive tooltip-trigger" /><path stroke-width="3" d="M105.447436 350.063748 L125.360256 350.063748" class="reactive tooltip-trigger" /><path stroke-width="3" d="M110.425641 349.417781 L120.382051 349.417781" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 350.679739 L115.403846 350.208205" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 349.417781 L115.403846 349.892036" class="reactive tooltip-trigger" /><rect x="105.4474358974359" y="349.8920364821779" height="0.31616867331365484" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="350.7247116587163" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="250.69578727350194" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.7260 | |
372 | Q1-1.5IQR: 16.7590 | |
373 | Q1: 17.1050 | |
374 | Median: 17.2110 | |
375 | Q3: 17.3370 | |
376 | Q3+1.5IQR: 17.6850 | |
377 | Max: 90.1250</desc><desc class="x centered">115.40384615384615</desc><desc class="y centered">350.0523017882313</desc><desc class="x_label" /></g></g></g><g class="series serie-5 color-5"><g class="boxes"><g class="box"><path stroke-width="3" d="M133.053846 349.976529 L143.010256 349.976529" class="reactive tooltip-trigger" /><path stroke-width="3" d="M128.075641 348.908087 L147.988462 348.908087" class="reactive tooltip-trigger" /><path stroke-width="3" d="M133.053846 347.610690 L143.010256 347.610690" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 349.976529 L138.032051 349.161568" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 347.610690 L138.032051 348.544213" class="reactive tooltip-trigger" /><rect x="128.07564102564103" y="348.54421326027943" height="0.6173546471126201" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="349.9765285950601" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="314.87461693788697" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 17.2750 | |
378 | Q1-1.5IQR: 17.2750 | |
379 | Q1: 17.8730 | |
380 | Median: 18.0590 | |
381 | Q3: 18.3260 | |
382 | Q3+1.5IQR: 19.0110 | |
383 | Max: 43.0320</desc><desc class="x centered">138.0320512820513</desc><desc class="y centered">348.84021726269094</desc><desc class="x_label" /></g></g></g><g class="series serie-6 color-6"><g class="boxes"><g class="box"><path stroke-width="3" d="M155.682051 349.810266 L165.638462 349.810266" class="reactive tooltip-trigger" /><path stroke-width="3" d="M150.703846 349.188821 L170.616667 349.188821" class="reactive tooltip-trigger" /><path stroke-width="3" d="M155.682051 348.537401 L165.638462 348.537401" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 349.810266 L160.660256 349.337374" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 348.537401 L160.660256 349.019837" class="reactive tooltip-trigger" /><rect x="150.70384615384614" y="349.01983712280315" height="0.3175370469291465" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="349.94791173814446" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="204.99530634517467" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 17.2960 | |
384 | Q1-1.5IQR: 17.3970 | |
385 | Q1: 17.7440 | |
386 | Median: 17.8530 | |
387 | Q3: 17.9770 | |
388 | Q3+1.5IQR: 18.3310 | |
389 | Max: 123.6590</desc><desc class="x centered">160.6602564102564</desc><desc class="y centered">349.1787400046916</desc><desc class="x_label" /></g></g></g><g class="series serie-7 color-7"><g class="boxes"><g class="box"><path stroke-width="3" d="M178.310256 347.492122 L188.266667 347.492122" class="reactive tooltip-trigger" /><path stroke-width="3" d="M173.332051 346.750756 L193.244872 346.750756" class="reactive tooltip-trigger" /><path stroke-width="3" d="M178.310256 345.960327 L188.266667 345.960327" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 347.492122 L183.288462 346.926563" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 345.960327 L183.288462 346.540885" class="reactive tooltip-trigger" /><rect x="173.33205128205125" y="346.540884539923" height="0.3856780866811391" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="347.5984241560678" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="306.055875363223" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 19.0200 | |
390 | Q1-1.5IQR: 19.0980 | |
391 | Q1: 19.5130 | |
392 | Median: 19.6420 | |
393 | Q3: 19.7960 | |
394 | Q3+1.5IQR: 20.2220 | |
395 | Max: 49.5030</desc><desc class="x centered">183.28846153846152</desc><desc class="y centered">346.7341306248354</desc><desc class="x_label" /></g></g></g><g class="series serie-8 color-8"><g class="boxes"><g class="box"><path stroke-width="3" d="M200.938462 324.839490 L210.894872 324.839490" class="reactive tooltip-trigger" /><path stroke-width="3" d="M195.960256 323.659295 L215.873077 323.659295" class="reactive tooltip-trigger" /><path stroke-width="3" d="M200.938462 322.439581 L210.894872 322.439581" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 324.839490 L205.916667 323.945486" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 322.439581 L205.916667 323.344488" class="reactive tooltip-trigger" /><rect x="195.9602564102564" y="323.3444876929769" height="0.6009986161068923" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="324.9975772201437" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="181.9883400022189" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 35.6040 | |
396 | Q1-1.5IQR: 35.7200 | |
397 | Q1: 36.3760 | |
398 | Median: 36.5860 | |
399 | Q3: 36.8170 | |
400 | Q3+1.5IQR: 37.4810 | |
401 | Max: 140.5410</desc><desc class="x centered">205.91666666666666</desc><desc class="y centered">323.64566821311286</desc><desc class="x_label" /></g></g></g><g class="series serie-9 color-9"><g class="boxes"><g class="box"><path stroke-width="3" d="M223.566667 324.297094 L233.523077 324.297094" class="reactive tooltip-trigger" /><path stroke-width="3" d="M218.588462 323.437160 L238.501282 323.437160" class="reactive tooltip-trigger" /><path stroke-width="3" d="M223.566667 322.554059 L233.523077 322.554059" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 324.297094 L228.544872 323.648051" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 322.554059 L228.544872 323.210932" class="reactive tooltip-trigger" /><rect x="218.58846153846153" y="323.21093244495313" height="0.4371185230858714" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="324.4769854275741" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="285.4106574282538" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 35.9860 | |
402 | Q1-1.5IQR: 36.1180 | |
403 | Q1: 36.5943 | |
404 | Median: 36.7490 | |
405 | Q3: 36.9150 | |
406 | Q3+1.5IQR: 37.3970 | |
407 | Max: 64.6520</desc><desc class="x centered">228.5448717948718</desc><desc class="y centered">323.42945923241206</desc><desc class="x_label" /></g></g></g><g class="series serie-10 color-10"><g class="boxes"><g class="box"><path stroke-width="3" d="M246.194872 323.164601 L256.151282 323.164601" class="reactive tooltip-trigger" /><path stroke-width="3" d="M241.216667 321.978952 L261.129487 321.978952" class="reactive tooltip-trigger" /><path stroke-width="3" d="M246.194872 320.693824 L256.151282 320.693824" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 323.164601 L251.173077 322.266502" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 320.693824 L251.173077 321.640977" class="reactive tooltip-trigger" /><rect x="241.21666666666664" y="321.6409765728039" height="0.6255252258022779" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="323.2218348129984" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="258.9871249347714" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 36.9070 | |
408 | Q1-1.5IQR: 36.9490 | |
409 | Q1: 37.6080 | |
410 | Median: 37.8190 | |
411 | Q3: 38.0670 | |
412 | Q3+1.5IQR: 38.7620 | |
413 | Max: 84.0410</desc><desc class="x centered">251.1730769230769</desc><desc class="y centered">321.948971196915</desc><desc class="x_label" /></g></g></g><g class="series serie-11 color-11"><g class="boxes"><g class="box"><path stroke-width="3" d="M268.823077 319.168841 L278.779487 319.168841" class="reactive tooltip-trigger" /><path stroke-width="3" d="M263.844872 317.549822 L283.757692 317.549822" class="reactive tooltip-trigger" /><path stroke-width="3" d="M268.823077 315.189432 L278.779487 315.189432" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 319.168841 L273.801282 318.092219" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 315.189432 L273.801282 316.937916" class="reactive tooltip-trigger" /><rect x="263.84487179487184" y="316.93791611930567" height="1.1543024706878668" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="319.16884106862415" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="279.0558758212044" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 39.8810 | |
414 | Q1-1.5IQR: 39.8810 | |
415 | Q1: 40.6710 | |
416 | Median: 41.0690 | |
417 | Q3: 41.5180 | |
418 | Q3+1.5IQR: 42.8010 | |
419 | Max: 69.3150</desc><desc class="x centered">273.8012820512821</desc><desc class="y centered">317.38764599009363</desc><desc class="x_label" /></g></g></g><g class="series serie-12 color-12"><g class="boxes"><g class="box"><path stroke-width="3" d="M291.451282 318.498333 L301.407692 318.498333" class="reactive tooltip-trigger" /><path stroke-width="3" d="M286.473077 317.369928 L306.385897 317.369928" class="reactive tooltip-trigger" /><path stroke-width="3" d="M291.451282 316.161116 L301.407692 316.161116" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 318.498333 L296.429487 317.643853" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 316.161116 L296.429487 317.051030" class="reactive tooltip-trigger" /><rect x="286.473076923077" y="317.05103004697895" height="0.5928230795418017" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="318.6223493348683" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="-14.31495929252793" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 40.2820 | |
420 | Q1-1.5IQR: 40.3730 | |
421 | Q1: 41.0000 | |
422 | Median: 41.2010 | |
423 | Q3: 41.4350 | |
424 | Q3+1.5IQR: 42.0880 | |
425 | Max: 284.5840</desc><desc class="x centered">296.42948717948724</desc><desc class="y centered">317.34485208841875</desc><desc class="x_label" /></g></g></g><g class="series serie-13 color-13"><g class="boxes"><g class="box"><path stroke-width="3" d="M314.079487 316.428227 L324.035897 316.428227" class="reactive tooltip-trigger" /><path stroke-width="3" d="M309.101282 314.223881 L329.014103 314.223881" class="reactive tooltip-trigger" /><path stroke-width="3" d="M314.079487 311.922772 L324.035897 311.922772" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 316.428227 L319.057692 314.765596" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 311.922772 L319.057692 313.630374" class="reactive tooltip-trigger" /><rect x="309.1012820512821" y="313.630373649232" height="1.1352220871397094" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="316.4895556137084" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="169.07843895820895" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 41.8470 | |
426 | Q1-1.5IQR: 41.8920 | |
427 | Q1: 43.1120 | |
428 | Median: 43.5095 | |
429 | Q3: 43.9450 | |
430 | Q3+1.5IQR: 45.1980 | |
431 | Max: 150.0140</desc><desc class="x centered">319.0576923076924</desc><desc class="y centered">314.1941698555611</desc><desc class="x_label" /></g></g></g><g class="series serie-14 color-14"><g class="boxes"><g class="box"><path stroke-width="3" d="M336.707692 316.008478 L346.664103 316.008478" class="reactive tooltip-trigger" /><path stroke-width="3" d="M331.729487 313.864777 L351.642308 313.864777" class="reactive tooltip-trigger" /><path stroke-width="3" d="M336.707692 311.606604 L346.664103 311.606604" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 316.008478 L341.685897 314.381284" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 311.606604 L341.685897 313.271959" class="reactive tooltip-trigger" /><rect x="331.7294871794872" y="313.27195891947724" height="1.1093246248911441" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="316.2892177837973" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="129.59236731020692" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 41.9940 | |
432 | Q1-1.5IQR: 42.2000 | |
433 | Q1: 43.3940 | |
434 | Median: 43.7730 | |
435 | Q3: 44.2080 | |
436 | Q3+1.5IQR: 45.4300 | |
437 | Max: 178.9880</desc><desc class="x centered">341.68589743589746</desc><desc class="y centered">313.8266202403477</desc><desc class="x_label" /></g></g></g><g class="series serie-15 color-15"><g class="boxes"><g class="box"><path stroke-width="3" d="M359.335897 314.002423 L369.292308 314.002423" class="reactive tooltip-trigger" /><path stroke-width="3" d="M354.357692 311.103726 L374.270513 311.103726" class="reactive tooltip-trigger" /><path stroke-width="3" d="M359.335897 308.124623 L369.292308 308.124623" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 314.002423 L364.314103 311.811022" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 308.124623 L364.314103 310.337824" class="reactive tooltip-trigger" /><rect x="354.35769230769233" y="310.3378237944239" height="1.4731979754816393" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="314.62795272006537" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="240.45699614784263" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 43.2130 | |
438 | Q1-1.5IQR: 43.6720 | |
439 | Q1: 45.2800 | |
440 | Median: 45.7990 | |
441 | Q3: 46.3610 | |
442 | Q3+1.5IQR: 47.9850 | |
443 | Max: 97.6380</desc><desc class="x centered">364.3141025641026</desc><desc class="y centered">311.0759235310539</desc><desc class="x_label" /></g></g></g><g class="series serie-16 color-16"><g class="boxes"><g class="box"><path stroke-width="3" d="M381.964103 313.532252 L391.920513 313.532252" class="reactive tooltip-trigger" /><path stroke-width="3" d="M376.985897 311.425349 L396.898718 311.425349" class="reactive tooltip-trigger" /><path stroke-width="3" d="M381.964103 309.183526 L391.920513 309.183526" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 313.532252 L386.942308 311.945940" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 309.183526 L386.942308 310.841725" class="reactive tooltip-trigger" /><rect x="376.98589743589747" y="310.84172489939704" height="1.1042155342723845" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="313.71350730424956" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="233.25318333324913" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 43.8840 | |
444 | Q1-1.5IQR: 44.0170 | |
445 | Q1: 45.1810 | |
446 | Median: 45.5630 | |
447 | Q3: 45.9912 | |
448 | Q3+1.5IQR: 47.2080 | |
449 | Max: 102.9240</desc><desc class="x centered">386.94230769230774</desc><desc class="y centered">311.38575851852045</desc><desc class="x_label" /></g></g></g><g class="series serie-17 color-17"><g class="boxes"><g class="box"><path stroke-width="3" d="M404.592308 312.890371 L414.548718 312.890371" class="reactive tooltip-trigger" /><path stroke-width="3" d="M399.614103 310.580408 L419.526923 310.580408" class="reactive tooltip-trigger" /><path stroke-width="3" d="M404.592308 308.176408 L414.548718 308.176408" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 312.890371 L409.570513 311.139155" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 308.176408 L409.570513 309.954877" class="reactive tooltip-trigger" /><rect x="399.6141025641026" y="309.9548774970984" height="1.1842777854681117" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="313.2215323685956" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="-191.86735560796" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 44.2450 | |
450 | Q1-1.5IQR: 44.4880 | |
451 | Q1: 45.7730 | |
452 | Median: 46.1830 | |
453 | Q3: 46.6420 | |
454 | Q3+1.5IQR: 47.9470 | |
455 | Max: 414.8680</desc><desc class="x centered">409.5705128205129</desc><desc class="y centered">310.548243959786</desc><desc class="x_label" /></g></g></g><g class="series serie-18 color-18"><g class="boxes"><g class="box"><path stroke-width="3" d="M427.220513 309.381132 L437.176923 309.381132" class="reactive tooltip-trigger" /><path stroke-width="3" d="M422.242308 306.900816 L442.155128 306.900816" class="reactive tooltip-trigger" /><path stroke-width="3" d="M427.220513 304.304665 L437.176923 304.304665" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 309.381132 L432.198718 307.505910" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 304.304665 L432.198718 306.226223" class="reactive tooltip-trigger" /><rect x="422.24230769230775" y="306.22622300472744" height="1.279687140021906" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="309.67550121726543" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="-36.784977811908504" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 46.8470 | |
456 | Q1-1.5IQR: 47.0630 | |
457 | Q1: 48.4390 | |
458 | Median: 48.8830 | |
459 | Q3: 49.3780 | |
460 | Q3+1.5IQR: 50.7880 | |
461 | Max: 301.0720</desc><desc class="x centered">432.198717948718</desc><desc class="y centered">306.8637492637678</desc><desc class="x_label" /></g></g></g><g class="series serie-19 color-19"><g class="boxes"><g class="box"><path stroke-width="3" d="M449.848718 307.963810 L459.805128 307.963810" class="reactive tooltip-trigger" /><path stroke-width="3" d="M444.870513 305.566627 L464.783333 305.566627" class="reactive tooltip-trigger" /><path stroke-width="3" d="M449.848718 303.109479 L459.805128 303.109479" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 307.963810 L454.826923 306.148548" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 303.109479 L454.826923 304.932922" class="reactive tooltip-trigger" /><rect x="444.87051282051283" y="304.93292153880634" height="1.215626431739338" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="308.38900691429393" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="12.462902641364337" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 47.7910 | |
462 | Q1-1.5IQR: 48.1030 | |
463 | Q1: 49.4350 | |
464 | Median: 49.8620 | |
465 | Q3: 50.3270 | |
466 | Q3+1.5IQR: 51.6650 | |
467 | Max: 264.9350</desc><desc class="x centered">454.8269230769231</desc><desc class="y centered">305.54427715666253</desc><desc class="x_label" /></g></g></g><g class="series serie-20 color-20"><g class="boxes"><g class="box"><path stroke-width="3" d="M472.476923 303.938069 L482.433333 303.938069" class="reactive tooltip-trigger" /><path stroke-width="3" d="M467.498718 300.571930 L487.411538 300.571930" class="reactive tooltip-trigger" /><path stroke-width="3" d="M472.476923 297.115839 L482.433333 297.115839" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 303.938069 L477.455128 301.433222" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 297.115839 L477.455128 299.706882" class="reactive tooltip-trigger" /><rect x="467.49871794871797" y="299.7068820757246" height="1.726339657537551" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="304.6549086747135" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="-97.80209099590445" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 50.5310 | |
468 | Q1-1.5IQR: 51.0570 | |
469 | Q1: 52.8950 | |
470 | Median: 53.5270 | |
471 | Q3: 54.1618 | |
472 | Q3+1.5IQR: 56.0630 | |
473 | Max: 345.8450</desc><desc class="x centered">477.45512820512823</desc><desc class="y centered">300.55318843493865</desc><desc class="x_label" /></g></g></g><g class="series serie-21 color-21"><g class="boxes"><g class="box"><path stroke-width="3" d="M495.105128 302.259085 L505.061538 302.259085" class="reactive tooltip-trigger" /><path stroke-width="3" d="M490.126923 299.038082 L510.039744 299.038082" class="reactive tooltip-trigger" /><path stroke-width="3" d="M495.105128 295.646727 L505.061538 295.646727" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 302.259085 L500.083333 299.803982" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 295.646727 L500.083333 298.143399" class="reactive tooltip-trigger" /><rect x="490.1269230769231" y="298.1433987099342" height="1.6605833558618883" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="302.9186854925292" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="153.30935594972263" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 51.8050 | |
474 | Q1-1.5IQR: 52.2890 | |
475 | Q1: 54.0905 | |
476 | Median: 54.6525 | |
477 | Q3: 55.3090 | |
478 | Q3+1.5IQR: 57.1410 | |
479 | Max: 161.5850</desc><desc class="x centered">500.08333333333337</desc><desc class="y centered">298.9782548558692</desc><desc class="x_label" /></g></g></g><g class="series serie-22 color-22"><g class="boxes"><g class="box"><path stroke-width="3" d="M517.733333 302.023323 L527.689744 302.023323" class="reactive tooltip-trigger" /><path stroke-width="3" d="M512.755128 299.243184 L532.667949 299.243184" class="reactive tooltip-trigger" /><path stroke-width="3" d="M517.733333 296.355391 L527.689744 296.355391" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 302.023323 L522.711538 299.910281" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 296.355391 L522.711538 298.491595" class="reactive tooltip-trigger" /><rect x="512.7551282051282" y="298.4915952584514" height="1.4186861352552" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="302.51256608549755" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="142.90021222468343" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 52.1030 | |
480 | Q1-1.5IQR: 52.4620 | |
481 | Q1: 54.0125 | |
482 | Median: 54.5020 | |
483 | Q3: 55.0535 | |
484 | Q3+1.5IQR: 56.6210 | |
485 | Max: 169.2230</desc><desc class="x centered">522.7115384615385</desc><desc class="y centered">299.2047548985762</desc><desc class="x_label" /></g></g></g><g class="series serie-23 color-23"><g class="boxes"><g class="box"><path stroke-width="3" d="M540.361538 301.043458 L550.317949 301.043458" class="reactive tooltip-trigger" /><path stroke-width="3" d="M535.383333 298.281044 L555.296154 298.281044" class="reactive tooltip-trigger" /><path stroke-width="3" d="M540.361538 295.436855 L550.317949 295.436855" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 301.043458 L545.339744 298.949160" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 295.436855 L545.339744 297.545127" class="reactive tooltip-trigger" /><rect x="535.3833333333333" y="297.54512692530744" height="1.4040331344558012" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="302.2154753167943" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="152.15505843691022" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 52.3210 | |
486 | Q1-1.5IQR: 53.1810 | |
487 | Q1: 54.7177 | |
488 | Median: 55.2080 | |
489 | Q3: 55.7480 | |
490 | Q3+1.5IQR: 57.2950 | |
491 | Max: 162.4320</desc><desc class="x centered">545.3397435897435</desc><desc class="y centered">298.25112888069054</desc><desc class="x_label" /></g></g></g><g class="series serie-24 color-24"><g class="boxes"><g class="box"><path stroke-width="3" d="M562.989744 294.826317 L572.946154 294.826317" class="reactive tooltip-trigger" /><path stroke-width="3" d="M558.011538 291.518775 L577.924359 291.518775" class="reactive tooltip-trigger" /><path stroke-width="3" d="M562.989744 288.085858 L572.946154 288.085858" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 294.826317 L567.967949 292.314658" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 288.085858 L567.967949 290.623410" class="reactive tooltip-trigger" /><rect x="558.0115384615385" y="290.62340978521394" height="1.6912478153253687" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="296.1182602956118" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="-139.6471842204129" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 56.7950 | |
492 | Q1-1.5IQR: 57.7430 | |
493 | Q1: 59.5860 | |
494 | Median: 60.1700 | |
495 | Q3: 60.8270 | |
496 | Q3+1.5IQR: 62.6890 | |
497 | Max: 376.5500</desc><desc class="x centered">567.9679487179487</desc><desc class="y centered">291.473803416923</desc><desc class="x_label" /></g></g></g><g class="series serie-25 color-25"><g class="boxes"><g class="box"><path stroke-width="3" d="M585.617949 289.897034 L595.574359 289.897034" class="reactive tooltip-trigger" /><path stroke-width="3" d="M580.639744 286.852517 L600.552564 286.852517" class="reactive tooltip-trigger" /><path stroke-width="3" d="M585.617949 283.538157 L595.574359 283.538157" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 289.897034 L590.596154 287.565266" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 283.538157 L590.596154 285.957144" class="reactive tooltip-trigger" /><rect x="580.6397435897436" y="285.95714420413424" height="1.6081215971209417" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="290.4557864962519" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="248.0124165292413" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 60.9500 | |
498 | Q1-1.5IQR: 61.3600 | |
499 | Q1: 63.0710 | |
500 | Median: 63.5940 | |
501 | Q3: 64.2510 | |
502 | Q3+1.5IQR: 66.0260 | |
503 | Max: 92.0940</desc><desc class="x centered">590.5961538461538</desc><desc class="y centered">286.76202354792633</desc><desc class="x_label" /></g></g></g><g class="series serie-26 color-26"><g class="boxes"><g class="box"><path stroke-width="3" d="M608.246154 79.273318 L618.202564 79.273318" class="reactive tooltip-trigger" /><path stroke-width="3" d="M603.267949 74.949803 L623.180769 74.949803" class="reactive tooltip-trigger" /><path stroke-width="3" d="M608.246154 70.454576 L618.202564 70.454576" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 79.273318 L613.224359 76.006663" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 70.454576 L613.224359 73.796184" class="reactive tooltip-trigger" /><rect x="603.2679487179488" y="73.796184498674" height="2.210478671092517" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="80.47668364709313" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="4.456389965012875" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 215.0280 | |
504 | Q1-1.5IQR: 215.9110 | |
505 | Q1: 218.3080 | |
506 | Median: 219.0835 | |
507 | Q3: 219.9300 | |
508 | Q3+1.5IQR: 222.3820 | |
509 | Max: 270.8100</desc><desc class="x centered">613.224358974359</desc><desc class="y centered">74.8961089917716</desc><desc class="x_label" /></g></g></g><g class="series serie-27 color-27"><g class="boxes"><g class="box"><path stroke-width="3" d="M630.874359 71.577530 L640.830769 71.577530" class="reactive tooltip-trigger" /><path stroke-width="3" d="M625.896154 67.298304 L645.808974 67.298304" class="reactive tooltip-trigger" /><path stroke-width="3" d="M630.874359 62.739701 L640.830769 62.739701" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 71.577530 L635.852564 68.382757" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 62.739701 L635.852564 66.144346" class="reactive tooltip-trigger" /><rect x="625.8961538461539" y="66.14434583507392" height="2.23841134120039" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="72.58191652479928" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="-667.3260167648473" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 220.8210 | |
510 | Q1-1.5IQR: 221.5580 | |
511 | Q1: 223.9023 | |
512 | Median: 224.6980 | |
513 | Q3: 225.5447 | |
514 | Q3+1.5IQR: 228.0430 | |
515 | Max: 763.7490</desc><desc class="x centered">635.8525641025641</desc><desc class="y centered">67.22852758635514</desc><desc class="x_label" /></g></g></g><g class="series serie-28 color-28"><g class="boxes"><g class="box"><path stroke-width="3" d="M653.502564 30.086762 L663.458974 30.086762" class="reactive tooltip-trigger" /><path stroke-width="3" d="M648.524359 24.770442 L668.437179 24.770442" class="reactive tooltip-trigger" /><path stroke-width="3" d="M653.502564 19.131131 L663.458974 19.131131" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 30.086762 L658.480769 26.054212" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 19.131131 L658.480769 23.288386" class="reactive tooltip-trigger" /><rect x="648.524358974359" y="23.28838643361047" height="2.765825170345863" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="30.899000363105642" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="-253.91747188265458" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 251.4070 | |
516 | Q1-1.5IQR: 252.0030 | |
517 | Q1: 254.9620 | |
518 | Median: 255.9040 | |
519 | Q3: 256.9915 | |
520 | Q3+1.5IQR: 260.0420 | |
521 | Max: 460.3990</desc><desc class="x centered">658.4807692307692</desc><desc class="y centered">24.66618645765186</desc><desc class="x_label" /></g></g></g><g class="series serie-29 color-29"><g class="boxes"><g class="box"><path stroke-width="3" d="M676.130769 17.814656 L686.087179 17.814656" class="reactive tooltip-trigger" /><path stroke-width="3" d="M671.152564 12.735462 L691.065385 12.735462" class="reactive tooltip-trigger" /><path stroke-width="3" d="M676.130769 7.158844 L686.087179 7.158844" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 17.814656 L681.108974 13.979710" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 7.158844 L681.108974 11.267718" class="reactive tooltip-trigger" /><rect x="671.1525641025642" y="11.267717529975528" height="2.71199255905168" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="18.27665113549375" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="-300.2884608404562" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 260.6690 | |
522 | Q1-1.5IQR: 261.0080 | |
523 | Q1: 263.8220 | |
524 | Median: 264.7350 | |
525 | Q3: 265.8120 | |
526 | Q3+1.5IQR: 268.8270 | |
527 | Max: 494.4250</desc><desc class="x centered">681.1089743589744</desc><desc class="y centered">12.591277901150875</desc><desc class="x_label" /></g></g></g></g><g class="titles"><text x="400.0" y="26" class="title plot_title">Speed in Microseconds (us)</text><text x="427.0" y="580.0" class="title">Trial</text><text x="0" y="252.0" class="title" transform="rotate(-90 0.000000 226.000000)">Duration</text></g><g transform="translate(74, 46)" class="plot overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot text-overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot tooltip-overlay"><g transform="translate(0 0)" style="opacity: 0" class="tooltip"><rect rx="0" ry="0" width="0" height="0" class="tooltip-box" /><g class="text" /></g></g></g></svg>⏎ |
0 | <?xml version='1.0' encoding='utf-8'?> | |
1 | <svg xmlns="http://www.w3.org/2000/svg" id="chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797" class="pygal-chart" viewBox="0 0 800 600"><!--Generated with pygal 3.0.0 (etree) ©Kozea 2012-2016 on 2022-06-20--><!--http://pygal.org--><!--http://github.com/Kozea/pygal--><defs><style type="text/css">#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .title{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .legends .legend text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis text.major{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay text.value{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay text.label{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 text.no_data{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:64px} | |
2 | #chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797{background-color:rgba(249,249,249,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 path,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 line,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 rect,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .graph > .background{fill:rgba(249,249,249,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .plot > .background{fill:rgba(255,255,255,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .graph{fill:rgba(0,0,0,.87)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 text.no_data{fill:rgba(0,0,0,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .title{fill:rgba(0,0,0,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .legends .legend text{fill:rgba(0,0,0,.87)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis .line{stroke:rgba(0,0,0,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis text.major{fill:rgba(0,0,0,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.y .guides:hover .guide.line,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .line-graph .axis.x .guides:hover .guide.line,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .stackedline-graph .axis.x .guides:hover .guide.line,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .reactive{fill-opacity:.7;stroke-opacity:.8;stroke-width:1}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .ci{stroke:rgba(0,0,0,.87)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .reactive.active,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .ci .reactive.active{stroke-width:1.5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .series text{fill:rgba(0,0,0,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip .value{font-size:1.5em}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .bound{font-size:.5em}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-0,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-0 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-1,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-1 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-2,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-2 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-3,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-3 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-4,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-4 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-5,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-5 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-6,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-6 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-7,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-7 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-8,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-8 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-9,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-9 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-10,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-10 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-11,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-11 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-12,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-12 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-13,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-13 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-14,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-14 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-15,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-15 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-16,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-16 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-17,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-17 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-18,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-18 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-19,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-19 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-20,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-20 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-21,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-21 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-22,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-22 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-23,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-23 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-24,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-24 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-25,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-25 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-26,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-26 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-27,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-27 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-28,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-28 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-29,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .color-29 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-0 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-1 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-2 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-3 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-4 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-5 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-6 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-7 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-8 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-9 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-10 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-11 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-12 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-13 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-14 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-15 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-16 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-17 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-18 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-19 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-20 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-21 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-22 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-23 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-24 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-25 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-26 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-27 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-28 text{fill:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .text-overlay .color-29 text{fill:black} | |
3 | #chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 text.no_data{text-anchor:middle}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .guide.line{fill:none}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .centered{text-anchor:middle}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .title{text-anchor:middle}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .legends .legend text{fill-opacity:1}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.x text{text-anchor:middle}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.x:not(.web) text[transform]{text-anchor:start}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.y text{text-anchor:end}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.y text[transform].backwards{text-anchor:start}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.y2 text{text-anchor:start}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.y2 text[transform].backwards{text-anchor:end}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis .guide.line{stroke-dasharray:4,4;stroke:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis .major.guide.line{stroke-dasharray:6,6;stroke:black}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .horizontal .axis.y .guide.line,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .horizontal .axis.y2 .guide.line,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .vertical .axis.x .guide.line{opacity:0}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .horizontal .axis.always_show .guide.line,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.y .guides:hover .guide.line,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.y2 .guides:hover .guide.line,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis.x .guides:hover .guide.line{opacity:1}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .axis .guides:hover text{opacity:1}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .nofill{fill:none}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .subtle-fill{fill-opacity:.2}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .dot{stroke-width:1px;fill-opacity:1;stroke-opacity:1}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .dot.active{stroke-width:5px}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .dot.negative{fill:transparent}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 text,#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 tspan{stroke:none !important}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .series text.active{opacity:1}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .tooltip text{fill-opacity:1}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .showable{visibility:hidden}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .showable.shown{visibility:visible}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-be6cdfb8-8c9d-4441-ba08-e1f74ae57797 .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px} | |
4 | .tooltip .value{font-size:1em !important}.axis text{font-size:9px !important}</style><script type="text/javascript">window.pygal = window.pygal || {};window.pygal.config = window.pygal.config || {};window.pygal.config['be6cdfb8-8c9d-4441-ba08-e1f74ae57797'] = {"allow_interruptions": false, "box_mode": "tukey", "classes": ["pygal-chart"], "css": ["file://style.css", "file://graph.css", "inline:\n .tooltip .value {\n font-size: 1em !important;\n }\n .axis text {\n font-size: 9px !important;\n }\n "], "defs": [], "disable_xml_declaration": false, "dots_size": 2.5, "dynamic_print_values": false, "explicit_size": false, "fill": false, "force_uri_protocol": "https", "formatter": null, "half_pie": false, "height": 600, "include_x_axis": false, "inner_radius": 0, "interpolate": null, "interpolation_parameters": {}, "interpolation_precision": 250, "inverse_y_axis": false, "js": ["file:///home/theel/.pyenv/versions/3.9.13/lib/python3.9/site-packages/pygaljs/static/2.0.x/pygal-tooltips.js"], "legend_at_bottom": false, "legend_at_bottom_columns": null, "legend_box_size": 12, "logarithmic": false, "margin": 20, "margin_bottom": null, "margin_left": null, "margin_right": null, "margin_top": null, "max_scale": 20, "min_scale": 20, "missing_value_fill_truncation": "x", "no_data_text": "No data", "no_prefix": false, "order_min": null, "pretty_print": false, "print_labels": false, "print_values": false, "print_values_position": "center", "print_zeroes": true, "range": [14, 157], "rounded_bars": null, "secondary_range": null, "show_dots": true, "show_legend": false, "show_minor_x_labels": true, "show_minor_y_labels": true, "show_only_major_dots": false, "show_x_guides": false, "show_x_labels": true, "show_y_guides": true, "show_y_labels": true, "spacing": 10, "stack_from_top": false, "strict": false, "stroke": true, "stroke_style": null, "style": {"background": "rgba(249, 249, 249, 1)", "ci_colors": [], "colors": ["#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5"], "dot_opacity": "1", "font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "foreground": "rgba(0, 0, 0, .87)", "foreground_strong": "rgba(0, 0, 0, 1)", "foreground_subtle": "rgba(0, 0, 0, .54)", "guide_stroke_color": "black", "guide_stroke_dasharray": "4,4", "label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "label_font_size": 10, "legend_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "legend_font_size": 14, "major_guide_stroke_color": "black", "major_guide_stroke_dasharray": "6,6", "major_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "major_label_font_size": 10, "no_data_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "no_data_font_size": 64, "opacity": ".7", "opacity_hover": ".8", "plot_background": "rgba(255, 255, 255, 1)", "stroke_opacity": ".8", "stroke_opacity_hover": ".9", "stroke_width": "1", "stroke_width_hover": "4", "title_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "title_font_size": 16, "tooltip_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "tooltip_font_size": 14, "transition": "150ms", "value_background": "rgba(229, 229, 229, 1)", "value_colors": [], "value_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_font_size": 16, "value_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_label_font_size": 10}, "title": "Speed in Microseconds (us)", "tooltip_border_radius": 0, "tooltip_fancy_mode": true, "truncate_label": 50, "truncate_legend": null, "width": 800, "x_label_rotation": 270, "x_labels": ["simple_tuple_d", "simple_set_d", "simple_list_e", "simple_tuple_e", "simple_set_e", "simple_dict_d", "simple_dict_e", "simple_list_d", "complex_homog_tuple_d", "complex_homog_set_d", "complex_heterog_set_d", "complex_heterog_tuple_d", "complex_homog_list_e", "complex_homog_list_d", "complex_homog_dict_d", "complex_homog_tuple_e", "complex_homog_set_e", "complex_heterog_dict_d", "complex_heterog_list_d", "complex_heterog_set_e", "complex_heterog_list_e", "complex_heterog_tuple_e", "complex_homog_dict_e", "simple_cls_d", "complex_heterog_dict_e", "simple_cls_e", "complex_cls_d", "state_cls_d", "complex_cls_e", "state_cls_e"], "x_labels_major": null, "x_labels_major_count": null, "x_labels_major_every": null, "x_title": "Trial", "xrange": null, "y_label_rotation": 0, "y_labels": null, "y_labels_major": null, "y_labels_major_count": null, "y_labels_major_every": null, "y_title": "Duration", "zero": 14, "legends": ["jsonpickle_benchmarks.py::simple_tuple_d - 17900 rounds", "jsonpickle_benchmarks.py::simple_set_d - 17556 rounds", "jsonpickle_benchmarks.py::simple_list_e - 16356 rounds", "jsonpickle_benchmarks.py::simple_tuple_e - 12546 rounds", "jsonpickle_benchmarks.py::simple_set_e - 14094 rounds", "jsonpickle_benchmarks.py::simple_dict_d - 10888 rounds", "jsonpickle_benchmarks.py::simple_dict_e - 7615 rounds", "jsonpickle_benchmarks.py::simple_list_d - 14743 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_d - 14018 rounds", "jsonpickle_benchmarks.py::complex_homog_set_d - 12033 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_d - 11789 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_d - 10634 rounds", "jsonpickle_benchmarks.py::complex_homog_list_e - 698 rounds", "jsonpickle_benchmarks.py::complex_homog_list_d - 10203 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_d - 10654 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_e - 10067 rounds", "jsonpickle_benchmarks.py::complex_homog_set_e - 9318 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_d - 8547 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_d - 9362 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_e - 8887 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_e - 7869 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_e - 6067 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_e - 7435 rounds", "jsonpickle_benchmarks.py::simple_cls_d - 6070 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_e - 7439 rounds", "jsonpickle_benchmarks.py::simple_cls_e - 6490 rounds", "jsonpickle_benchmarks.py::complex_cls_d - 4682 rounds", "jsonpickle_benchmarks.py::state_cls_d - 4265 rounds", "jsonpickle_benchmarks.py::complex_cls_e - 4047 rounds", "jsonpickle_benchmarks.py::state_cls_e - 3217 rounds"]}</script><script type="text/javascript">(function() { | |
5 | var $, get_translation, init, init_svg, matches, padding, r_translation, sibl, svg_ns, tooltip_timeout, xlink_ns; | |
6 | ||
7 | svg_ns = 'http://www.w3.org/2000/svg'; | |
8 | ||
9 | xlink_ns = 'http://www.w3.org/1999/xlink'; | |
10 | ||
11 | $ = function(sel, ctx) { | |
12 | if (ctx == null) { | |
13 | ctx = null; | |
14 | } | |
15 | ctx = ctx || document; | |
16 | return Array.prototype.slice.call(ctx.querySelectorAll(sel), 0).filter(function(e) { | |
17 | return e !== ctx; | |
18 | }); | |
19 | }; | |
20 | ||
21 | matches = function(el, selector) { | |
22 | return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector); | |
23 | }; | |
24 | ||
25 | sibl = function(el, match) { | |
26 | if (match == null) { | |
27 | match = null; | |
28 | } | |
29 | return Array.prototype.filter.call(el.parentElement.children, function(child) { | |
30 | return child !== el && (!match || matches(child, match)); | |
31 | }); | |
32 | }; | |
33 | ||
34 | Array.prototype.one = function() { | |
35 | return this.length > 0 && this[0] || {}; | |
36 | }; | |
37 | ||
38 | padding = 5; | |
39 | ||
40 | tooltip_timeout = null; | |
41 | ||
42 | r_translation = /translate\((\d+)[ ,]+(\d+)\)/; | |
43 | ||
44 | get_translation = function(el) { | |
45 | return (r_translation.exec(el.getAttribute('transform')) || []).slice(1).map(function(x) { | |
46 | return +x; | |
47 | }); | |
48 | }; | |
49 | ||
50 | init = function(ctx) { | |
51 | var bbox, box, config, el, graph, inner_svg, num, parent, tooltip, tooltip_el, tt, uid, untooltip, xconvert, yconvert, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; | |
52 | if ($('svg', ctx).length) { | |
53 | inner_svg = $('svg', ctx).one(); | |
54 | parent = inner_svg.parentElement; | |
55 | box = inner_svg.viewBox.baseVal; | |
56 | bbox = parent.getBBox(); | |
57 | xconvert = function(x) { | |
58 | return ((x - box.x) / box.width) * bbox.width; | |
59 | }; | |
60 | yconvert = function(y) { | |
61 | return ((y - box.y) / box.height) * bbox.height; | |
62 | }; | |
63 | } else { | |
64 | xconvert = yconvert = function(x) { | |
65 | return x; | |
66 | }; | |
67 | } | |
68 | if (((_ref = window.pygal) != null ? _ref.config : void 0) != null) { | |
69 | if (window.pygal.config.no_prefix != null) { | |
70 | config = window.pygal.config; | |
71 | } else { | |
72 | uid = ctx.id.replace('chart-', ''); | |
73 | config = window.pygal.config[uid]; | |
74 | } | |
75 | } else { | |
76 | config = window.config; | |
77 | } | |
78 | tooltip_el = null; | |
79 | graph = $('.graph').one(); | |
80 | tt = $('.tooltip', ctx).one(); | |
81 | _ref1 = $('.reactive', ctx); | |
82 | for (_i = 0, _len = _ref1.length; _i < _len; _i++) { | |
83 | el = _ref1[_i]; | |
84 | el.addEventListener('mouseenter', (function(el) { | |
85 | return function() { | |
86 | return el.classList.add('active'); | |
87 | }; | |
88 | })(el)); | |
89 | el.addEventListener('mouseleave', (function(el) { | |
90 | return function() { | |
91 | return el.classList.remove('active'); | |
92 | }; | |
93 | })(el)); | |
94 | } | |
95 | _ref2 = $('.activate-serie', ctx); | |
96 | for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { | |
97 | el = _ref2[_j]; | |
98 | num = el.id.replace('activate-serie-', ''); | |
99 | el.addEventListener('mouseenter', (function(num) { | |
100 | return function() { | |
101 | var re, _k, _len2, _ref3, _results; | |
102 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
103 | _results = []; | |
104 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
105 | re = _ref3[_k]; | |
106 | _results.push(re.classList.add('active')); | |
107 | } | |
108 | return _results; | |
109 | }; | |
110 | })(num)); | |
111 | el.addEventListener('mouseleave', (function(num) { | |
112 | return function() { | |
113 | var re, _k, _len2, _ref3, _results; | |
114 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
115 | _results = []; | |
116 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
117 | re = _ref3[_k]; | |
118 | _results.push(re.classList.remove('active')); | |
119 | } | |
120 | return _results; | |
121 | }; | |
122 | })(num)); | |
123 | el.addEventListener('click', (function(el, num) { | |
124 | return function() { | |
125 | var ov, re, rect, show, _k, _l, _len2, _len3, _ref3, _ref4, _results; | |
126 | rect = $('rect', el).one(); | |
127 | show = rect.style.fill !== ''; | |
128 | rect.style.fill = show ? '' : 'transparent'; | |
129 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
130 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
131 | re = _ref3[_k]; | |
132 | re.style.display = show ? '' : 'none'; | |
133 | } | |
134 | _ref4 = $('.text-overlay .serie-' + num, ctx); | |
135 | _results = []; | |
136 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
137 | ov = _ref4[_l]; | |
138 | _results.push(ov.style.display = show ? '' : 'none'); | |
139 | } | |
140 | return _results; | |
141 | }; | |
142 | })(el, num)); | |
143 | } | |
144 | _ref3 = $('.tooltip-trigger', ctx); | |
145 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
146 | el = _ref3[_k]; | |
147 | el.addEventListener('mouseenter', (function(el) { | |
148 | return function() { | |
149 | return tooltip_el = tooltip(el); | |
150 | }; | |
151 | })(el)); | |
152 | } | |
153 | tt.addEventListener('mouseenter', function() { | |
154 | return tooltip_el != null ? tooltip_el.classList.add('active') : void 0; | |
155 | }); | |
156 | tt.addEventListener('mouseleave', function() { | |
157 | return tooltip_el != null ? tooltip_el.classList.remove('active') : void 0; | |
158 | }); | |
159 | ctx.addEventListener('mouseleave', function() { | |
160 | if (tooltip_timeout) { | |
161 | clearTimeout(tooltip_timeout); | |
162 | } | |
163 | return untooltip(0); | |
164 | }); | |
165 | graph.addEventListener('mousemove', function(el) { | |
166 | if (tooltip_timeout) { | |
167 | return; | |
168 | } | |
169 | if (!matches(el.target, '.background')) { | |
170 | return; | |
171 | } | |
172 | return untooltip(1000); | |
173 | }); | |
174 | tooltip = function(el) { | |
175 | var a, baseline, cls, current_x, current_y, dy, h, i, key, keys, label, legend, name, plot_x, plot_y, rect, serie_index, subval, text, text_group, texts, traversal, value, w, x, x_elt, x_label, xlink, y, y_elt, _l, _len3, _len4, _len5, _m, _n, _ref4, _ref5, _ref6, _ref7, _ref8; | |
176 | clearTimeout(tooltip_timeout); | |
177 | tooltip_timeout = null; | |
178 | tt.style.opacity = 1; | |
179 | tt.style.display = ''; | |
180 | text_group = $('g.text', tt).one(); | |
181 | rect = $('rect', tt).one(); | |
182 | text_group.innerHTML = ''; | |
183 | label = sibl(el, '.label').one().textContent; | |
184 | x_label = sibl(el, '.x_label').one().textContent; | |
185 | value = sibl(el, '.value').one().textContent; | |
186 | xlink = sibl(el, '.xlink').one().textContent; | |
187 | serie_index = null; | |
188 | parent = el; | |
189 | traversal = []; | |
190 | while (parent) { | |
191 | traversal.push(parent); | |
192 | if (parent.classList.contains('series')) { | |
193 | break; | |
194 | } | |
195 | parent = parent.parentElement; | |
196 | } | |
197 | if (parent) { | |
198 | _ref4 = parent.classList; | |
199 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
200 | cls = _ref4[_l]; | |
201 | if (cls.indexOf('serie-') === 0) { | |
202 | serie_index = +cls.replace('serie-', ''); | |
203 | break; | |
204 | } | |
205 | } | |
206 | } | |
207 | legend = null; | |
208 | if (serie_index !== null) { | |
209 | legend = config.legends[serie_index]; | |
210 | } | |
211 | dy = 0; | |
212 | keys = [[label, 'label']]; | |
213 | _ref5 = value.split('\n'); | |
214 | for (i = _m = 0, _len4 = _ref5.length; _m < _len4; i = ++_m) { | |
215 | subval = _ref5[i]; | |
216 | keys.push([subval, 'value-' + i]); | |
217 | } | |
218 | if (config.tooltip_fancy_mode) { | |
219 | keys.push([xlink, 'xlink']); | |
220 | keys.unshift([x_label, 'x_label']); | |
221 | keys.unshift([legend, 'legend']); | |
222 | } | |
223 | texts = {}; | |
224 | for (_n = 0, _len5 = keys.length; _n < _len5; _n++) { | |
225 | _ref6 = keys[_n], key = _ref6[0], name = _ref6[1]; | |
226 | if (key) { | |
227 | text = document.createElementNS(svg_ns, 'text'); | |
228 | text.textContent = key; | |
229 | text.setAttribute('x', padding); | |
230 | text.setAttribute('dy', dy); | |
231 | text.classList.add(name.indexOf('value') === 0 ? 'value' : name); | |
232 | if (name.indexOf('value') === 0 && config.tooltip_fancy_mode) { | |
233 | text.classList.add('color-' + serie_index); | |
234 | } | |
235 | if (name === 'xlink') { | |
236 | a = document.createElementNS(svg_ns, 'a'); | |
237 | a.setAttributeNS(xlink_ns, 'href', key); | |
238 | a.textContent = void 0; | |
239 | a.appendChild(text); | |
240 | text.textContent = 'Link >'; | |
241 | text_group.appendChild(a); | |
242 | } else { | |
243 | text_group.appendChild(text); | |
244 | } | |
245 | dy += text.getBBox().height + padding / 2; | |
246 | baseline = padding; | |
247 | if (text.style.dominantBaseline !== void 0) { | |
248 | text.style.dominantBaseline = 'text-before-edge'; | |
249 | } else { | |
250 | baseline += text.getBBox().height * .8; | |
251 | } | |
252 | text.setAttribute('y', baseline); | |
253 | texts[name] = text; | |
254 | } | |
255 | } | |
256 | w = text_group.getBBox().width + 2 * padding; | |
257 | h = text_group.getBBox().height + 2 * padding; | |
258 | rect.setAttribute('width', w); | |
259 | rect.setAttribute('height', h); | |
260 | if (texts.value) { | |
261 | texts.value.setAttribute('dx', (w - texts.value.getBBox().width) / 2 - padding); | |
262 | } | |
263 | if (texts.x_label) { | |
264 | texts.x_label.setAttribute('dx', w - texts.x_label.getBBox().width - 2 * padding); | |
265 | } | |
266 | if (texts.xlink) { | |
267 | texts.xlink.setAttribute('dx', w - texts.xlink.getBBox().width - 2 * padding); | |
268 | } | |
269 | x_elt = sibl(el, '.x').one(); | |
270 | y_elt = sibl(el, '.y').one(); | |
271 | x = parseInt(x_elt.textContent); | |
272 | if (x_elt.classList.contains('centered')) { | |
273 | x -= w / 2; | |
274 | } else if (x_elt.classList.contains('left')) { | |
275 | x -= w; | |
276 | } else if (x_elt.classList.contains('auto')) { | |
277 | x = xconvert(el.getBBox().x + el.getBBox().width / 2) - w / 2; | |
278 | } | |
279 | y = parseInt(y_elt.textContent); | |
280 | if (y_elt.classList.contains('centered')) { | |
281 | y -= h / 2; | |
282 | } else if (y_elt.classList.contains('top')) { | |
283 | y -= h; | |
284 | } else if (y_elt.classList.contains('auto')) { | |
285 | y = yconvert(el.getBBox().y + el.getBBox().height / 2) - h / 2; | |
286 | } | |
287 | _ref7 = get_translation(tt.parentElement), plot_x = _ref7[0], plot_y = _ref7[1]; | |
288 | if (x + w + plot_x > config.width) { | |
289 | x = config.width - w - plot_x; | |
290 | } | |
291 | if (y + h + plot_y > config.height) { | |
292 | y = config.height - h - plot_y; | |
293 | } | |
294 | if (x + plot_x < 0) { | |
295 | x = -plot_x; | |
296 | } | |
297 | if (y + plot_y < 0) { | |
298 | y = -plot_y; | |
299 | } | |
300 | _ref8 = get_translation(tt), current_x = _ref8[0], current_y = _ref8[1]; | |
301 | if (current_x === x && current_y === y) { | |
302 | return el; | |
303 | } | |
304 | tt.setAttribute('transform', "translate(" + x + " " + y + ")"); | |
305 | return el; | |
306 | }; | |
307 | return untooltip = function(ms) { | |
308 | return tooltip_timeout = setTimeout(function() { | |
309 | tt.style.display = 'none'; | |
310 | tt.style.opacity = 0; | |
311 | if (tooltip_el != null) { | |
312 | tooltip_el.classList.remove('active'); | |
313 | } | |
314 | return tooltip_timeout = null; | |
315 | }, ms); | |
316 | }; | |
317 | }; | |
318 | ||
319 | init_svg = function() { | |
320 | var chart, charts, _i, _len, _results; | |
321 | charts = $('.pygal-chart'); | |
322 | if (charts.length) { | |
323 | _results = []; | |
324 | for (_i = 0, _len = charts.length; _i < _len; _i++) { | |
325 | chart = charts[_i]; | |
326 | _results.push(init(chart)); | |
327 | } | |
328 | return _results; | |
329 | } | |
330 | }; | |
331 | ||
332 | if (document.readyState !== 'loading') { | |
333 | init_svg(); | |
334 | } else { | |
335 | document.addEventListener('DOMContentLoaded', function() { | |
336 | return init_svg(); | |
337 | }); | |
338 | } | |
339 | ||
340 | window.pygal = window.pygal || {}; | |
341 | ||
342 | window.pygal.init = init; | |
343 | ||
344 | window.pygal.init_svg = init_svg; | |
345 | ||
346 | }).call(this); | |
347 | </script></defs><title>Speed in Microseconds (us)</title><g class="graph custombox-graph vertical"><rect x="0" y="0" width="800" height="600" class="background" /><g transform="translate(74, 46)" class="plot"><rect x="0" y="0" width="706.0" height="360.0" class="background" /><g class="axis y always_show"><path d="M0.000000 360.000000 h706.000000" class="line" /><g class="guides"><path d="M0.000000 348.235611 h706.000000" class="guide line" /><text x="-5" y="351.73561054330287" class="">16</text><title>16</title></g><g class="guides"><path d="M0.000000 328.870360 h706.000000" class="guide line" /><text x="-5" y="332.37036040882197" class="">24</text><title>24</title></g><g class="guides"><path d="M0.000000 309.505110 h706.000000" class="guide line" /><text x="-5" y="313.00511027434106" class="">32</text><title>32</title></g><g class="guides"><path d="M0.000000 290.139860 h706.000000" class="guide line" /><text x="-5" y="293.63986013986016" class="">40</text><title>40</title></g><g class="guides"><path d="M0.000000 270.774610 h706.000000" class="guide line" /><text x="-5" y="274.27461000537926" class="">48</text><title>48</title></g><g class="guides"><path d="M0.000000 251.409360 h706.000000" class="guide line" /><text x="-5" y="254.90935987089836" class="">56</text><title>56</title></g><g class="guides"><path d="M0.000000 232.044110 h706.000000" class="guide line" /><text x="-5" y="235.54410973641745" class="">64</text><title>64</title></g><g class="guides"><path d="M0.000000 212.678860 h706.000000" class="guide line" /><text x="-5" y="216.17885960193655" class="">72</text><title>72</title></g><g class="guides"><path d="M0.000000 193.313609 h706.000000" class="guide line" /><text x="-5" y="196.81360946745565" class="">80</text><title>80</title></g><g class="guides"><path d="M0.000000 173.948359 h706.000000" class="guide line" /><text x="-5" y="177.44835933297477" class="">88</text><title>88</title></g><g class="guides"><path d="M0.000000 154.583109 h706.000000" class="guide line" /><text x="-5" y="158.08310919849387" class="">96</text><title>96</title></g><g class="guides"><path d="M0.000000 135.217859 h706.000000" class="guide line" /><text x="-5" y="138.71785906401297" class="">104</text><title>104</title></g><g class="guides"><path d="M0.000000 115.852609 h706.000000" class="guide line" /><text x="-5" y="119.35260892953207" class="">112</text><title>112</title></g><g class="guides"><path d="M0.000000 96.487359 h706.000000" class="guide line" /><text x="-5" y="99.98735879505114" class="">120</text><title>120</title></g><g class="guides"><path d="M0.000000 77.122109 h706.000000" class="guide line" /><text x="-5" y="80.62210866057023" class="">128</text><title>128</title></g><g class="guides"><path d="M0.000000 57.756859 h706.000000" class="guide line" /><text x="-5" y="61.25685852608939" class="">136</text><title>136</title></g><g class="guides"><path d="M0.000000 38.391608 h706.000000" class="guide line" /><text x="-5" y="41.89160839160843" class="">144</text><title>144</title></g><g class="guides"><path d="M0.000000 19.026358 h706.000000" class="guide line" /><text x="-5" y="22.526358257127526" class="">152</text><title>152</title></g></g><g class="axis x"><path d="M0.000000 0.000000 v360.000000" class="line" /><g class="guides"><path d="M24.891026 0.000000 v360.000000" class="guide line" /><text x="24.89102564102564" y="375.0" class="backwards" transform="rotate(270 24.891026 375.000000)">simple_tuple_d</text></g><g class="guides"><path d="M47.519231 0.000000 v360.000000" class="guide line" /><text x="47.51923076923077" y="375.0" class="backwards" transform="rotate(270 47.519231 375.000000)">simple_set_d</text></g><g class="guides"><path d="M70.147436 0.000000 v360.000000" class="guide line" /><text x="70.1474358974359" y="375.0" class="backwards" transform="rotate(270 70.147436 375.000000)">simple_list_e</text></g><g class="guides"><path d="M92.775641 0.000000 v360.000000" class="guide line" /><text x="92.77564102564102" y="375.0" class="backwards" transform="rotate(270 92.775641 375.000000)">simple_tuple_e</text></g><g class="guides"><path d="M115.403846 0.000000 v360.000000" class="guide line" /><text x="115.40384615384615" y="375.0" class="backwards" transform="rotate(270 115.403846 375.000000)">simple_set_e</text></g><g class="guides"><path d="M138.032051 0.000000 v360.000000" class="guide line" /><text x="138.03205128205127" y="375.0" class="backwards" transform="rotate(270 138.032051 375.000000)">simple_dict_d</text></g><g class="guides"><path d="M160.660256 0.000000 v360.000000" class="guide line" /><text x="160.6602564102564" y="375.0" class="backwards" transform="rotate(270 160.660256 375.000000)">simple_dict_e</text></g><g class="guides"><path d="M183.288462 0.000000 v360.000000" class="guide line" /><text x="183.28846153846155" y="375.0" class="backwards" transform="rotate(270 183.288462 375.000000)">simple_list_d</text></g><g class="guides"><path d="M205.916667 0.000000 v360.000000" class="guide line" /><text x="205.91666666666666" y="375.0" class="backwards" transform="rotate(270 205.916667 375.000000)">complex_homog_tuple_d</text></g><g class="guides"><path d="M228.544872 0.000000 v360.000000" class="guide line" /><text x="228.5448717948718" y="375.0" class="backwards" transform="rotate(270 228.544872 375.000000)">complex_homog_set_d</text></g><g class="guides"><path d="M251.173077 0.000000 v360.000000" class="guide line" /><text x="251.17307692307688" y="375.0" class="backwards" transform="rotate(270 251.173077 375.000000)">complex_heterog_set_d</text></g><g class="guides"><path d="M273.801282 0.000000 v360.000000" class="guide line" /><text x="273.8012820512821" y="375.0" class="backwards" transform="rotate(270 273.801282 375.000000)">complex_heterog_tuple_d</text></g><g class="guides"><path d="M296.429487 0.000000 v360.000000" class="guide line" /><text x="296.4294871794872" y="375.0" class="backwards" transform="rotate(270 296.429487 375.000000)">complex_homog_list_e</text></g><g class="guides"><path d="M319.057692 0.000000 v360.000000" class="guide line" /><text x="319.05769230769226" y="375.0" class="backwards" transform="rotate(270 319.057692 375.000000)">complex_homog_list_d</text></g><g class="guides"><path d="M341.685897 0.000000 v360.000000" class="guide line" /><text x="341.6858974358974" y="375.0" class="backwards" transform="rotate(270 341.685897 375.000000)">complex_homog_dict_d</text></g><g class="guides"><path d="M364.314103 0.000000 v360.000000" class="guide line" /><text x="364.3141025641026" y="375.0" class="backwards" transform="rotate(270 364.314103 375.000000)">complex_homog_tuple_e</text></g><g class="guides"><path d="M386.942308 0.000000 v360.000000" class="guide line" /><text x="386.9423076923077" y="375.0" class="backwards" transform="rotate(270 386.942308 375.000000)">complex_homog_set_e</text></g><g class="guides"><path d="M409.570513 0.000000 v360.000000" class="guide line" /><text x="409.5705128205129" y="375.0" class="backwards" transform="rotate(270 409.570513 375.000000)">complex_heterog_dict_d</text></g><g class="guides"><path d="M432.198718 0.000000 v360.000000" class="guide line" /><text x="432.19871794871796" y="375.0" class="backwards" transform="rotate(270 432.198718 375.000000)">complex_heterog_list_d</text></g><g class="guides"><path d="M454.826923 0.000000 v360.000000" class="guide line" /><text x="454.8269230769231" y="375.0" class="backwards" transform="rotate(270 454.826923 375.000000)">complex_heterog_set_e</text></g><g class="guides"><path d="M477.455128 0.000000 v360.000000" class="guide line" /><text x="477.4551282051282" y="375.0" class="backwards" transform="rotate(270 477.455128 375.000000)">complex_heterog_list_e</text></g><g class="guides"><path d="M500.083333 0.000000 v360.000000" class="guide line" /><text x="500.08333333333337" y="375.0" class="backwards" transform="rotate(270 500.083333 375.000000)">complex_heterog_tuple_e</text></g><g class="guides"><path d="M522.711538 0.000000 v360.000000" class="guide line" /><text x="522.7115384615385" y="375.0" class="backwards" transform="rotate(270 522.711538 375.000000)">complex_homog_dict_e</text></g><g class="guides"><path d="M545.339744 0.000000 v360.000000" class="guide line" /><text x="545.3397435897435" y="375.0" class="backwards" transform="rotate(270 545.339744 375.000000)">simple_cls_d</text></g><g class="guides"><path d="M567.967949 0.000000 v360.000000" class="guide line" /><text x="567.9679487179487" y="375.0" class="backwards" transform="rotate(270 567.967949 375.000000)">complex_heterog_dict_e</text></g><g class="guides"><path d="M590.596154 0.000000 v360.000000" class="guide line" /><text x="590.5961538461538" y="375.0" class="backwards" transform="rotate(270 590.596154 375.000000)">simple_cls_e</text></g><g class="guides"><path d="M613.224359 0.000000 v360.000000" class="guide line" /><text x="613.224358974359" y="375.0" class="backwards" transform="rotate(270 613.224359 375.000000)">complex_cls_d</text></g><g class="guides"><path d="M635.852564 0.000000 v360.000000" class="guide line" /><text x="635.8525641025641" y="375.0" class="backwards" transform="rotate(270 635.852564 375.000000)">state_cls_d</text></g><g class="guides"><path d="M658.480769 0.000000 v360.000000" class="guide line" /><text x="658.4807692307692" y="375.0" class="backwards" transform="rotate(270 658.480769 375.000000)">complex_cls_e</text></g><g class="guides"><path d="M681.108974 0.000000 v360.000000" class="guide line" /><text x="681.1089743589743" y="375.0" class="backwards" transform="rotate(270 681.108974 375.000000)">state_cls_e</text></g></g><g class="series serie-0 color-0"><g class="boxes"><g class="box"><path stroke-width="3" d="M19.912821 351.275962 L29.869231 351.275962" class="reactive tooltip-trigger" /><path stroke-width="3" d="M14.934615 350.387574 L34.847436 350.387574" class="reactive tooltip-trigger" /><path stroke-width="3" d="M19.912821 349.484674 L29.869231 349.484674" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 351.275962 L24.891026 350.605433" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 349.484674 L24.891026 350.157607" class="reactive tooltip-trigger" /><rect x="14.934615384615384" y="350.1576068020221" height="0.44782658055225966" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="351.47686922913465" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="193.76142332748918" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 14.6610 | |
348 | Q1-1.5IQR: 14.7440 | |
349 | Q1: 15.0210 | |
350 | Median: 15.1110 | |
351 | Q3: 15.2060 | |
352 | Q3+1.5IQR: 15.4840 | |
353 | Max: 79.8150</desc><desc class="x centered">24.891025641025642</desc><desc class="y centered">350.382250134253</desc><desc class="x_label" /></g></g></g><g class="series serie-1 color-1"><g class="boxes"><g class="box"><path stroke-width="3" d="M42.541026 350.360944 L52.497436 350.360944" class="reactive tooltip-trigger" /><path stroke-width="3" d="M37.562821 349.499195 L57.475641 349.499195" class="reactive tooltip-trigger" /><path stroke-width="3" d="M42.541026 348.608394 L52.497436 348.608394" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 350.360944 L47.519231 349.704954" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 348.608394 L47.519231 349.266815" class="reactive tooltip-trigger" /><rect x="37.562820512820515" y="349.2668147164188" height="0.43813965473452754" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="350.66352851859193" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="182.07934304319113" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 14.9970 | |
354 | Q1-1.5IQR: 15.1220 | |
355 | Q1: 15.3930 | |
356 | Median: 15.4780 | |
357 | Q3: 15.5740 | |
358 | Q3+1.5IQR: 15.8460 | |
359 | Max: 84.6410</desc><desc class="x centered">47.519230769230774</desc><desc class="y centered">349.4880605795766</desc><desc class="x_label" /></g></g></g><g class="series serie-2 color-2"><g class="boxes"><g class="box"><path stroke-width="3" d="M65.169231 349.961535 L75.125641 349.961535" class="reactive tooltip-trigger" /><path stroke-width="3" d="M60.191026 348.739106 L80.103846 348.739106" class="reactive tooltip-trigger" /><path stroke-width="3" d="M65.169231 347.499735 L75.125641 347.499735" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 349.961535 L70.147436 349.039269" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 347.499735 L70.147436 348.424422" class="reactive tooltip-trigger" /><rect x="60.19102564102564" y="348.4244220347192" height="0.6148467942418279" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="350.2447539091966" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="199.26116665419207" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 15.1700 | |
360 | Q1-1.5IQR: 15.2870 | |
361 | Q1: 15.6680 | |
362 | Median: 15.7920 | |
363 | Q3: 15.9220 | |
364 | Q3+1.5IQR: 16.3040 | |
365 | Max: 77.5430</desc><desc class="x centered">70.1474358974359</desc><desc class="y centered">348.7328132437923</desc><desc class="x_label" /></g></g></g><g class="series serie-3 color-3"><g class="boxes"><g class="box"><path stroke-width="3" d="M87.797436 348.538191 L97.753846 348.538191" class="reactive tooltip-trigger" /><path stroke-width="3" d="M82.819231 347.335127 L102.732051 347.335127" class="reactive tooltip-trigger" /><path stroke-width="3" d="M87.797436 346.081234 L97.753846 346.081234" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 348.538191 L92.775641 347.620759" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 346.081234 L92.775641 347.005921" class="reactive tooltip-trigger" /><rect x="82.81923076923077" y="347.00592145575246" height="0.6148379879456343" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="348.8867613914056" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="314.83055077596896" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 15.7310 | |
366 | Q1-1.5IQR: 15.8750 | |
367 | Q1: 16.2540 | |
368 | Median: 16.3720 | |
369 | Q3: 16.5080 | |
370 | Q3+1.5IQR: 16.8900 | |
371 | Max: 29.8000</desc><desc class="x centered">92.77564102564102</desc><desc class="y centered">347.3162465274706</desc><desc class="x_label" /></g></g></g><g class="series serie-4 color-4"><g class="boxes"><g class="box"><path stroke-width="3" d="M110.425641 348.402635 L120.382051 348.402635" class="reactive tooltip-trigger" /><path stroke-width="3" d="M105.447436 347.279445 L125.360256 347.279445" class="reactive tooltip-trigger" /><path stroke-width="3" d="M110.425641 346.107855 L120.382051 346.107855" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 348.402635 L115.403846 347.543308" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 346.107855 L115.403846 346.969613" class="reactive tooltip-trigger" /><rect x="105.4474358974359" y="346.96961309652846" height="0.5736949721089672" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="348.58902051695435" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="287.7216272310626" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 15.8540 | |
372 | Q1-1.5IQR: 15.9310 | |
373 | Q1: 16.2860 | |
374 | Median: 16.3950 | |
375 | Q3: 16.5230 | |
376 | Q3+1.5IQR: 16.8790 | |
377 | Max: 40.9990</desc><desc class="x centered">115.40384615384615</desc><desc class="y centered">347.26057136164815</desc><desc class="x_label" /></g></g></g><g class="series serie-5 color-5"><g class="boxes"><g class="box"><path stroke-width="3" d="M133.053846 345.831901 L143.010256 345.831901" class="reactive tooltip-trigger" /><path stroke-width="3" d="M128.075641 343.948631 L147.988462 343.948631" class="reactive tooltip-trigger" /><path stroke-width="3" d="M133.053846 341.820871 L143.010256 341.820871" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 345.831901 L138.032051 344.401292" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 341.820871 L138.032051 343.370092" class="reactive tooltip-trigger" /><rect x="128.07564102564103" y="343.3700923634104" height="1.0311996721827654" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="345.831901271832" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="303.39779434962605" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.9930 | |
378 | Q1-1.5IQR: 16.9930 | |
379 | Q1: 17.5840 | |
380 | Median: 17.7710 | |
381 | Q3: 18.0100 | |
382 | Q3+1.5IQR: 18.6500 | |
383 | Max: 34.5230</desc><desc class="x centered">138.0320512820513</desc><desc class="y centered">343.87455751858914</desc><desc class="x_label" /></g></g></g><g class="series serie-6 color-6"><g class="boxes"><g class="box"><path stroke-width="3" d="M155.682051 345.171059 L165.638462 345.171059" class="reactive tooltip-trigger" /><path stroke-width="3" d="M150.703846 342.931953 L170.616667 342.931953" class="reactive tooltip-trigger" /><path stroke-width="3" d="M155.682051 339.850454 L165.638462 339.850454" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 345.171059 L160.660256 343.495961" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 339.850454 L160.660256 342.041152" class="reactive tooltip-trigger" /><rect x="150.70384615384614" y="342.04115181677633" height="1.4548089381907516" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="345.17105919254857" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="286.3200611596844" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 17.2660 | |
384 | Q1-1.5IQR: 17.2660 | |
385 | Q1: 17.9580 | |
386 | Median: 18.1910 | |
387 | Q3: 18.5590 | |
388 | Q3+1.5IQR: 19.4640 | |
389 | Max: 41.5780</desc><desc class="x centered">160.6602564102564</desc><desc class="y centered">342.69811560321426</desc><desc class="x_label" /></g></g></g><g class="series serie-7 color-7"><g class="boxes"><g class="box"><path stroke-width="3" d="M178.310256 343.924422 L188.266667 343.924422" class="reactive tooltip-trigger" /><path stroke-width="3" d="M173.332051 342.786719 L193.244872 342.786719" class="reactive tooltip-trigger" /><path stroke-width="3" d="M178.310256 341.593334 L188.266667 341.593334" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 343.924422 L183.288462 343.060252" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 341.593334 L183.288462 342.474448" class="reactive tooltip-trigger" /><rect x="173.33205128205125" y="342.47444800860205" height="0.5858036293811324" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="344.47875221694994" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="148.6452444163595" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 17.5520 | |
390 | Q1-1.5IQR: 17.7810 | |
391 | Q1: 18.1380 | |
392 | Median: 18.2510 | |
393 | Q3: 18.3800 | |
394 | Q3+1.5IQR: 18.7440 | |
395 | Max: 98.4530</desc><desc class="x centered">183.28846153846152</desc><desc class="y centered">342.76783505021314</desc><desc class="x_label" /></g></g></g><g class="series serie-8 color-8"><g class="boxes"><g class="box"><path stroke-width="3" d="M200.938462 322.039262 L210.894872 322.039262" class="reactive tooltip-trigger" /><path stroke-width="3" d="M195.960256 320.819255 L215.873077 320.819255" class="reactive tooltip-trigger" /><path stroke-width="3" d="M200.938462 319.555675 L210.894872 319.555675" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 322.039262 L205.916667 321.124261" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 319.555675 L205.916667 320.497306" class="reactive tooltip-trigger" /><rect x="195.9602564102564" y="320.4973055100652" height="0.6269554515139362" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="322.458044971122" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="125.03415530237399" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 26.6490 | |
396 | Q1-1.5IQR: 26.8220 | |
397 | Q1: 27.2000 | |
398 | Median: 27.3260 | |
399 | Q3: 27.4590 | |
400 | Q3+1.5IQR: 27.8480 | |
401 | Max: 108.2070</desc><desc class="x centered">205.91666666666666</desc><desc class="y centered">320.8071515192701</desc><desc class="x_label" /></g></g></g><g class="series serie-9 color-9"><g class="boxes"><g class="box"><path stroke-width="3" d="M223.566667 320.180200 L233.523077 320.180200" class="reactive tooltip-trigger" /><path stroke-width="3" d="M218.588462 318.747177 L238.501282 318.747177" class="reactive tooltip-trigger" /><path stroke-width="3" d="M223.566667 317.277838 L233.523077 317.277838" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 320.180200 L228.544872 319.095748" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 317.277838 L228.544872 318.369552" class="reactive tooltip-trigger" /><rect x="218.58846153846153" y="318.36955244004093" height="0.7261958049422219" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="320.8386199381037" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="165.27272048799827" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 27.3180 | |
402 | Q1-1.5IQR: 27.5900 | |
403 | Q1: 28.0380 | |
404 | Median: 28.1820 | |
405 | Q3: 28.3380 | |
406 | Q3+1.5IQR: 28.7890 | |
407 | Max: 91.5840</desc><desc class="x centered">228.5448717948718</desc><desc class="y centered">318.7341031612273</desc><desc class="x_label" /></g></g></g><g class="series serie-10 color-10"><g class="boxes"><g class="box"><path stroke-width="3" d="M246.194872 318.149274 L256.151282 318.149274" class="reactive tooltip-trigger" /><path stroke-width="3" d="M241.216667 316.069931 L261.129487 316.069931" class="reactive tooltip-trigger" /><path stroke-width="3" d="M246.194872 314.097101 L256.151282 314.097101" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 318.149274 L251.173077 316.646048" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 314.097101 L251.173077 315.626948" class="reactive tooltip-trigger" /><rect x="241.21666666666664" y="315.62694817262684" height="1.0190998212067939" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="318.5172186162615" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="260.455352785692" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 28.2770 | |
408 | Q1-1.5IQR: 28.4290 | |
409 | Q1: 29.0500 | |
410 | Median: 29.2880 | |
411 | Q3: 29.4710 | |
412 | Q3+1.5IQR: 30.1030 | |
413 | Max: 52.2630</desc><desc class="x centered">251.1730769230769</desc><desc class="y centered">316.117860437957</desc><desc class="x_label" /></g></g></g><g class="series serie-11 color-11"><g class="boxes"><g class="box"><path stroke-width="3" d="M268.823077 299.720822 L278.779487 299.720822" class="reactive tooltip-trigger" /><path stroke-width="3" d="M263.844872 295.586337 L283.757692 295.586337" class="reactive tooltip-trigger" /><path stroke-width="3" d="M268.823077 291.379234 L278.779487 291.379234" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 299.720822 L273.801282 296.600593" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 291.379234 L273.801282 294.513985" class="reactive tooltip-trigger" /><rect x="263.84487179487184" y="294.5139851325831" height="2.086607852613554" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="300.4542810391788" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="232.00295830542507" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 35.7390 | |
414 | Q1-1.5IQR: 36.0420 | |
415 | Q1: 37.3310 | |
416 | Median: 37.7500 | |
417 | Q3: 38.1930 | |
418 | Q3+1.5IQR: 39.4880 | |
419 | Max: 64.0170</desc><desc class="x centered">273.8012820512821</desc><desc class="y centered">295.5601942560056</desc><desc class="x_label" /></g></g></g><g class="series serie-12 color-12"><g class="boxes"><g class="box"><path stroke-width="3" d="M291.451282 299.626419 L301.407692 299.626419" class="reactive tooltip-trigger" /><path stroke-width="3" d="M286.473077 295.809035 L306.385897 295.809035" class="reactive tooltip-trigger" /><path stroke-width="3" d="M291.451282 291.149275 L301.407692 291.149275" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 299.626419 L296.429487 296.973372" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 291.149275 L296.429487 294.714901" class="reactive tooltip-trigger" /><rect x="286.473076923077" y="294.71490078033844" height="2.2584715292119313" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="299.6264187462058" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="210.40586032560515" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 36.0810 | |
420 | Q1-1.5IQR: 36.0810 | |
421 | Q1: 37.1770 | |
422 | Median: 37.6580 | |
423 | Q3: 38.1100 | |
424 | Q3+1.5IQR: 39.5830 | |
425 | Max: 72.9390</desc><desc class="x centered">296.42948717948724</desc><desc class="y centered">295.65460039313604</desc><desc class="x_label" /></g></g></g><g class="series serie-13 color-13"><g class="boxes"><g class="box"><path stroke-width="3" d="M314.079487 298.779183 L324.035897 298.779183" class="reactive tooltip-trigger" /><path stroke-width="3" d="M309.101282 296.201183 L329.014103 296.201183" class="reactive tooltip-trigger" /><path stroke-width="3" d="M314.079487 293.531202 L324.035897 293.531202" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 298.779183 L319.057692 296.816030" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 293.531202 L319.057692 295.504645" class="reactive tooltip-trigger" /><rect x="309.1012820512821" y="295.5046450202188" height="1.3113851951635525" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="299.09386678993343" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="126.05808978019346" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 36.3010 | |
426 | Q1-1.5IQR: 36.4310 | |
427 | Q1: 37.2420 | |
428 | Median: 37.4960 | |
429 | Q3: 37.7837 | |
430 | Q3+1.5IQR: 38.5990 | |
431 | Max: 107.7840</desc><desc class="x centered">319.0576923076924</desc><desc class="y centered">296.16644874704707</desc><desc class="x_label" /></g></g></g><g class="series serie-14 color-14"><g class="boxes"><g class="box"><path stroke-width="3" d="M336.707692 297.297743 L346.664103 297.297743" class="reactive tooltip-trigger" /><path stroke-width="3" d="M331.729487 294.037115 L351.642308 294.037115" class="reactive tooltip-trigger" /><path stroke-width="3" d="M336.707692 290.423073 L346.664103 290.423073" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 297.297743 L341.685897 294.775418" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 290.423073 L341.685897 293.037389" class="reactive tooltip-trigger" /><rect x="331.7294871794872" y="293.0373894175988" height="1.7380282302116825" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="297.2977434237041" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="154.82516844879646" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 37.0430 | |
432 | Q1-1.5IQR: 37.0430 | |
433 | Q1: 38.0850 | |
434 | Median: 38.3900 | |
435 | Q3: 38.8030 | |
436 | Q3+1.5IQR: 39.8830 | |
437 | Max: 95.9000</desc><desc class="x centered">341.68589743589746</desc><desc class="y centered">293.9141477895811</desc><desc class="x_label" /></g></g></g><g class="series serie-15 color-15"><g class="boxes"><g class="box"><path stroke-width="3" d="M359.335897 295.816304 L369.292308 295.816304" class="reactive tooltip-trigger" /><path stroke-width="3" d="M354.357692 291.991659 L374.270513 291.991659" class="reactive tooltip-trigger" /><path stroke-width="3" d="M359.335897 288.036303 L369.292308 288.036303" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 295.816304 L364.314103 292.918777" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 288.036303 L364.314103 290.974990" class="reactive tooltip-trigger" /><rect x="354.35769230769233" y="290.9749900732333" height="1.943787340875815" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="295.9857373846587" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="194.93544351140963" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 37.5850 | |
438 | Q1-1.5IQR: 37.6550 | |
439 | Q1: 38.8520 | |
440 | Median: 39.2350 | |
441 | Q3: 39.6550 | |
442 | Q3+1.5IQR: 40.8690 | |
443 | Max: 79.3300</desc><desc class="x centered">364.3141025641026</desc><desc class="y centered">291.94760674058904</desc><desc class="x_label" /></g></g></g><g class="series serie-16 color-16"><g class="boxes"><g class="box"><path stroke-width="3" d="M381.964103 293.163258 L391.920513 293.163258" class="reactive tooltip-trigger" /><path stroke-width="3" d="M376.985897 289.292635 L396.898718 289.292635" class="reactive tooltip-trigger" /><path stroke-width="3" d="M381.964103 285.259818 L391.920513 285.259818" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 293.163258 L386.942308 290.241531" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 285.259818 L386.942308 288.251749" class="reactive tooltip-trigger" /><rect x="376.98589743589747" y="288.25174864958433" height="1.9897826259175417" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="293.7805263348517" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="179.7821326170046" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 38.4960 | |
444 | Q1-1.5IQR: 38.7510 | |
445 | Q1: 39.9580 | |
446 | Median: 40.3500 | |
447 | Q3: 40.7800 | |
448 | Q3+1.5IQR: 42.0160 | |
449 | Max: 85.5900</desc><desc class="x centered">386.94230769230774</desc><desc class="y centered">289.24179826089346</desc><desc class="x_label" /></g></g></g><g class="series serie-17 color-17"><g class="boxes"><g class="box"><path stroke-width="3" d="M404.592308 292.369282 L414.548718 292.369282" class="reactive tooltip-trigger" /><path stroke-width="3" d="M399.614103 287.670788 L419.526923 287.670788" class="reactive tooltip-trigger" /><path stroke-width="3" d="M404.592308 282.621302 L414.548718 282.621302" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 292.369282 L409.570513 288.837552" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 282.621302 L409.570513 286.351535" class="reactive tooltip-trigger" /><rect x="399.6141025641026" y="286.3515348622957" height="2.4860174166697107" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="292.93329899653946" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="107.8305537208756" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 38.8460 | |
450 | Q1-1.5IQR: 39.0790 | |
451 | Q1: 40.5380 | |
452 | Median: 41.0200 | |
453 | Q3: 41.5650 | |
454 | Q3+1.5IQR: 43.1060 | |
455 | Max: 115.3140</desc><desc class="x centered">409.5705128205129</desc><desc class="y centered">287.57009200860745</desc><desc class="x_label" /></g></g></g><g class="series serie-18 color-18"><g class="boxes"><g class="box"><path stroke-width="3" d="M427.220513 291.236414 L437.176923 291.236414" class="reactive tooltip-trigger" /><path stroke-width="3" d="M422.242308 286.398737 L442.155128 286.398737" class="reactive tooltip-trigger" /><path stroke-width="3" d="M427.220513 281.440026 L437.176923 281.440026" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 291.236414 L432.198718 287.576385" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 281.440026 L432.198718 285.129106" class="reactive tooltip-trigger" /><rect x="422.24230769230775" y="285.1291064681754" height="2.4472785196950895" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="291.52205480563975" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="153.3800464364234" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 39.4290 | |
456 | Q1-1.5IQR: 39.5470 | |
457 | Q1: 41.0590 | |
458 | Median: 41.5455 | |
459 | Q3: 42.0700 | |
460 | Q3+1.5IQR: 43.5940 | |
461 | Max: 96.4970</desc><desc class="x centered">432.198717948718</desc><desc class="y centered">286.35613351017025</desc><desc class="x_label" /></g></g></g><g class="series serie-19 color-19"><g class="boxes"><g class="box"><path stroke-width="3" d="M449.848718 283.763849 L459.805128 283.763849" class="reactive tooltip-trigger" /><path stroke-width="3" d="M444.870513 280.033616 L464.783333 280.033616" class="reactive tooltip-trigger" /><path stroke-width="3" d="M449.848718 276.225923 L459.805128 276.225923" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 283.763849 L454.826923 280.951047" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 276.225923 L454.826923 279.070199" class="reactive tooltip-trigger" /><rect x="444.87051282051283" y="279.07019855809006" height="1.8808487419494213" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="284.3738520873541" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="151.81871653942275" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 42.3820 | |
462 | Q1-1.5IQR: 42.6340 | |
463 | Q1: 43.7960 | |
464 | Median: 44.1750 | |
465 | Q3: 44.5730 | |
466 | Q3+1.5IQR: 45.7480 | |
467 | Max: 97.1420</desc><desc class="x centered">454.8269230769231</desc><desc class="y centered">280.00892683641706</desc><desc class="x_label" /></g></g></g><g class="series serie-20 color-20"><g class="boxes"><g class="box"><path stroke-width="3" d="M472.476923 267.995700 L482.433333 267.995700" class="reactive tooltip-trigger" /><path stroke-width="3" d="M467.498718 262.568582 L487.411538 262.568582" class="reactive tooltip-trigger" /><path stroke-width="3" d="M472.476923 257.151160 L482.433333 257.151160" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 267.995700 L477.455128 263.936865" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 257.151160 L477.455128 261.225120" class="reactive tooltip-trigger" /><rect x="467.49871794871797" y="261.22511994264744" height="2.7117448039625742" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="268.8937571536371" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="70.78967797285878" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 48.7770 | |
468 | Q1-1.5IQR: 49.1480 | |
469 | Q1: 50.8247 | |
470 | Median: 51.3900 | |
471 | Q3: 51.9450 | |
472 | Q3+1.5IQR: 53.6280 | |
473 | Max: 130.6160</desc><desc class="x centered">477.45512820512823</desc><desc class="y centered">262.57548532730135</desc><desc class="x_label" /></g></g></g><g class="series serie-21 color-21"><g class="boxes"><g class="box"><path stroke-width="3" d="M495.105128 266.838623 L505.061538 266.838623" class="reactive tooltip-trigger" /><path stroke-width="3" d="M490.126923 261.597899 L510.039744 261.597899" class="reactive tooltip-trigger" /><path stroke-width="3" d="M495.105128 256.282146 L505.061538 256.282146" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 266.838623 L500.083333 262.887506" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 256.282146 L500.083333 260.252015" class="reactive tooltip-trigger" /><rect x="490.1269230769231" y="260.2520154064823" height="2.635491085184867" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="267.581768727184" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="187.59602087748257" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 49.3190 | |
474 | Q1-1.5IQR: 49.6260 | |
475 | Q1: 51.2583 | |
476 | Median: 51.7910 | |
477 | Q3: 52.3470 | |
478 | Q3+1.5IQR: 53.9870 | |
479 | Max: 82.3620</desc><desc class="x centered">500.08333333333337</desc><desc class="y centered">261.5716380111093</desc><desc class="x_label" /></g></g></g><g class="series serie-22 color-22"><g class="boxes"><g class="box"><path stroke-width="3" d="M517.733333 262.532274 L527.689744 262.532274" class="reactive tooltip-trigger" /><path stroke-width="3" d="M512.755128 256.591987 L532.667949 256.591987" class="reactive tooltip-trigger" /><path stroke-width="3" d="M517.733333 250.501614 L527.689744 250.501614" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 262.532274 L522.711538 258.090369" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 250.501614 L522.711538 255.079074" class="reactive tooltip-trigger" /><rect x="512.7551282051282" y="255.07907373168382" height="3.011295372282575" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="264.50995648742946" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="111.95535240960655" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 50.5880 | |
480 | Q1-1.5IQR: 51.4050 | |
481 | Q1: 53.2400 | |
482 | Median: 53.8590 | |
483 | Q3: 54.4840 | |
484 | Q3+1.5IQR: 56.3750 | |
485 | Max: 113.6100</desc><desc class="x centered">522.7115384615385</desc><desc class="y centered">256.55906339322286</desc><desc class="x_label" /></g></g></g><g class="series serie-23 color-23"><g class="boxes"><g class="box"><path stroke-width="3" d="M540.361538 259.867136 L550.317949 259.867136" class="reactive tooltip-trigger" /><path stroke-width="3" d="M535.383333 252.655995 L555.296154 252.655995" class="reactive tooltip-trigger" /><path stroke-width="3" d="M540.361538 245.154378 L550.317949 245.154378" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 259.867136 L545.339744 254.466649" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 245.154378 L545.339744 250.775155" class="reactive tooltip-trigger" /><rect x="535.3833333333333" y="250.7751549782874" height="3.691493690609036" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="260.31253227395433" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="124.63716746977224" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 52.3220 | |
486 | Q1-1.5IQR: 52.5060 | |
487 | Q1: 54.7370 | |
488 | Median: 55.4850 | |
489 | Q3: 56.2620 | |
490 | Q3+1.5IQR: 58.5840 | |
491 | Max: 108.3710</desc><desc class="x centered">545.3397435897435</desc><desc class="y centered">252.5838625417835</desc><desc class="x_label" /></g></g></g><g class="series serie-24 color-24"><g class="boxes"><g class="box"><path stroke-width="3" d="M562.989744 252.317102 L572.946154 252.317102" class="reactive tooltip-trigger" /><path stroke-width="3" d="M558.011538 246.173478 L577.924359 246.173478" class="reactive tooltip-trigger" /><path stroke-width="3" d="M562.989744 239.988701 L572.946154 239.988701" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 252.317102 L567.967949 247.715434" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 239.988701 L567.967949 244.638787" class="reactive tooltip-trigger" /><rect x="558.0115384615385" y="244.6387868868453" height="3.0766468963672082" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="253.098978031584" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="101.56589550642235" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 55.3020 | |
492 | Q1-1.5IQR: 55.6250 | |
493 | Q1: 57.5260 | |
494 | Median: 58.1630 | |
495 | Q3: 58.7970 | |
496 | Q3+1.5IQR: 60.7180 | |
497 | Max: 117.9020</desc><desc class="x centered">567.9679487179487</desc><desc class="y centered">246.16670041229338</desc><desc class="x_label" /></g></g></g><g class="series serie-25 color-25"><g class="boxes"><g class="box"><path stroke-width="3" d="M585.617949 245.410976 L595.574359 245.410976" class="reactive tooltip-trigger" /><path stroke-width="3" d="M580.639744 239.361755 L600.552564 239.361755" class="reactive tooltip-trigger" /><path stroke-width="3" d="M585.617949 232.528245 L595.574359 232.528245" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 245.410976 L590.596154 240.831085" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 232.528245 L590.596154 237.517214" class="reactive tooltip-trigger" /><rect x="580.6397435897436" y="237.51721440826213" height="3.3138709033464977" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="245.93141907425536" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="176.27218952881162" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 58.2630 | |
498 | Q1-1.5IQR: 58.4780 | |
499 | Q1: 60.3700 | |
500 | Median: 60.9770 | |
501 | Q3: 61.7390 | |
502 | Q3+1.5IQR: 63.8000 | |
503 | Max: 87.0400</desc><desc class="x centered">590.5961538461538</desc><desc class="y centered">239.12985507068953</desc><desc class="x_label" /></g></g></g><g class="series serie-26 color-26"><g class="boxes"><g class="box"><path stroke-width="3" d="M608.246154 85.008606 L618.202564 85.008606" class="reactive tooltip-trigger" /><path stroke-width="3" d="M603.267949 77.925763 L623.180769 77.925763" class="reactive tooltip-trigger" /><path stroke-width="3" d="M608.246154 70.704944 L618.202564 70.704944" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 85.008606 L613.224359 79.700109" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 70.704944 L613.224359 76.107853" class="reactive tooltip-trigger" /><rect x="603.2679487179488" y="76.1078530845532" height="3.5922555387548414" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="86.40290649249584" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="-191.30930655701763" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 124.1660 | |
504 | Q1-1.5IQR: 124.7420 | |
505 | Q1: 126.9350 | |
506 | Median: 127.6680 | |
507 | Q3: 128.4190 | |
508 | Q3+1.5IQR: 130.6510 | |
509 | Max: 238.8920</desc><desc class="x centered">613.224358974359</desc><desc class="y centered">77.88945486835217</desc><desc class="x_label" /></g></g></g><g class="series serie-27 color-27"><g class="boxes"><g class="box"><path stroke-width="3" d="M630.874359 76.773530 L640.830769 76.773530" class="reactive tooltip-trigger" /><path stroke-width="3" d="M625.896154 69.480102 L645.808974 69.480102" class="reactive tooltip-trigger" /><path stroke-width="3" d="M630.874359 61.838087 L640.830769 61.838087" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 76.773530 L635.852564 71.324634" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 61.838087 L635.852564 67.562937" class="reactive tooltip-trigger" /><rect x="625.8961538461539" y="67.5629365640944" height="3.7616974838987858" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="79.11189206876867" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="7.993001315929121" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 127.1780 | |
510 | Q1-1.5IQR: 128.1440 | |
511 | Q1: 130.3950 | |
512 | Median: 131.1570 | |
513 | Q3: 131.9490 | |
514 | Q3+1.5IQR: 134.3140 | |
515 | Max: 156.5580</desc><desc class="x centered">635.8525641025641</desc><desc class="y centered">69.39585791961628</desc><desc class="x_label" /></g></g></g><g class="series serie-28 color-28"><g class="boxes"><g class="box"><path stroke-width="3" d="M653.502564 43.586342 L663.458974 43.586342" class="reactive tooltip-trigger" /><path stroke-width="3" d="M648.524359 36.597903 L668.437179 36.597903" class="reactive tooltip-trigger" /><path stroke-width="3" d="M653.502564 29.515061 L663.458974 29.515061" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 43.586342 L658.480769 38.345013" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 29.515061 L658.480769 34.819932" class="reactive tooltip-trigger" /><rect x="648.524358974359" y="34.81993184556006" height="3.525081111357167" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="45.13071990323431" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="-126.41635273424919" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 141.2160 | |
516 | Q1-1.5IQR: 141.8540 | |
517 | Q1: 144.0192 | |
518 | Median: 144.7410 | |
519 | Q3: 145.4755 | |
520 | Q3+1.5IQR: 147.6670 | |
521 | Max: 212.0840</desc><desc class="x centered">658.4807692307692</desc><desc class="y centered">36.57285020169803</desc><desc class="x_label" /></g></g></g><g class="series serie-29 color-29"><g class="boxes"><g class="box"><path stroke-width="3" d="M676.130769 22.988970 L686.087179 22.988970" class="reactive tooltip-trigger" /><path stroke-width="3" d="M671.152564 16.257129 L691.065385 16.257129" class="reactive tooltip-trigger" /><path stroke-width="3" d="M676.130769 9.251747 L686.087179 9.251747" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 22.988970 L681.108974 17.908624" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 9.251747 L681.108974 14.470078" class="reactive tooltip-trigger" /><rect x="671.1525641025642" y="14.470078402546164" height="3.4385460417684044" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="26.690150732592883" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="-243.99972799019167" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 148.8340 | |
522 | Q1-1.5IQR: 150.3630 | |
523 | Q1: 152.4617 | |
524 | Median: 153.1440 | |
525 | Q3: 153.8822 | |
526 | Q3+1.5IQR: 156.0380 | |
527 | Max: 260.6590</desc><desc class="x centered">681.1089743589744</desc><desc class="y centered">16.175309784142826</desc><desc class="x_label" /></g></g></g></g><g class="titles"><text x="400.0" y="26" class="title plot_title">Speed in Microseconds (us)</text><text x="427.0" y="580.0" class="title">Trial</text><text x="0" y="252.0" class="title" transform="rotate(-90 0.000000 226.000000)">Duration</text></g><g transform="translate(74, 46)" class="plot overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot text-overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot tooltip-overlay"><g transform="translate(0 0)" style="opacity: 0" class="tooltip"><rect rx="0" ry="0" width="0" height="0" class="tooltip-box" /><g class="text" /></g></g></g></svg>⏎ |
0 | <?xml version='1.0' encoding='utf-8'?> | |
1 | <svg xmlns="http://www.w3.org/2000/svg" id="chart-7ffad177-5146-4ca1-823f-60f74aae7bd9" class="pygal-chart" viewBox="0 0 800 600"><!--Generated with pygal 3.0.0 (etree) ©Kozea 2012-2016 on 2022-06-20--><!--http://pygal.org--><!--http://github.com/Kozea/pygal--><defs><style type="text/css">#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .title{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .legends .legend text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis text{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis text.major{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay text.value{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:16px}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay text.label{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:10px}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:14px}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 text.no_data{font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace;font-size:64px} | |
2 | #chart-7ffad177-5146-4ca1-823f-60f74aae7bd9{background-color:rgba(249,249,249,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 path,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 line,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 rect,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .graph > .background{fill:rgba(249,249,249,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .plot > .background{fill:rgba(255,255,255,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .graph{fill:rgba(0,0,0,.87)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 text.no_data{fill:rgba(0,0,0,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .title{fill:rgba(0,0,0,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .legends .legend text{fill:rgba(0,0,0,.87)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis .line{stroke:rgba(0,0,0,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis text.major{fill:rgba(0,0,0,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.y .guides:hover .guide.line,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .line-graph .axis.x .guides:hover .guide.line,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .stackedline-graph .axis.x .guides:hover .guide.line,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .reactive{fill-opacity:.7;stroke-opacity:.8;stroke-width:1}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .ci{stroke:rgba(0,0,0,.87)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .reactive.active,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .ci .reactive.active{stroke-width:1.5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .series text{fill:rgba(0,0,0,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip .value{font-size:1.5em}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .bound{font-size:.5em}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-0,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-0 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-1,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-1 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-2,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-2 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-3,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-3 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-4,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-4 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-5,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-5 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-6,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-6 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-7,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-7 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-8,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-8 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-9,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-9 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-10,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-10 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-11,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-11 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-12,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-12 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-13,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-13 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-14,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-14 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-15,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-15 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-16,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-16 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-17,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-17 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-18,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-18 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-19,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-19 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-20,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-20 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-21,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-21 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-22,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-22 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-23,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-23 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-24,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-24 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-25,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-25 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-26,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-26 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-27,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-27 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-28,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-28 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-29,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .color-29 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-0 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-1 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-2 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-3 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-4 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-5 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-6 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-7 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-8 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-9 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-10 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-11 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-12 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-13 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-14 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-15 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-16 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-17 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-18 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-19 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-20 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-21 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-22 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-23 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-24 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-25 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-26 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-27 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-28 text{fill:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .text-overlay .color-29 text{fill:black} | |
3 | #chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 text.no_data{text-anchor:middle}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .guide.line{fill:none}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .centered{text-anchor:middle}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .title{text-anchor:middle}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .legends .legend text{fill-opacity:1}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.x text{text-anchor:middle}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.x:not(.web) text[transform]{text-anchor:start}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.y text{text-anchor:end}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.y text[transform].backwards{text-anchor:start}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.y2 text{text-anchor:start}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.y2 text[transform].backwards{text-anchor:end}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis .guide.line{stroke-dasharray:4,4;stroke:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis .major.guide.line{stroke-dasharray:6,6;stroke:black}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .horizontal .axis.y .guide.line,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .horizontal .axis.y2 .guide.line,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .vertical .axis.x .guide.line{opacity:0}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .horizontal .axis.always_show .guide.line,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.y .guides:hover .guide.line,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.y2 .guides:hover .guide.line,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis.x .guides:hover .guide.line{opacity:1}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .axis .guides:hover text{opacity:1}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .nofill{fill:none}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .subtle-fill{fill-opacity:.2}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .dot{stroke-width:1px;fill-opacity:1;stroke-opacity:1}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .dot.active{stroke-width:5px}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .dot.negative{fill:transparent}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 text,#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 tspan{stroke:none !important}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .series text.active{opacity:1}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .tooltip text{fill-opacity:1}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .showable{visibility:hidden}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .showable.shown{visibility:visible}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-7ffad177-5146-4ca1-823f-60f74aae7bd9 .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px} | |
4 | .tooltip .value{font-size:1em !important}.axis text{font-size:9px !important}</style><script type="text/javascript">window.pygal = window.pygal || {};window.pygal.config = window.pygal.config || {};window.pygal.config['7ffad177-5146-4ca1-823f-60f74aae7bd9'] = {"allow_interruptions": false, "box_mode": "tukey", "classes": ["pygal-chart"], "css": ["file://style.css", "file://graph.css", "inline:\n .tooltip .value {\n font-size: 1em !important;\n }\n .axis text {\n font-size: 9px !important;\n }\n "], "defs": [], "disable_xml_declaration": false, "dots_size": 2.5, "dynamic_print_values": false, "explicit_size": false, "fill": false, "force_uri_protocol": "https", "formatter": null, "half_pie": false, "height": 600, "include_x_axis": false, "inner_radius": 0, "interpolate": null, "interpolation_parameters": {}, "interpolation_precision": 250, "inverse_y_axis": false, "js": ["file:///home/theel/.pyenv/versions/3.9.13/lib/python3.9/site-packages/pygaljs/static/2.0.x/pygal-tooltips.js"], "legend_at_bottom": false, "legend_at_bottom_columns": null, "legend_box_size": 12, "logarithmic": false, "margin": 20, "margin_bottom": null, "margin_left": null, "margin_right": null, "margin_top": null, "max_scale": 20, "min_scale": 20, "missing_value_fill_truncation": "x", "no_data_text": "No data", "no_prefix": false, "order_min": null, "pretty_print": false, "print_labels": false, "print_values": false, "print_values_position": "center", "print_zeroes": true, "range": [14, 160], "rounded_bars": null, "secondary_range": null, "show_dots": true, "show_legend": false, "show_minor_x_labels": true, "show_minor_y_labels": true, "show_only_major_dots": false, "show_x_guides": false, "show_x_labels": true, "show_y_guides": true, "show_y_labels": true, "spacing": 10, "stack_from_top": false, "strict": false, "stroke": true, "stroke_style": null, "style": {"background": "rgba(249, 249, 249, 1)", "ci_colors": [], "colors": ["#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5", "#3F51B5"], "dot_opacity": "1", "font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "foreground": "rgba(0, 0, 0, .87)", "foreground_strong": "rgba(0, 0, 0, 1)", "foreground_subtle": "rgba(0, 0, 0, .54)", "guide_stroke_color": "black", "guide_stroke_dasharray": "4,4", "label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "label_font_size": 10, "legend_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "legend_font_size": 14, "major_guide_stroke_color": "black", "major_guide_stroke_dasharray": "6,6", "major_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "major_label_font_size": 10, "no_data_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "no_data_font_size": 64, "opacity": ".7", "opacity_hover": ".8", "plot_background": "rgba(255, 255, 255, 1)", "stroke_opacity": ".8", "stroke_opacity_hover": ".9", "stroke_width": "1", "stroke_width_hover": "4", "title_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "title_font_size": 16, "tooltip_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "tooltip_font_size": 14, "transition": "150ms", "value_background": "rgba(229, 229, 229, 1)", "value_colors": [], "value_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_font_size": 16, "value_label_font_family": "Consolas, \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", \"Courier New\", monospace", "value_label_font_size": 10}, "title": "Speed in Microseconds (us)", "tooltip_border_radius": 0, "tooltip_fancy_mode": true, "truncate_label": 50, "truncate_legend": null, "width": 800, "x_label_rotation": 270, "x_labels": ["simple_tuple_d", "simple_set_d", "simple_list_e", "simple_tuple_e", "simple_set_e", "simple_dict_d", "simple_list_d", "simple_dict_e", "complex_homog_tuple_d", "complex_homog_set_d", "complex_heterog_set_d", "complex_heterog_tuple_d", "complex_homog_list_d", "complex_homog_dict_d", "complex_homog_list_e", "complex_heterog_dict_d", "complex_heterog_list_d", "complex_homog_tuple_e", "complex_homog_set_e", "complex_heterog_set_e", "complex_heterog_list_e", "complex_heterog_tuple_e", "complex_homog_dict_e", "simple_cls_d", "complex_heterog_dict_e", "simple_cls_e", "complex_cls_d", "state_cls_d", "complex_cls_e", "state_cls_e"], "x_labels_major": null, "x_labels_major_count": null, "x_labels_major_every": null, "x_title": "Trial", "xrange": null, "y_label_rotation": 0, "y_labels": null, "y_labels_major": null, "y_labels_major_count": null, "y_labels_major_every": null, "y_title": "Duration", "zero": 14, "legends": ["jsonpickle_benchmarks.py::simple_tuple_d - 15133 rounds", "jsonpickle_benchmarks.py::simple_set_d - 16792 rounds", "jsonpickle_benchmarks.py::simple_list_e - 13251 rounds", "jsonpickle_benchmarks.py::simple_tuple_e - 13300 rounds", "jsonpickle_benchmarks.py::simple_set_e - 17505 rounds", "jsonpickle_benchmarks.py::simple_dict_d - 11427 rounds", "jsonpickle_benchmarks.py::simple_list_d - 1845 rounds", "jsonpickle_benchmarks.py::simple_dict_e - 9720 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_d - 13199 rounds", "jsonpickle_benchmarks.py::complex_homog_set_d - 12972 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_d - 11259 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_d - 9155 rounds", "jsonpickle_benchmarks.py::complex_homog_list_d - 11673 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_d - 9415 rounds", "jsonpickle_benchmarks.py::complex_homog_list_e - 8770 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_d - 8975 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_d - 8358 rounds", "jsonpickle_benchmarks.py::complex_homog_tuple_e - 8736 rounds", "jsonpickle_benchmarks.py::complex_homog_set_e - 10218 rounds", "jsonpickle_benchmarks.py::complex_heterog_set_e - 9623 rounds", "jsonpickle_benchmarks.py::complex_heterog_list_e - 7529 rounds", "jsonpickle_benchmarks.py::complex_heterog_tuple_e - 8611 rounds", "jsonpickle_benchmarks.py::complex_homog_dict_e - 7896 rounds", "jsonpickle_benchmarks.py::simple_cls_d - 6613 rounds", "jsonpickle_benchmarks.py::complex_heterog_dict_e - 7505 rounds", "jsonpickle_benchmarks.py::simple_cls_e - 6559 rounds", "jsonpickle_benchmarks.py::complex_cls_d - 4647 rounds", "jsonpickle_benchmarks.py::state_cls_d - 4523 rounds", "jsonpickle_benchmarks.py::complex_cls_e - 3993 rounds", "jsonpickle_benchmarks.py::state_cls_e - 3931 rounds"]}</script><script type="text/javascript">(function() { | |
5 | var $, get_translation, init, init_svg, matches, padding, r_translation, sibl, svg_ns, tooltip_timeout, xlink_ns; | |
6 | ||
7 | svg_ns = 'http://www.w3.org/2000/svg'; | |
8 | ||
9 | xlink_ns = 'http://www.w3.org/1999/xlink'; | |
10 | ||
11 | $ = function(sel, ctx) { | |
12 | if (ctx == null) { | |
13 | ctx = null; | |
14 | } | |
15 | ctx = ctx || document; | |
16 | return Array.prototype.slice.call(ctx.querySelectorAll(sel), 0).filter(function(e) { | |
17 | return e !== ctx; | |
18 | }); | |
19 | }; | |
20 | ||
21 | matches = function(el, selector) { | |
22 | return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector); | |
23 | }; | |
24 | ||
25 | sibl = function(el, match) { | |
26 | if (match == null) { | |
27 | match = null; | |
28 | } | |
29 | return Array.prototype.filter.call(el.parentElement.children, function(child) { | |
30 | return child !== el && (!match || matches(child, match)); | |
31 | }); | |
32 | }; | |
33 | ||
34 | Array.prototype.one = function() { | |
35 | return this.length > 0 && this[0] || {}; | |
36 | }; | |
37 | ||
38 | padding = 5; | |
39 | ||
40 | tooltip_timeout = null; | |
41 | ||
42 | r_translation = /translate\((\d+)[ ,]+(\d+)\)/; | |
43 | ||
44 | get_translation = function(el) { | |
45 | return (r_translation.exec(el.getAttribute('transform')) || []).slice(1).map(function(x) { | |
46 | return +x; | |
47 | }); | |
48 | }; | |
49 | ||
50 | init = function(ctx) { | |
51 | var bbox, box, config, el, graph, inner_svg, num, parent, tooltip, tooltip_el, tt, uid, untooltip, xconvert, yconvert, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; | |
52 | if ($('svg', ctx).length) { | |
53 | inner_svg = $('svg', ctx).one(); | |
54 | parent = inner_svg.parentElement; | |
55 | box = inner_svg.viewBox.baseVal; | |
56 | bbox = parent.getBBox(); | |
57 | xconvert = function(x) { | |
58 | return ((x - box.x) / box.width) * bbox.width; | |
59 | }; | |
60 | yconvert = function(y) { | |
61 | return ((y - box.y) / box.height) * bbox.height; | |
62 | }; | |
63 | } else { | |
64 | xconvert = yconvert = function(x) { | |
65 | return x; | |
66 | }; | |
67 | } | |
68 | if (((_ref = window.pygal) != null ? _ref.config : void 0) != null) { | |
69 | if (window.pygal.config.no_prefix != null) { | |
70 | config = window.pygal.config; | |
71 | } else { | |
72 | uid = ctx.id.replace('chart-', ''); | |
73 | config = window.pygal.config[uid]; | |
74 | } | |
75 | } else { | |
76 | config = window.config; | |
77 | } | |
78 | tooltip_el = null; | |
79 | graph = $('.graph').one(); | |
80 | tt = $('.tooltip', ctx).one(); | |
81 | _ref1 = $('.reactive', ctx); | |
82 | for (_i = 0, _len = _ref1.length; _i < _len; _i++) { | |
83 | el = _ref1[_i]; | |
84 | el.addEventListener('mouseenter', (function(el) { | |
85 | return function() { | |
86 | return el.classList.add('active'); | |
87 | }; | |
88 | })(el)); | |
89 | el.addEventListener('mouseleave', (function(el) { | |
90 | return function() { | |
91 | return el.classList.remove('active'); | |
92 | }; | |
93 | })(el)); | |
94 | } | |
95 | _ref2 = $('.activate-serie', ctx); | |
96 | for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { | |
97 | el = _ref2[_j]; | |
98 | num = el.id.replace('activate-serie-', ''); | |
99 | el.addEventListener('mouseenter', (function(num) { | |
100 | return function() { | |
101 | var re, _k, _len2, _ref3, _results; | |
102 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
103 | _results = []; | |
104 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
105 | re = _ref3[_k]; | |
106 | _results.push(re.classList.add('active')); | |
107 | } | |
108 | return _results; | |
109 | }; | |
110 | })(num)); | |
111 | el.addEventListener('mouseleave', (function(num) { | |
112 | return function() { | |
113 | var re, _k, _len2, _ref3, _results; | |
114 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
115 | _results = []; | |
116 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
117 | re = _ref3[_k]; | |
118 | _results.push(re.classList.remove('active')); | |
119 | } | |
120 | return _results; | |
121 | }; | |
122 | })(num)); | |
123 | el.addEventListener('click', (function(el, num) { | |
124 | return function() { | |
125 | var ov, re, rect, show, _k, _l, _len2, _len3, _ref3, _ref4, _results; | |
126 | rect = $('rect', el).one(); | |
127 | show = rect.style.fill !== ''; | |
128 | rect.style.fill = show ? '' : 'transparent'; | |
129 | _ref3 = $('.serie-' + num + ' .reactive', ctx); | |
130 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
131 | re = _ref3[_k]; | |
132 | re.style.display = show ? '' : 'none'; | |
133 | } | |
134 | _ref4 = $('.text-overlay .serie-' + num, ctx); | |
135 | _results = []; | |
136 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
137 | ov = _ref4[_l]; | |
138 | _results.push(ov.style.display = show ? '' : 'none'); | |
139 | } | |
140 | return _results; | |
141 | }; | |
142 | })(el, num)); | |
143 | } | |
144 | _ref3 = $('.tooltip-trigger', ctx); | |
145 | for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { | |
146 | el = _ref3[_k]; | |
147 | el.addEventListener('mouseenter', (function(el) { | |
148 | return function() { | |
149 | return tooltip_el = tooltip(el); | |
150 | }; | |
151 | })(el)); | |
152 | } | |
153 | tt.addEventListener('mouseenter', function() { | |
154 | return tooltip_el != null ? tooltip_el.classList.add('active') : void 0; | |
155 | }); | |
156 | tt.addEventListener('mouseleave', function() { | |
157 | return tooltip_el != null ? tooltip_el.classList.remove('active') : void 0; | |
158 | }); | |
159 | ctx.addEventListener('mouseleave', function() { | |
160 | if (tooltip_timeout) { | |
161 | clearTimeout(tooltip_timeout); | |
162 | } | |
163 | return untooltip(0); | |
164 | }); | |
165 | graph.addEventListener('mousemove', function(el) { | |
166 | if (tooltip_timeout) { | |
167 | return; | |
168 | } | |
169 | if (!matches(el.target, '.background')) { | |
170 | return; | |
171 | } | |
172 | return untooltip(1000); | |
173 | }); | |
174 | tooltip = function(el) { | |
175 | var a, baseline, cls, current_x, current_y, dy, h, i, key, keys, label, legend, name, plot_x, plot_y, rect, serie_index, subval, text, text_group, texts, traversal, value, w, x, x_elt, x_label, xlink, y, y_elt, _l, _len3, _len4, _len5, _m, _n, _ref4, _ref5, _ref6, _ref7, _ref8; | |
176 | clearTimeout(tooltip_timeout); | |
177 | tooltip_timeout = null; | |
178 | tt.style.opacity = 1; | |
179 | tt.style.display = ''; | |
180 | text_group = $('g.text', tt).one(); | |
181 | rect = $('rect', tt).one(); | |
182 | text_group.innerHTML = ''; | |
183 | label = sibl(el, '.label').one().textContent; | |
184 | x_label = sibl(el, '.x_label').one().textContent; | |
185 | value = sibl(el, '.value').one().textContent; | |
186 | xlink = sibl(el, '.xlink').one().textContent; | |
187 | serie_index = null; | |
188 | parent = el; | |
189 | traversal = []; | |
190 | while (parent) { | |
191 | traversal.push(parent); | |
192 | if (parent.classList.contains('series')) { | |
193 | break; | |
194 | } | |
195 | parent = parent.parentElement; | |
196 | } | |
197 | if (parent) { | |
198 | _ref4 = parent.classList; | |
199 | for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { | |
200 | cls = _ref4[_l]; | |
201 | if (cls.indexOf('serie-') === 0) { | |
202 | serie_index = +cls.replace('serie-', ''); | |
203 | break; | |
204 | } | |
205 | } | |
206 | } | |
207 | legend = null; | |
208 | if (serie_index !== null) { | |
209 | legend = config.legends[serie_index]; | |
210 | } | |
211 | dy = 0; | |
212 | keys = [[label, 'label']]; | |
213 | _ref5 = value.split('\n'); | |
214 | for (i = _m = 0, _len4 = _ref5.length; _m < _len4; i = ++_m) { | |
215 | subval = _ref5[i]; | |
216 | keys.push([subval, 'value-' + i]); | |
217 | } | |
218 | if (config.tooltip_fancy_mode) { | |
219 | keys.push([xlink, 'xlink']); | |
220 | keys.unshift([x_label, 'x_label']); | |
221 | keys.unshift([legend, 'legend']); | |
222 | } | |
223 | texts = {}; | |
224 | for (_n = 0, _len5 = keys.length; _n < _len5; _n++) { | |
225 | _ref6 = keys[_n], key = _ref6[0], name = _ref6[1]; | |
226 | if (key) { | |
227 | text = document.createElementNS(svg_ns, 'text'); | |
228 | text.textContent = key; | |
229 | text.setAttribute('x', padding); | |
230 | text.setAttribute('dy', dy); | |
231 | text.classList.add(name.indexOf('value') === 0 ? 'value' : name); | |
232 | if (name.indexOf('value') === 0 && config.tooltip_fancy_mode) { | |
233 | text.classList.add('color-' + serie_index); | |
234 | } | |
235 | if (name === 'xlink') { | |
236 | a = document.createElementNS(svg_ns, 'a'); | |
237 | a.setAttributeNS(xlink_ns, 'href', key); | |
238 | a.textContent = void 0; | |
239 | a.appendChild(text); | |
240 | text.textContent = 'Link >'; | |
241 | text_group.appendChild(a); | |
242 | } else { | |
243 | text_group.appendChild(text); | |
244 | } | |
245 | dy += text.getBBox().height + padding / 2; | |
246 | baseline = padding; | |
247 | if (text.style.dominantBaseline !== void 0) { | |
248 | text.style.dominantBaseline = 'text-before-edge'; | |
249 | } else { | |
250 | baseline += text.getBBox().height * .8; | |
251 | } | |
252 | text.setAttribute('y', baseline); | |
253 | texts[name] = text; | |
254 | } | |
255 | } | |
256 | w = text_group.getBBox().width + 2 * padding; | |
257 | h = text_group.getBBox().height + 2 * padding; | |
258 | rect.setAttribute('width', w); | |
259 | rect.setAttribute('height', h); | |
260 | if (texts.value) { | |
261 | texts.value.setAttribute('dx', (w - texts.value.getBBox().width) / 2 - padding); | |
262 | } | |
263 | if (texts.x_label) { | |
264 | texts.x_label.setAttribute('dx', w - texts.x_label.getBBox().width - 2 * padding); | |
265 | } | |
266 | if (texts.xlink) { | |
267 | texts.xlink.setAttribute('dx', w - texts.xlink.getBBox().width - 2 * padding); | |
268 | } | |
269 | x_elt = sibl(el, '.x').one(); | |
270 | y_elt = sibl(el, '.y').one(); | |
271 | x = parseInt(x_elt.textContent); | |
272 | if (x_elt.classList.contains('centered')) { | |
273 | x -= w / 2; | |
274 | } else if (x_elt.classList.contains('left')) { | |
275 | x -= w; | |
276 | } else if (x_elt.classList.contains('auto')) { | |
277 | x = xconvert(el.getBBox().x + el.getBBox().width / 2) - w / 2; | |
278 | } | |
279 | y = parseInt(y_elt.textContent); | |
280 | if (y_elt.classList.contains('centered')) { | |
281 | y -= h / 2; | |
282 | } else if (y_elt.classList.contains('top')) { | |
283 | y -= h; | |
284 | } else if (y_elt.classList.contains('auto')) { | |
285 | y = yconvert(el.getBBox().y + el.getBBox().height / 2) - h / 2; | |
286 | } | |
287 | _ref7 = get_translation(tt.parentElement), plot_x = _ref7[0], plot_y = _ref7[1]; | |
288 | if (x + w + plot_x > config.width) { | |
289 | x = config.width - w - plot_x; | |
290 | } | |
291 | if (y + h + plot_y > config.height) { | |
292 | y = config.height - h - plot_y; | |
293 | } | |
294 | if (x + plot_x < 0) { | |
295 | x = -plot_x; | |
296 | } | |
297 | if (y + plot_y < 0) { | |
298 | y = -plot_y; | |
299 | } | |
300 | _ref8 = get_translation(tt), current_x = _ref8[0], current_y = _ref8[1]; | |
301 | if (current_x === x && current_y === y) { | |
302 | return el; | |
303 | } | |
304 | tt.setAttribute('transform', "translate(" + x + " " + y + ")"); | |
305 | return el; | |
306 | }; | |
307 | return untooltip = function(ms) { | |
308 | return tooltip_timeout = setTimeout(function() { | |
309 | tt.style.display = 'none'; | |
310 | tt.style.opacity = 0; | |
311 | if (tooltip_el != null) { | |
312 | tooltip_el.classList.remove('active'); | |
313 | } | |
314 | return tooltip_timeout = null; | |
315 | }, ms); | |
316 | }; | |
317 | }; | |
318 | ||
319 | init_svg = function() { | |
320 | var chart, charts, _i, _len, _results; | |
321 | charts = $('.pygal-chart'); | |
322 | if (charts.length) { | |
323 | _results = []; | |
324 | for (_i = 0, _len = charts.length; _i < _len; _i++) { | |
325 | chart = charts[_i]; | |
326 | _results.push(init(chart)); | |
327 | } | |
328 | return _results; | |
329 | } | |
330 | }; | |
331 | ||
332 | if (document.readyState !== 'loading') { | |
333 | init_svg(); | |
334 | } else { | |
335 | document.addEventListener('DOMContentLoaded', function() { | |
336 | return init_svg(); | |
337 | }); | |
338 | } | |
339 | ||
340 | window.pygal = window.pygal || {}; | |
341 | ||
342 | window.pygal.init = init; | |
343 | ||
344 | window.pygal.init_svg = init_svg; | |
345 | ||
346 | }).call(this); | |
347 | </script></defs><title>Speed in Microseconds (us)</title><g class="graph custombox-graph vertical"><rect x="0" y="0" width="800" height="600" class="background" /><g transform="translate(74, 46)" class="plot"><rect x="0" y="0" width="706.0" height="360.0" class="background" /><g class="axis y always_show"><path d="M0.000000 360.000000 h706.000000" class="line" /><g class="guides"><path d="M0.000000 348.335090 h706.000000" class="guide line" /><text x="-5" y="351.8350895679663" class="">16</text><title>16</title></g><g class="guides"><path d="M0.000000 329.367756 h706.000000" class="guide line" /><text x="-5" y="332.8677555321391" class="">24</text><title>24</title></g><g class="guides"><path d="M0.000000 310.400421 h706.000000" class="guide line" /><text x="-5" y="313.9004214963119" class="">32</text><title>32</title></g><g class="guides"><path d="M0.000000 291.433087 h706.000000" class="guide line" /><text x="-5" y="294.93308746048467" class="">40</text><title>40</title></g><g class="guides"><path d="M0.000000 272.465753 h706.000000" class="guide line" /><text x="-5" y="275.9657534246575" class="">48</text><title>48</title></g><g class="guides"><path d="M0.000000 253.498419 h706.000000" class="guide line" /><text x="-5" y="256.9984193888303" class="">56</text><title>56</title></g><g class="guides"><path d="M0.000000 234.531085 h706.000000" class="guide line" /><text x="-5" y="238.03108535300314" class="">64</text><title>64</title></g><g class="guides"><path d="M0.000000 215.563751 h706.000000" class="guide line" /><text x="-5" y="219.06375131717596" class="">72</text><title>72</title></g><g class="guides"><path d="M0.000000 196.596417 h706.000000" class="guide line" /><text x="-5" y="200.09641728134875" class="">80</text><title>80</title></g><g class="guides"><path d="M0.000000 177.629083 h706.000000" class="guide line" /><text x="-5" y="181.12908324552157" class="">88</text><title>88</title></g><g class="guides"><path d="M0.000000 158.661749 h706.000000" class="guide line" /><text x="-5" y="162.16174920969436" class="">96</text><title>96</title></g><g class="guides"><path d="M0.000000 139.694415 h706.000000" class="guide line" /><text x="-5" y="143.1944151738672" class="">104</text><title>104</title></g><g class="guides"><path d="M0.000000 120.727081 h706.000000" class="guide line" /><text x="-5" y="124.22708113804003" class="">112</text><title>112</title></g><g class="guides"><path d="M0.000000 101.759747 h706.000000" class="guide line" /><text x="-5" y="105.25974710221283" class="">120</text><title>120</title></g><g class="guides"><path d="M0.000000 82.792413 h706.000000" class="guide line" /><text x="-5" y="86.29241306638562" class="">128</text><title>128</title></g><g class="guides"><path d="M0.000000 63.825079 h706.000000" class="guide line" /><text x="-5" y="67.32507903055847" class="">136</text><title>136</title></g><g class="guides"><path d="M0.000000 44.857745 h706.000000" class="guide line" /><text x="-5" y="48.35774499473126" class="">144</text><title>144</title></g><g class="guides"><path d="M0.000000 25.890411 h706.000000" class="guide line" /><text x="-5" y="29.390410958904056" class="">152</text><title>152</title></g><g class="guides"><path d="M0.000000 6.923077 h706.000000" class="guide line" /><text x="-5" y="10.423076923076906" class="">160</text><title>160</title></g></g><g class="axis x"><path d="M0.000000 0.000000 v360.000000" class="line" /><g class="guides"><path d="M24.891026 0.000000 v360.000000" class="guide line" /><text x="24.89102564102564" y="375.0" class="backwards" transform="rotate(270 24.891026 375.000000)">simple_tuple_d</text></g><g class="guides"><path d="M47.519231 0.000000 v360.000000" class="guide line" /><text x="47.51923076923077" y="375.0" class="backwards" transform="rotate(270 47.519231 375.000000)">simple_set_d</text></g><g class="guides"><path d="M70.147436 0.000000 v360.000000" class="guide line" /><text x="70.1474358974359" y="375.0" class="backwards" transform="rotate(270 70.147436 375.000000)">simple_list_e</text></g><g class="guides"><path d="M92.775641 0.000000 v360.000000" class="guide line" /><text x="92.77564102564102" y="375.0" class="backwards" transform="rotate(270 92.775641 375.000000)">simple_tuple_e</text></g><g class="guides"><path d="M115.403846 0.000000 v360.000000" class="guide line" /><text x="115.40384615384615" y="375.0" class="backwards" transform="rotate(270 115.403846 375.000000)">simple_set_e</text></g><g class="guides"><path d="M138.032051 0.000000 v360.000000" class="guide line" /><text x="138.03205128205127" y="375.0" class="backwards" transform="rotate(270 138.032051 375.000000)">simple_dict_d</text></g><g class="guides"><path d="M160.660256 0.000000 v360.000000" class="guide line" /><text x="160.6602564102564" y="375.0" class="backwards" transform="rotate(270 160.660256 375.000000)">simple_list_d</text></g><g class="guides"><path d="M183.288462 0.000000 v360.000000" class="guide line" /><text x="183.28846153846155" y="375.0" class="backwards" transform="rotate(270 183.288462 375.000000)">simple_dict_e</text></g><g class="guides"><path d="M205.916667 0.000000 v360.000000" class="guide line" /><text x="205.91666666666666" y="375.0" class="backwards" transform="rotate(270 205.916667 375.000000)">complex_homog_tuple_d</text></g><g class="guides"><path d="M228.544872 0.000000 v360.000000" class="guide line" /><text x="228.5448717948718" y="375.0" class="backwards" transform="rotate(270 228.544872 375.000000)">complex_homog_set_d</text></g><g class="guides"><path d="M251.173077 0.000000 v360.000000" class="guide line" /><text x="251.17307692307688" y="375.0" class="backwards" transform="rotate(270 251.173077 375.000000)">complex_heterog_set_d</text></g><g class="guides"><path d="M273.801282 0.000000 v360.000000" class="guide line" /><text x="273.8012820512821" y="375.0" class="backwards" transform="rotate(270 273.801282 375.000000)">complex_heterog_tuple_d</text></g><g class="guides"><path d="M296.429487 0.000000 v360.000000" class="guide line" /><text x="296.4294871794872" y="375.0" class="backwards" transform="rotate(270 296.429487 375.000000)">complex_homog_list_d</text></g><g class="guides"><path d="M319.057692 0.000000 v360.000000" class="guide line" /><text x="319.05769230769226" y="375.0" class="backwards" transform="rotate(270 319.057692 375.000000)">complex_homog_dict_d</text></g><g class="guides"><path d="M341.685897 0.000000 v360.000000" class="guide line" /><text x="341.6858974358974" y="375.0" class="backwards" transform="rotate(270 341.685897 375.000000)">complex_homog_list_e</text></g><g class="guides"><path d="M364.314103 0.000000 v360.000000" class="guide line" /><text x="364.3141025641026" y="375.0" class="backwards" transform="rotate(270 364.314103 375.000000)">complex_heterog_dict_d</text></g><g class="guides"><path d="M386.942308 0.000000 v360.000000" class="guide line" /><text x="386.9423076923077" y="375.0" class="backwards" transform="rotate(270 386.942308 375.000000)">complex_heterog_list_d</text></g><g class="guides"><path d="M409.570513 0.000000 v360.000000" class="guide line" /><text x="409.5705128205129" y="375.0" class="backwards" transform="rotate(270 409.570513 375.000000)">complex_homog_tuple_e</text></g><g class="guides"><path d="M432.198718 0.000000 v360.000000" class="guide line" /><text x="432.19871794871796" y="375.0" class="backwards" transform="rotate(270 432.198718 375.000000)">complex_homog_set_e</text></g><g class="guides"><path d="M454.826923 0.000000 v360.000000" class="guide line" /><text x="454.8269230769231" y="375.0" class="backwards" transform="rotate(270 454.826923 375.000000)">complex_heterog_set_e</text></g><g class="guides"><path d="M477.455128 0.000000 v360.000000" class="guide line" /><text x="477.4551282051282" y="375.0" class="backwards" transform="rotate(270 477.455128 375.000000)">complex_heterog_list_e</text></g><g class="guides"><path d="M500.083333 0.000000 v360.000000" class="guide line" /><text x="500.08333333333337" y="375.0" class="backwards" transform="rotate(270 500.083333 375.000000)">complex_heterog_tuple_e</text></g><g class="guides"><path d="M522.711538 0.000000 v360.000000" class="guide line" /><text x="522.7115384615385" y="375.0" class="backwards" transform="rotate(270 522.711538 375.000000)">complex_homog_dict_e</text></g><g class="guides"><path d="M545.339744 0.000000 v360.000000" class="guide line" /><text x="545.3397435897435" y="375.0" class="backwards" transform="rotate(270 545.339744 375.000000)">simple_cls_d</text></g><g class="guides"><path d="M567.967949 0.000000 v360.000000" class="guide line" /><text x="567.9679487179487" y="375.0" class="backwards" transform="rotate(270 567.967949 375.000000)">complex_heterog_dict_e</text></g><g class="guides"><path d="M590.596154 0.000000 v360.000000" class="guide line" /><text x="590.5961538461538" y="375.0" class="backwards" transform="rotate(270 590.596154 375.000000)">simple_cls_e</text></g><g class="guides"><path d="M613.224359 0.000000 v360.000000" class="guide line" /><text x="613.224358974359" y="375.0" class="backwards" transform="rotate(270 613.224359 375.000000)">complex_cls_d</text></g><g class="guides"><path d="M635.852564 0.000000 v360.000000" class="guide line" /><text x="635.8525641025641" y="375.0" class="backwards" transform="rotate(270 635.852564 375.000000)">state_cls_d</text></g><g class="guides"><path d="M658.480769 0.000000 v360.000000" class="guide line" /><text x="658.4807692307692" y="375.0" class="backwards" transform="rotate(270 658.480769 375.000000)">complex_cls_e</text></g><g class="guides"><path d="M681.108974 0.000000 v360.000000" class="guide line" /><text x="681.1089743589743" y="375.0" class="backwards" transform="rotate(270 681.108974 375.000000)">state_cls_e</text></g></g><g class="series serie-0 color-0"><g class="boxes"><g class="box"><path stroke-width="3" d="M19.912821 351.855899 L29.869231 351.855899" class="reactive tooltip-trigger" /><path stroke-width="3" d="M14.934615 350.786624 L34.847436 350.786624" class="reactive tooltip-trigger" /><path stroke-width="3" d="M19.912821 349.698364 L29.869231 349.698364" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 351.855899 L24.891026 351.049783" class="reactive tooltip-trigger" /><path stroke-width="2" d="M24.891026 349.698364 L24.891026 350.509224" class="reactive tooltip-trigger" /><rect x="14.934615384615384" y="350.5092242894988" height="0.5405589906146133" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="352.23525068401756" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="24.891025641025642" cy="300.4639122264707" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 14.3550 | |
348 | Q1-1.5IQR: 14.5150 | |
349 | Q1: 14.8550 | |
350 | Median: 14.9660 | |
351 | Q3: 15.0830 | |
352 | Q3+1.5IQR: 15.4250 | |
353 | Max: 36.1910</desc><desc class="x centered">24.891025641025642</desc><desc class="y centered">350.7799790413104</desc><desc class="x_label" /></g></g></g><g class="series serie-1 color-1"><g class="boxes"><g class="box"><path stroke-width="3" d="M42.541026 351.142256 L52.497436 351.142256" class="reactive tooltip-trigger" /><path stroke-width="3" d="M37.562821 350.163063 L57.475641 350.163063" class="reactive tooltip-trigger" /><path stroke-width="3" d="M42.541026 349.160169 L52.497436 349.160169" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 351.142256 L47.519231 350.400157" class="reactive tooltip-trigger" /><path stroke-width="2" d="M47.519231 349.160169 L47.519231 349.904631" class="reactive tooltip-trigger" /><rect x="37.562820512820515" y="349.9046307383007" height="0.4955260648595754" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="351.2489511193418" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="47.519230769230774" cy="325.1380396336886" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 14.7710 | |
354 | Q1-1.5IQR: 14.8160 | |
355 | Q1: 15.1290 | |
356 | Median: 15.2290 | |
357 | Q3: 15.3380 | |
358 | Q3+1.5IQR: 15.6520 | |
359 | Max: 25.7840</desc><desc class="x centered">47.519230769230774</desc><desc class="y centered">350.1540550121594</desc><desc class="x_label" /></g></g></g><g class="series serie-2 color-2"><g class="boxes"><g class="box"><path stroke-width="3" d="M65.169231 349.413857 L75.125641 349.413857" class="reactive tooltip-trigger" /><path stroke-width="3" d="M60.191026 347.955743 L80.103846 347.955743" class="reactive tooltip-trigger" /><path stroke-width="3" d="M65.169231 346.381453 L75.125641 346.381453" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 349.413857 L70.147436 348.323234" class="reactive tooltip-trigger" /><path stroke-width="2" d="M70.147436 346.381453 L70.147436 347.547945" class="reactive tooltip-trigger" /><rect x="60.19102564102564" y="347.54794500027737" height="0.7752891268912094" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="349.60827251266954" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="70.1474358974359" cy="280.3537911975592" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 15.4630 | |
360 | Q1-1.5IQR: 15.5450 | |
361 | Q1: 16.0050 | |
362 | Median: 16.1600 | |
363 | Q3: 16.3320 | |
364 | Q3+1.5IQR: 16.8240 | |
365 | Max: 44.6730</desc><desc class="x centered">70.1474358974359</desc><desc class="y centered">347.9244464806387</desc><desc class="x_label" /></g></g></g><g class="series serie-3 color-3"><g class="boxes"><g class="box"><path stroke-width="3" d="M87.797436 347.751848 L97.753846 347.751848" class="reactive tooltip-trigger" /><path stroke-width="3" d="M82.819231 346.407536 L102.732051 346.407536" class="reactive tooltip-trigger" /><path stroke-width="3" d="M87.797436 345.008695 L97.753846 345.008695" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 347.751848 L92.775641 346.729978" class="reactive tooltip-trigger" /><path stroke-width="2" d="M92.775641 345.008695 L92.775641 346.042417" class="reactive tooltip-trigger" /><rect x="82.81923076923077" y="346.04241692293994" height="0.687560743850554" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="348.35168914001406" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="92.77564102564102" cy="312.5864032248488" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 15.9930 | |
366 | Q1-1.5IQR: 16.2460 | |
367 | Q1: 16.6770 | |
368 | Median: 16.8130 | |
369 | Q3: 16.9670 | |
370 | Q3+1.5IQR: 17.4030 | |
371 | Max: 31.0780</desc><desc class="x centered">92.77564102564102</desc><desc class="y centered">346.38809487074457</desc><desc class="x_label" /></g></g></g><g class="series serie-4 color-4"><g class="boxes"><g class="box"><path stroke-width="3" d="M110.425641 348.000784 L120.382051 348.000784" class="reactive tooltip-trigger" /><path stroke-width="3" d="M105.447436 346.535562 L125.360256 346.535562" class="reactive tooltip-trigger" /><path stroke-width="3" d="M110.425641 345.013431 L120.382051 345.013431" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 348.000784 L115.403846 346.884087" class="reactive tooltip-trigger" /><path stroke-width="2" d="M115.403846 345.013431 L115.403846 346.136653" class="reactive tooltip-trigger" /><rect x="105.4474358974359" y="346.13665312871234" height="0.747433575516709" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="348.2947791143231" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="115.40384615384615" cy="306.66859721144937" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.0170 | |
372 | Q1-1.5IQR: 16.1410 | |
373 | Q1: 16.6120 | |
374 | Median: 16.7590 | |
375 | Q3: 16.9273 | |
376 | Q3+1.5IQR: 17.4010 | |
377 | Max: 33.5740</desc><desc class="x centered">115.40384615384615</desc><desc class="y centered">346.5141033970133</desc><desc class="x_label" /></g></g></g><g class="series serie-5 color-5"><g class="boxes"><g class="box"><path stroke-width="3" d="M133.053846 346.891203 L143.010256 346.891203" class="reactive tooltip-trigger" /><path stroke-width="3" d="M128.075641 345.558742 L147.988462 345.558742" class="reactive tooltip-trigger" /><path stroke-width="3" d="M133.053846 344.067437 L143.010256 344.067437" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 346.891203 L138.032051 345.869341" class="reactive tooltip-trigger" /><path stroke-width="2" d="M138.032051 344.067437 L138.032051 345.148581" class="reactive tooltip-trigger" /><rect x="128.07564102564103" y="345.1485810556583" height="0.7207596963943956" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="346.8912026137766" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="138.0320512820513" cy="306.1967908450818" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 16.6090 | |
378 | Q1-1.5IQR: 16.6090 | |
379 | Q1: 17.0400 | |
380 | Median: 17.1710 | |
381 | Q3: 17.3440 | |
382 | Q3+1.5IQR: 17.8000 | |
383 | Max: 33.7730</desc><desc class="x centered">138.0320512820513</desc><desc class="y centered">345.5070607403727</desc><desc class="x_label" /></g></g></g><g class="series serie-6 color-6"><g class="boxes"><g class="box"><path stroke-width="3" d="M155.682051 345.615643 L165.638462 345.615643" class="reactive tooltip-trigger" /><path stroke-width="3" d="M150.703846 344.202579 L170.616667 344.202579" class="reactive tooltip-trigger" /><path stroke-width="3" d="M155.682051 342.644885 L165.638462 342.644885" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 345.615643 L160.660256 344.601488" class="reactive tooltip-trigger" /><path stroke-width="2" d="M160.660256 342.644885 L160.660256 343.822643" class="reactive tooltip-trigger" /><rect x="150.70384615384614" y="343.8226434409485" height="0.7788449253287695" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="345.6156434823275" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="160.6602564102564" cy="276.1620115786786" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 17.1470 | |
384 | Q1-1.5IQR: 17.1470 | |
385 | Q1: 17.5748 | |
386 | Median: 17.7430 | |
387 | Q3: 17.9032 | |
388 | Q3+1.5IQR: 18.4000 | |
389 | Max: 46.4410</desc><desc class="x centered">160.6602564102564</desc><desc class="y centered">344.17744786619835</desc><desc class="x_label" /></g></g></g><g class="series serie-7 color-7"><g class="boxes"><g class="box"><path stroke-width="3" d="M178.310256 344.866437 L188.266667 344.866437" class="reactive tooltip-trigger" /><path stroke-width="3" d="M173.332051 342.924657 L193.244872 342.924657" class="reactive tooltip-trigger" /><path stroke-width="3" d="M178.310256 340.646203 L188.266667 340.646203" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 344.866437 L183.288462 343.372761" class="reactive tooltip-trigger" /><path stroke-width="2" d="M183.288462 340.646203 L183.288462 342.284509" class="reactive tooltip-trigger" /><rect x="173.33205128205125" y="342.2845094035295" height="1.0882511414666851" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="344.8664373984326" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="183.28846153846152" cy="282.70574162122904" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 17.4630 | |
390 | Q1-1.5IQR: 17.4630 | |
391 | Q1: 18.0930 | |
392 | Median: 18.2820 | |
393 | Q3: 18.5520 | |
394 | Q3+1.5IQR: 19.2430 | |
395 | Max: 43.6810</desc><desc class="x centered">183.28846153846152</desc><desc class="y centered">342.8189133480191</desc><desc class="x_label" /></g></g></g><g class="series serie-8 color-8"><g class="boxes"><g class="box"><path stroke-width="3" d="M200.938462 323.468915 L210.894872 323.468915" class="reactive tooltip-trigger" /><path stroke-width="3" d="M195.960256 322.134082 L215.873077 322.134082" class="reactive tooltip-trigger" /><path stroke-width="3" d="M200.938462 320.737622 L210.894872 320.737622" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 323.468915 L205.916667 322.449425" class="reactive tooltip-trigger" /><path stroke-width="2" d="M205.916667 320.737622 L205.916667 321.767190" class="reactive tooltip-trigger" /><rect x="195.9602564102564" y="321.76719015427017" height="0.6822345933709357" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="323.57560153066026" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="205.91666666666666" cy="214.83825026841063" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 26.4430 | |
396 | Q1-1.5IQR: 26.4880 | |
397 | Q1: 26.9180 | |
398 | Median: 27.0510 | |
399 | Q3: 27.2057 | |
400 | Q3+1.5IQR: 27.6400 | |
401 | Max: 72.3060</desc><desc class="x centered">205.91666666666666</desc><desc class="y centered">322.11144664523425</desc><desc class="x_label" /></g></g></g><g class="series serie-9 color-9"><g class="boxes"><g class="box"><path stroke-width="3" d="M223.566667 322.231298 L233.523077 322.231298" class="reactive tooltip-trigger" /><path stroke-width="3" d="M218.588462 320.201798 L238.501282 320.201798" class="reactive tooltip-trigger" /><path stroke-width="3" d="M223.566667 318.153313 L233.523077 318.153313" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 322.231298 L228.544872 320.725762" class="reactive tooltip-trigger" /><path stroke-width="2" d="M228.544872 318.153313 L228.544872 319.696784" class="reactive tooltip-trigger" /><rect x="218.58846153846153" y="319.6967839263551" height="1.0289777712714567" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="322.6485753361797" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="228.5448717948718" cy="252.91518037049912" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 26.8340 | |
402 | Q1-1.5IQR: 27.0100 | |
403 | Q1: 27.6450 | |
404 | Median: 27.8660 | |
405 | Q3: 28.0790 | |
406 | Q3+1.5IQR: 28.7300 | |
407 | Max: 56.2460</desc><desc class="x centered">228.5448717948718</desc><desc class="y centered">320.20179097033554</desc><desc class="x_label" /></g></g></g><g class="series serie-10 color-10"><g class="boxes"><g class="box"><path stroke-width="3" d="M246.194872 320.189938 L256.151282 320.189938" class="reactive tooltip-trigger" /><path stroke-width="3" d="M241.216667 318.599054 L261.129487 318.599054" class="reactive tooltip-trigger" /><path stroke-width="3" d="M246.194872 316.493676 L256.151282 316.493676" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 320.189938 L251.173077 318.990256" class="reactive tooltip-trigger" /><path stroke-width="2" d="M251.173077 316.493676 L251.173077 317.992097" class="reactive tooltip-trigger" /><rect x="241.21666666666664" y="317.9920966351342" height="0.9981594139217123" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="320.18993802136544" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="251.1730769230769" cy="211.01159012475313" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 27.8710 | |
408 | Q1-1.5IQR: 27.8710 | |
409 | Q1: 28.3770 | |
410 | Median: 28.5420 | |
411 | Q3: 28.7980 | |
412 | Q3+1.5IQR: 29.4300 | |
413 | Max: 73.9200</desc><desc class="x centered">251.1730769230769</desc><desc class="y centered">318.4530040156783</desc><desc class="x_label" /></g></g></g><g class="series serie-11 color-11"><g class="boxes"><g class="box"><path stroke-width="3" d="M268.823077 303.294785 L278.779487 303.294785" class="reactive tooltip-trigger" /><path stroke-width="3" d="M263.844872 299.103005 L283.757692 299.103005" class="reactive tooltip-trigger" /><path stroke-width="3" d="M268.823077 294.795051 L278.779487 294.795051" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 303.294785 L273.801282 300.147979" class="reactive tooltip-trigger" /><path stroke-width="2" d="M273.801282 294.795051 L273.801282 298.024233" class="reactive tooltip-trigger" /><rect x="263.84487179487184" y="298.0242334197602" height="2.1237453608147803" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="304.25500144773514" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="273.8012820512821" cy="202.04241309458735" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 34.5920 | |
414 | Q1-1.5IQR: 34.9970 | |
415 | Q1: 36.3243 | |
416 | Median: 36.7650 | |
417 | Q3: 37.2200 | |
418 | Q3+1.5IQR: 38.5820 | |
419 | Max: 77.7030</desc><desc class="x centered">273.8012820512821</desc><desc class="y centered">299.0730106702638</desc><desc class="x_label" /></g></g></g><g class="series serie-12 color-12"><g class="boxes"><g class="box"><path stroke-width="3" d="M291.451282 301.737091 L301.407692 301.737091" class="reactive tooltip-trigger" /><path stroke-width="3" d="M286.473077 299.785831 L306.385897 299.785831" class="reactive tooltip-trigger" /><path stroke-width="3" d="M291.451282 297.727875 L301.407692 297.727875" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 301.737091 L296.429487 300.236298" class="reactive tooltip-trigger" /><path stroke-width="2" d="M296.429487 297.727875 L296.429487 299.233403" class="reactive tooltip-trigger" /><rect x="286.473076923077" y="299.2334032714665" height="1.002894728275237" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="302.1923105908387" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="296.42948717948724" cy="208.82323661791864" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 35.4620 | |
420 | Q1-1.5IQR: 35.6540 | |
421 | Q1: 36.2870 | |
422 | Median: 36.4770 | |
423 | Q3: 36.7100 | |
424 | Q3+1.5IQR: 37.3450 | |
425 | Max: 74.8430</desc><desc class="x centered">296.42948717948724</desc><desc class="y centered">299.744099592947</desc><desc class="x_label" /></g></g></g><g class="series serie-13 color-13"><g class="boxes"><g class="box"><path stroke-width="3" d="M314.079487 301.428873 L324.035897 301.428873" class="reactive tooltip-trigger" /><path stroke-width="3" d="M309.101282 297.836934 L329.014103 297.836934" class="reactive tooltip-trigger" /><path stroke-width="3" d="M314.079487 293.894099 L324.035897 293.894099" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 301.428873 L319.057692 298.635335" class="reactive tooltip-trigger" /><path stroke-width="2" d="M319.057692 293.894099 L319.057692 296.741567" class="reactive tooltip-trigger" /><rect x="309.1012820512821" y="296.7415670041084" height="1.8937677895815455" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="301.4288726878486" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="319.0576923076924" cy="248.52423291239006" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 35.7840 | |
426 | Q1-1.5IQR: 35.7840 | |
427 | Q1: 36.9623 | |
428 | Median: 37.2990 | |
429 | Q3: 37.7610 | |
430 | Q3+1.5IQR: 38.9620 | |
431 | Max: 58.0980</desc><desc class="x centered">319.0576923076924</desc><desc class="y centered">297.70736153633874</desc><desc class="x_label" /></g></g></g><g class="series serie-14 color-14"><g class="boxes"><g class="box"><path stroke-width="3" d="M336.707692 299.117229 L346.664103 299.117229" class="reactive tooltip-trigger" /><path stroke-width="3" d="M331.729487 295.364065 L351.642308 295.364065" class="reactive tooltip-trigger" /><path stroke-width="3" d="M336.707692 291.203112 L346.664103 291.203112" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 299.117229 L341.685897 296.276868" class="reactive tooltip-trigger" /><path stroke-width="2" d="M341.685897 291.203112 L341.685897 294.254475" class="reactive tooltip-trigger" /><rect x="331.7294871794872" y="294.2544746764487" height="2.0223932454948113" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="299.1172285009253" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="341.68589743589746" cy="215.84588893638426" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 36.7590 | |
432 | Q1-1.5IQR: 36.7590 | |
433 | Q1: 37.9570 | |
434 | Median: 38.3420 | |
435 | Q3: 38.8100 | |
436 | Q3+1.5IQR: 40.0970 | |
437 | Max: 71.8810</desc><desc class="x centered">341.68589743589746</desc><desc class="y centered">295.2431496611116</desc><desc class="x_label" /></g></g></g><g class="series serie-15 color-15"><g class="boxes"><g class="box"><path stroke-width="3" d="M359.335897 294.669388 L369.292308 294.669388" class="reactive tooltip-trigger" /><path stroke-width="3" d="M354.357692 290.292681 L374.270513 290.292681" class="reactive tooltip-trigger" /><path stroke-width="3" d="M359.335897 285.757113 L369.292308 285.757113" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 294.669388 L364.314103 291.333510" class="reactive tooltip-trigger" /><path stroke-width="2" d="M364.314103 285.757113 L364.314103 289.107216" class="reactive tooltip-trigger" /><rect x="354.35769230769233" y="289.10721600657826" height="2.2262942427404937" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="295.2692292539699" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="364.3141025641026" cy="163.77819225320627" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 38.3820 | |
438 | Q1-1.5IQR: 38.6350 | |
439 | Q1: 40.0420 | |
440 | Median: 40.4810 | |
441 | Q3: 40.9810 | |
442 | Q3+1.5IQR: 42.3940 | |
443 | Max: 93.8420</desc><desc class="x centered">364.3141025641026</desc><desc class="y centered">290.2319816831707</desc><desc class="x_label" /></g></g></g><g class="series serie-16 color-16"><g class="boxes"><g class="box"><path stroke-width="3" d="M381.964103 293.770817 L391.920513 293.770817" class="reactive tooltip-trigger" /><path stroke-width="3" d="M376.985897 289.275555 L396.898718 289.275555" class="reactive tooltip-trigger" /><path stroke-width="3" d="M381.964103 284.600100 L391.920513 284.600100" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 293.770817 L386.942308 290.347211" class="reactive tooltip-trigger" /><path stroke-width="2" d="M386.942308 284.600100 L386.942308 288.064013" class="reactive tooltip-trigger" /><rect x="376.98589743589747" y="288.0640128852203" height="2.2831977994227373" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="295.2407742411244" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="386.94230769230774" cy="180.62591457687702" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 38.3940 | |
444 | Q1-1.5IQR: 39.0140 | |
445 | Q1: 40.4580 | |
446 | Median: 40.9100 | |
447 | Q3: 41.4210 | |
448 | Q3+1.5IQR: 42.8820 | |
449 | Max: 86.7360</desc><desc class="x centered">386.94230769230774</desc><desc class="y centered">289.21153912195115</desc><desc class="x_label" /></g></g></g><g class="series serie-17 color-17"><g class="boxes"><g class="box"><path stroke-width="3" d="M404.592308 292.443092 L414.548718 292.443092" class="reactive tooltip-trigger" /><path stroke-width="3" d="M399.614103 288.784773 L419.526923 288.784773" class="reactive tooltip-trigger" /><path stroke-width="3" d="M404.592308 285.041097 L414.548718 285.041097" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 292.443092 L409.570513 289.699948" class="reactive tooltip-trigger" /><path stroke-width="2" d="M409.570513 285.041097 L409.570513 287.837593" class="reactive tooltip-trigger" /><rect x="399.6141025641026" y="287.8375932687608" height="1.8623542834332625" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="293.178083384228" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="409.5705128205129" cy="254.56296626137404" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 39.2640 | |
450 | Q1-1.5IQR: 39.5740 | |
451 | Q1: 40.7310 | |
452 | Median: 41.1170 | |
453 | Q3: 41.5165 | |
454 | Q3+1.5IQR: 42.6960 | |
455 | Max: 55.5510</desc><desc class="x centered">409.5705128205129</desc><desc class="y centered">288.7613004305215</desc><desc class="x_label" /></g></g></g><g class="series serie-18 color-18"><g class="boxes"><g class="box"><path stroke-width="3" d="M427.220513 291.245782 L437.176923 291.245782" class="reactive tooltip-trigger" /><path stroke-width="3" d="M422.242308 287.407270 L442.155128 287.407270" class="reactive tooltip-trigger" /><path stroke-width="3" d="M427.220513 283.462064 L437.176923 283.462064" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 291.245782 L432.198718 288.350892" class="reactive tooltip-trigger" /><path stroke-width="2" d="M432.198718 283.462064 L432.198718 286.397260" class="reactive tooltip-trigger" /><rect x="422.24230769230775" y="286.39725986089667" height="1.9536319959028674" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="292.36248802059026" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="432.198717948718" cy="157.77028588691695" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 39.6080 | |
456 | Q1-1.5IQR: 40.0790 | |
457 | Q1: 41.3000 | |
458 | Median: 41.6980 | |
459 | Q3: 42.1240 | |
460 | Q3+1.5IQR: 43.3620 | |
461 | Max: 96.3760</desc><desc class="x centered">432.198717948718</desc><desc class="y centered">287.37265353947305</desc><desc class="x_label" /></g></g></g><g class="series serie-19 color-19"><g class="boxes"><g class="box"><path stroke-width="3" d="M449.848718 279.848786 L459.805128 279.848786" class="reactive tooltip-trigger" /><path stroke-width="3" d="M444.870513 276.076664 L464.783333 276.076664" class="reactive tooltip-trigger" /><path stroke-width="3" d="M449.848718 272.254748 L459.805128 272.254748" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 279.848786 L454.826923 277.008425" class="reactive tooltip-trigger" /><path stroke-width="2" d="M454.826923 272.254748 L454.826923 275.109323" class="reactive tooltip-trigger" /><rect x="444.87051282051283" y="275.10932273426" height="1.8991025654060536" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="280.93703702011453" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="454.8269230769231" cy="162.65200684484222" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 44.4270 | |
462 | Q1-1.5IQR: 44.8860 | |
463 | Q1: 46.0840 | |
464 | Median: 46.4770 | |
465 | Q3: 46.8850 | |
466 | Q3+1.5IQR: 48.0890 | |
467 | Max: 94.3170</desc><desc class="x centered">454.8269230769231</desc><desc class="y centered">276.05958905805574</desc><desc class="x_label" /></g></g></g><g class="series serie-20 color-20"><g class="boxes"><g class="box"><path stroke-width="3" d="M472.476923 266.453108 L482.433333 266.453108" class="reactive tooltip-trigger" /><path stroke-width="3" d="M467.498718 261.590354 L487.411538 261.590354" class="reactive tooltip-trigger" /><path stroke-width="3" d="M472.476923 256.585360 L482.433333 256.585360" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 266.453108 L477.455128 262.781150" class="reactive tooltip-trigger" /><path stroke-width="2" d="M477.455128 256.585360 L477.455128 260.310066" class="reactive tooltip-trigger" /><rect x="467.49871794871797" y="260.31006591739924" height="2.4710836875138398" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="267.58878100643057" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="477.45512820512823" cy="224.9596957499367" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 50.0570 | |
468 | Q1-1.5IQR: 50.5360 | |
469 | Q1: 52.0848 | |
470 | Median: 52.5870 | |
471 | Q3: 53.1270 | |
472 | Q3+1.5IQR: 54.6980 | |
473 | Max: 68.0370</desc><desc class="x centered">477.45512820512823</desc><desc class="y centered">261.54400732840884</desc><desc class="x_label" /></g></g></g><g class="series serie-21 color-21"><g class="boxes"><g class="box"><path stroke-width="3" d="M495.105128 265.051903 L505.061538 265.051903" class="reactive tooltip-trigger" /><path stroke-width="3" d="M490.126923 260.037412 L510.039744 260.037412" class="reactive tooltip-trigger" /><path stroke-width="3" d="M495.105128 254.963648 L505.061538 254.963648" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 265.051903 L500.083333 261.301112" class="reactive tooltip-trigger" /><path stroke-width="2" d="M500.083333 254.963648 L500.083333 258.766597" class="reactive tooltip-trigger" /><rect x="490.1269230769231" y="258.7665971041558" height="2.534514473953834" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="266.05716988609686" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="500.08333333333337" cy="191.31638268720812" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 50.7030 | |
474 | Q1-1.5IQR: 51.1270 | |
475 | Q1: 52.7090 | |
476 | Median: 53.2420 | |
477 | Q3: 53.7780 | |
478 | Q3+1.5IQR: 55.3820 | |
479 | Max: 82.2270</desc><desc class="x centered">500.08333333333337</desc><desc class="y centered">260.02413443995795</desc><desc class="x_label" /></g></g></g><g class="series serie-22 color-22"><g class="boxes"><g class="box"><path stroke-width="3" d="M517.733333 262.296899 L527.689744 262.296899" class="reactive tooltip-trigger" /><path stroke-width="3" d="M512.755128 256.815328 L532.667949 256.815328" class="reactive tooltip-trigger" /><path stroke-width="3" d="M517.733333 251.068235 L527.689744 251.068235" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 262.296899 L522.711538 258.199946" class="reactive tooltip-trigger" /><path stroke-width="2" d="M522.711538 251.068235 L522.711538 255.404636" class="reactive tooltip-trigger" /><rect x="512.7551282051282" y="255.40463604266313" height="2.7953104025368134" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="263.7858319359201" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="522.7115384615385" cy="116.947839498435" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 51.6610 | |
480 | Q1-1.5IQR: 52.2890 | |
481 | Q1: 54.0170 | |
482 | Median: 54.6010 | |
483 | Q3: 55.1960 | |
484 | Q3+1.5IQR: 57.0250 | |
485 | Max: 113.5940</desc><desc class="x centered">522.7115384615385</desc><desc class="y centered">256.7570090457086</desc><desc class="x_label" /></g></g></g><g class="series serie-23 color-23"><g class="boxes"><g class="box"><path stroke-width="3" d="M540.361538 263.219173 L550.317949 263.219173" class="reactive tooltip-trigger" /><path stroke-width="3" d="M535.383333 256.879346 L555.296154 256.879346" class="reactive tooltip-trigger" /><path stroke-width="3" d="M540.361538 250.418600 L550.317949 250.418600" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 263.219173 L545.339744 258.429926" class="reactive tooltip-trigger" /><path stroke-width="2" d="M545.339744 250.418600 L545.339744 255.233930" class="reactive tooltip-trigger" /><rect x="535.3833333333333" y="255.23392968528887" height="3.195996487480585" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="263.3566951508034" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="545.3397435897435" cy="158.08798321584595" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 51.8420 | |
486 | Q1-1.5IQR: 51.9000 | |
487 | Q1: 53.9200 | |
488 | Median: 54.5740 | |
489 | Q3: 55.2680 | |
490 | Q3+1.5IQR: 57.2990 | |
491 | Max: 96.2420</desc><desc class="x centered">545.3397435897435</desc><desc class="y centered">256.8361948871542</desc><desc class="x_label" /></g></g></g><g class="series serie-24 color-24"><g class="boxes"><g class="box"><path stroke-width="3" d="M562.989744 250.359327 L572.946154 250.359327" class="reactive tooltip-trigger" /><path stroke-width="3" d="M558.011538 244.922806 L577.924359 244.922806" class="reactive tooltip-trigger" /><path stroke-width="3" d="M562.989744 239.400947 L572.946154 239.400947" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 250.359327 L567.967949 246.270090" class="reactive tooltip-trigger" /><path stroke-width="2" d="M567.967949 239.400947 L567.967949 243.525753" class="reactive tooltip-trigger" /><rect x="558.0115384615385" y="243.52575281680618" height="2.7443367704776165" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="251.525818438358" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="567.9679487179487" cy="102.89779092180538" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 56.8320 | |
492 | Q1-1.5IQR: 57.3240 | |
493 | Q1: 59.0487 | |
494 | Median: 59.6170 | |
495 | Q3: 60.2062 | |
496 | Q3+1.5IQR: 61.9460 | |
497 | Max: 119.5200</desc><desc class="x centered">567.9679487179487</desc><desc class="y centered">244.8957844884781</desc><desc class="x_label" /></g></g></g><g class="series serie-25 color-25"><g class="boxes"><g class="box"><path stroke-width="3" d="M585.617949 245.027139 L595.574359 245.027139" class="reactive tooltip-trigger" /><path stroke-width="3" d="M580.639744 239.462592 L600.552564 239.462592" class="reactive tooltip-trigger" /><path stroke-width="3" d="M585.617949 233.592208 L595.574359 233.592208" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 245.027139 L590.596154 240.828234" class="reactive tooltip-trigger" /><path stroke-width="2" d="M590.596154 233.592208 L590.596154 237.936316" class="reactive tooltip-trigger" /><rect x="580.6397435897436" y="237.9363158403209" height="2.8919185781584247" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="245.50131690846922" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="590.5961538461538" cy="116.7534242242499" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 59.3730 | |
498 | Q1-1.5IQR: 59.5730 | |
499 | Q1: 61.3440 | |
500 | Median: 61.9200 | |
501 | Q3: 62.5637 | |
502 | Q3+1.5IQR: 64.3960 | |
503 | Max: 113.6760</desc><desc class="x centered">590.5961538461538</desc><desc class="y centered">239.36929786672152</desc><desc class="x_label" /></g></g></g><g class="series serie-26 color-26"><g class="boxes"><g class="box"><path stroke-width="3" d="M608.246154 92.984984 L618.202564 92.984984" class="reactive tooltip-trigger" /><path stroke-width="3" d="M603.267949 86.047688 L623.180769 86.047688" class="reactive tooltip-trigger" /><path stroke-width="3" d="M608.246154 78.707321 L618.202564 78.707321" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 92.984984 L613.224359 87.773121" class="reactive tooltip-trigger" /><path stroke-width="2" d="M613.224359 78.707321 L613.224359 84.224445" class="reactive tooltip-trigger" /><rect x="603.2679487179488" y="84.22444534598424" height="3.5486760590127346" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="94.82244113357626" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="613.224358974359" cy="-187.15305636789526" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 122.9260 | |
504 | Q1-1.5IQR: 123.7010 | |
505 | Q1: 125.8992 | |
506 | Median: 126.6270 | |
507 | Q3: 127.3960 | |
508 | Q3+1.5IQR: 129.7230 | |
509 | Max: 241.8570</desc><desc class="x centered">613.224358974359</desc><desc class="y centered">85.94751195339848</desc><desc class="x_label" /></g></g></g><g class="series serie-27 color-27"><g class="boxes"><g class="box"><path stroke-width="3" d="M630.874359 86.552693 L640.830769 86.552693" class="reactive tooltip-trigger" /><path stroke-width="3" d="M625.896154 79.997103 L645.808974 79.997103" class="reactive tooltip-trigger" /><path stroke-width="3" d="M630.874359 72.789515 L640.830769 72.789515" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 86.552693 L635.852564 81.640145" class="reactive tooltip-trigger" /><path stroke-width="2" d="M635.852564 72.789515 L635.852564 78.134154" class="reactive tooltip-trigger" /><rect x="625.8961538461539" y="78.13415399782366" height="3.505991383408343" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="87.79030956105879" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="635.8525641025641" cy="-203.2492092631668" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 125.8920 | |
510 | Q1-1.5IQR: 126.4140 | |
511 | Q1: 128.4860 | |
512 | Median: 129.1790 | |
513 | Q3: 129.9648 | |
514 | Q3+1.5IQR: 132.2190 | |
515 | Max: 248.6460</desc><desc class="x centered">635.8525641025641</desc><desc class="y centered">79.82272224448394</desc><desc class="x_label" /></g></g></g><g class="series serie-28 color-28"><g class="boxes"><g class="box"><path stroke-width="3" d="M653.502564 41.870388 L663.458974 41.870388" class="reactive tooltip-trigger" /><path stroke-width="3" d="M648.524359 34.769495 L668.437179 34.769495" class="reactive tooltip-trigger" /><path stroke-width="3" d="M653.502564 27.376971 L663.458974 27.376971" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 41.870388 L658.480769 36.499071" class="reactive tooltip-trigger" /><path stroke-width="2" d="M658.480769 27.376971 L658.480769 32.868607" class="reactive tooltip-trigger" /><rect x="648.524358974359" y="32.868607003257466" height="3.630463735749288" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="44.42386944457104" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="658.4807692307692" cy="-222.35168299875966" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 144.1830 | |
516 | Q1-1.5IQR: 145.2600 | |
517 | Q1: 147.5255 | |
518 | Median: 148.2550 | |
519 | Q3: 149.0568 | |
520 | Q3+1.5IQR: 151.3730 | |
521 | Max: 256.7030</desc><desc class="x centered">658.4807692307692</desc><desc class="y centered">34.67690625016377</desc><desc class="x_label" /></g></g></g><g class="series serie-29 color-29"><g class="boxes"><g class="box"><path stroke-width="3" d="M676.130769 21.549265 L686.087179 21.549265" class="reactive tooltip-trigger" /><path stroke-width="3" d="M671.152564 14.519488 L691.065385 14.519488" class="reactive tooltip-trigger" /><path stroke-width="3" d="M676.130769 7.340355 L686.087179 7.340355" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 21.549265 L681.108974 16.247893" class="reactive tooltip-trigger" /><path stroke-width="2" d="M681.108974 7.340355 L681.108974 12.699819" class="reactive tooltip-trigger" /><rect x="671.1525641025642" y="12.699818534630424" height="3.5480744412055287" width="19.912820512820513" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="22.229718455465274" r="3" class="subtle-fill reactive tooltip-trigger" /><circle cx="681.1089743589744" cy="-5475.27897892072" r="3" class="subtle-fill reactive tooltip-trigger" /><desc class="value">Min: 153.5440 | |
522 | Q1-1.5IQR: 153.8310 | |
523 | Q1: 156.0670 | |
524 | Median: 156.7960 | |
525 | Q3: 157.5635 | |
526 | Q3+1.5IQR: 159.8240 | |
527 | Max: 2472.2710</desc><desc class="x centered">681.1089743589744</desc><desc class="y centered">14.471363893089801</desc><desc class="x_label" /></g></g></g></g><g class="titles"><text x="400.0" y="26" class="title plot_title">Speed in Microseconds (us)</text><text x="427.0" y="580.0" class="title">Trial</text><text x="0" y="252.0" class="title" transform="rotate(-90 0.000000 226.000000)">Duration</text></g><g transform="translate(74, 46)" class="plot overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot text-overlay"><g class="series serie-0 color-0" /><g class="series serie-1 color-1" /><g class="series serie-2 color-2" /><g class="series serie-3 color-3" /><g class="series serie-4 color-4" /><g class="series serie-5 color-5" /><g class="series serie-6 color-6" /><g class="series serie-7 color-7" /><g class="series serie-8 color-8" /><g class="series serie-9 color-9" /><g class="series serie-10 color-10" /><g class="series serie-11 color-11" /><g class="series serie-12 color-12" /><g class="series serie-13 color-13" /><g class="series serie-14 color-14" /><g class="series serie-15 color-15" /><g class="series serie-16 color-16" /><g class="series serie-17 color-17" /><g class="series serie-18 color-18" /><g class="series serie-19 color-19" /><g class="series serie-20 color-20" /><g class="series serie-21 color-21" /><g class="series serie-22 color-22" /><g class="series serie-23 color-23" /><g class="series serie-24 color-24" /><g class="series serie-25 color-25" /><g class="series serie-26 color-26" /><g class="series serie-27 color-27" /><g class="series serie-28 color-28" /><g class="series serie-29 color-29" /></g><g transform="translate(74, 46)" class="plot tooltip-overlay"><g transform="translate(0 0)" style="opacity: 0" class="tooltip"><rect rx="0" ry="0" width="0" height="0" class="tooltip-box" /><g class="text" /></g></g></g></svg>⏎ |
10 | 10 | |
11 | 11 | .. warning:: |
12 | 12 | |
13 | jsonpickle can execute arbitrary Python code. Do not load jsonpickles from | |
14 | untrusted / unauthenticated sources. | |
13 | The jsonpickle module **is not secure**. Only unpickle data you trust. | |
14 | ||
15 | It is possible to construct malicious pickle data which will **execute | |
16 | arbitrary code during unpickling**. Never unpickle data that could have come | |
17 | from an untrusted source, or that could have been tampered with. | |
18 | ||
19 | Consider signing data with an HMAC if you need to ensure that it has not | |
20 | been tampered with. | |
21 | ||
22 | Safer deserialization approaches, such as reading the raw JSON | |
23 | directly, may be more appropriate if you are processing untrusted data. | |
15 | 24 | |
16 | 25 | jsonpickle can take almost any Python object and turn the object into JSON. |
17 | 26 | Additionally, it can reconstitute the object back into Python. |
51 | 60 | result = jsonpickle.decode(oneway) |
52 | 61 | assert obj.name == result['name'] == 'Awesome' |
53 | 62 | |
63 | .. note:: | |
64 | ||
65 | Please see the note in the :ref:`api-docs` when serializing dictionaries | |
66 | that contain non-string dictionary keys. | |
67 | ||
54 | 68 | """ |
55 | 69 | from __future__ import absolute_import, division, unicode_literals |
56 | 70 | |
57 | from .backend import json | |
58 | from .pickler import encode | |
59 | from .unpickler import decode | |
60 | ||
61 | 71 | # Export other names not in __all__ |
62 | 72 | from .backend import JSONBackend # noqa: F401 |
63 | from .version import __version__ # noqa: F401 | |
73 | from .backend import json | |
64 | 74 | from .handlers import register # noqa: F401 |
65 | 75 | from .handlers import unregister # noqa: F401 |
66 | 76 | from .pickler import Pickler # noqa: F401 |
77 | from .pickler import encode | |
67 | 78 | from .unpickler import Unpickler # noqa: F401 |
79 | from .unpickler import decode | |
80 | from .version import __version__ # noqa: F401 | |
68 | 81 | |
69 | 82 | __all__ = ('encode', 'decode') |
70 | 83 |
0 | 0 | from __future__ import absolute_import, division, unicode_literals |
1 | 1 | |
2 | 2 | from .compat import string_types |
3 | from .compat import PY3_ORDERED_DICT | |
4 | 3 | |
5 | 4 | |
6 | 5 | class JSONBackend(object): |
7 | 6 | """Manages encoding and decoding using various backends. |
8 | 7 | |
9 | 8 | It tries these modules in this order: |
10 | simplejson, json, demjson | |
9 | simplejson, json, ujson | |
11 | 10 | |
12 | 11 | simplejson is a fast and popular backend and is tried first. |
13 | 12 | json comes with Python and is tried second. |
14 | demjson is the most permissive backend and is tried last. | |
15 | 13 | |
16 | 14 | """ |
17 | ||
18 | def __init__(self, fallthrough=True): | |
19 | # Whether we should fallthrough to the next backend | |
20 | self._fallthrough = fallthrough | |
21 | # The names of backends that have been successfully imported | |
22 | self._backend_names = [] | |
23 | ||
24 | # A dictionary mapping backend names to encode/decode functions | |
25 | self._encoders = {} | |
26 | self._decoders = {} | |
27 | ||
28 | # Options to pass to specific encoders | |
29 | self._encoder_options = {} | |
30 | ||
31 | # Options to pass to specific decoders | |
32 | self._decoder_options = {} | |
33 | ||
34 | # The exception class that is thrown when a decoding error occurs | |
35 | self._decoder_exceptions = {} | |
36 | ||
37 | # Whether we've loaded any backends successfully | |
38 | self._verified = False | |
39 | ||
40 | self.load_backend('simplejson') | |
41 | self.load_backend('json') | |
42 | self.load_backend('demjson', 'encode', 'decode', 'JSONDecodeError') | |
43 | self.load_backend('jsonlib', 'write', 'read', 'ReadError') | |
44 | self.load_backend('yajl') | |
45 | self.load_backend('ujson') | |
46 | ||
47 | # Defaults for various encoders | |
48 | sort = not PY3_ORDERED_DICT | |
49 | json_opts = ((), {'sort_keys': sort}) | |
50 | self._encoder_options = { | |
51 | 'ujson': ((), {'sort_keys': sort, 'escape_forward_slashes': False}), | |
52 | 'json': json_opts, | |
53 | 'simplejson': json_opts, | |
54 | 'django.util.simplejson': json_opts, | |
55 | } | |
56 | 15 | |
57 | 16 | def _verify(self): |
58 | 17 | """Ensures that we've loaded at least one JSON backend.""" |
61 | 20 | raise AssertionError( |
62 | 21 | 'jsonpickle requires at least one of the ' |
63 | 22 | 'following:\n' |
64 | ' python2.6, simplejson, or demjson' | |
23 | ' python2.6, simplejson' | |
65 | 24 | ) |
25 | ||
26 | def encode(self, obj, indent=None, separators=None): | |
27 | """ | |
28 | Attempt to encode an object into JSON. | |
29 | ||
30 | This tries the loaded backends in order and passes along the last | |
31 | exception if no backend is able to encode the object. | |
32 | ||
33 | """ | |
34 | self._verify() | |
35 | ||
36 | if not self._fallthrough: | |
37 | name = self._backend_names[0] | |
38 | return self.backend_encode(name, obj, indent=indent, separators=separators) | |
39 | ||
40 | for idx, name in enumerate(self._backend_names): | |
41 | try: | |
42 | return self.backend_encode( | |
43 | name, obj, indent=indent, separators=separators | |
44 | ) | |
45 | except Exception as e: | |
46 | if idx == len(self._backend_names) - 1: | |
47 | raise e | |
48 | ||
49 | # def dumps | |
50 | dumps = encode | |
51 | ||
52 | def decode(self, string): | |
53 | """ | |
54 | Attempt to decode an object from a JSON string. | |
55 | ||
56 | This tries the loaded backends in order and passes along the last | |
57 | exception if no backends are able to decode the string. | |
58 | ||
59 | """ | |
60 | self._verify() | |
61 | ||
62 | if not self._fallthrough: | |
63 | name = self._backend_names[0] | |
64 | return self.backend_decode(name, string) | |
65 | ||
66 | for idx, name in enumerate(self._backend_names): | |
67 | try: | |
68 | return self.backend_decode(name, string) | |
69 | except self._decoder_exceptions[name] as e: | |
70 | if idx == len(self._backend_names) - 1: | |
71 | raise e | |
72 | else: | |
73 | pass # and try a more forgiving encoder | |
74 | ||
75 | # def loads | |
76 | loads = decode | |
77 | ||
78 | def __init__(self, fallthrough=True): | |
79 | # Whether we should fallthrough to the next backend | |
80 | self._fallthrough = fallthrough | |
81 | # The names of backends that have been successfully imported | |
82 | self._backend_names = [] | |
83 | ||
84 | # A dictionary mapping backend names to encode/decode functions | |
85 | self._encoders = {} | |
86 | self._decoders = {} | |
87 | ||
88 | # Options to pass to specific encoders | |
89 | self._encoder_options = {} | |
90 | ||
91 | # Options to pass to specific decoders | |
92 | self._decoder_options = {} | |
93 | ||
94 | # The exception class that is thrown when a decoding error occurs | |
95 | self._decoder_exceptions = {} | |
96 | ||
97 | # Whether we've loaded any backends successfully | |
98 | self._verified = False | |
99 | ||
100 | self.load_backend('simplejson') | |
101 | self.load_backend('json') | |
102 | self.load_backend('ujson') | |
103 | ||
104 | # Defaults for various encoders | |
105 | json_opts = ((), {'sort_keys': False}) | |
106 | self._encoder_options = { | |
107 | 'ujson': ((), {'sort_keys': False, 'escape_forward_slashes': False}), | |
108 | 'json': json_opts, | |
109 | 'simplejson': json_opts, | |
110 | 'django.util.simplejson': json_opts, | |
111 | } | |
66 | 112 | |
67 | 113 | def enable_fallthrough(self, enable): |
68 | 114 | """ |
80 | 126 | |
81 | 127 | """ |
82 | 128 | self._fallthrough = enable |
129 | ||
130 | def _store(self, dct, backend, obj, name): | |
131 | try: | |
132 | dct[backend] = getattr(obj, name) | |
133 | except AttributeError: | |
134 | self.remove_backend(backend) | |
135 | return False | |
136 | return True | |
83 | 137 | |
84 | 138 | def load_backend(self, name, dumps='dumps', loads='loads', loads_exc=ValueError): |
85 | 139 | |
151 | 205 | self._backend_names.remove(name) |
152 | 206 | self._verified = bool(self._backend_names) |
153 | 207 | |
154 | def encode(self, obj, indent=None, separators=None): | |
155 | """ | |
156 | Attempt to encode an object into JSON. | |
157 | ||
158 | This tries the loaded backends in order and passes along the last | |
159 | exception if no backend is able to encode the object. | |
160 | ||
161 | """ | |
162 | self._verify() | |
163 | ||
164 | if not self._fallthrough: | |
165 | name = self._backend_names[0] | |
166 | return self.backend_encode(name, obj, indent=indent, separators=separators) | |
167 | ||
168 | for idx, name in enumerate(self._backend_names): | |
169 | try: | |
170 | return self.backend_encode( | |
171 | name, obj, indent=indent, separators=separators | |
172 | ) | |
173 | except Exception as e: | |
174 | if idx == len(self._backend_names) - 1: | |
175 | raise e | |
176 | ||
177 | # def dumps | |
178 | dumps = encode | |
179 | ||
180 | 208 | def backend_encode(self, name, obj, indent=None, separators=None): |
181 | 209 | optargs, optkwargs = self._encoder_options.get(name, ([], {})) |
182 | 210 | encoder_kwargs = optkwargs.copy() |
187 | 215 | encoder_args = (obj,) + tuple(optargs) |
188 | 216 | return self._encoders[name](*encoder_args, **encoder_kwargs) |
189 | 217 | |
190 | def decode(self, string): | |
191 | """ | |
192 | Attempt to decode an object from a JSON string. | |
193 | ||
194 | This tries the loaded backends in order and passes along the last | |
195 | exception if no backends are able to decode the string. | |
196 | ||
197 | """ | |
198 | self._verify() | |
199 | ||
200 | if not self._fallthrough: | |
201 | name = self._backend_names[0] | |
202 | return self.backend_decode(name, string) | |
203 | ||
204 | for idx, name in enumerate(self._backend_names): | |
205 | try: | |
206 | return self.backend_decode(name, string) | |
207 | except self._decoder_exceptions[name] as e: | |
208 | if idx == len(self._backend_names) - 1: | |
209 | raise e | |
210 | else: | |
211 | pass # and try a more forgiving encoder, e.g. demjson | |
212 | ||
213 | # def loads | |
214 | loads = decode | |
215 | ||
216 | 218 | def backend_decode(self, name, string): |
217 | 219 | optargs, optkwargs = self._decoder_options.get(name, ((), {})) |
218 | 220 | decoder_kwargs = optkwargs.copy() |
230 | 232 | set_preferred_backend('simplejson') |
231 | 233 | |
232 | 234 | If the backend is not one of the built-in jsonpickle backends |
233 | (json/simplejson, or demjson) then you must load the backend | |
235 | (json/simplejson) then you must load the backend | |
234 | 236 | prior to calling set_preferred_backend. |
235 | 237 | |
236 | 238 | AssertionError is raised if the backend has not been loaded. |
254 | 256 | For example:: |
255 | 257 | |
256 | 258 | set_encoder_options('simplejson', sort_keys=True, indent=4) |
257 | set_encoder_options('demjson', compactly=False) | |
258 | 259 | |
259 | 260 | See the appropriate encoder's documentation for details about |
260 | 261 | the supported arguments and keyword arguments. |
261 | 262 | |
263 | WARNING: If you pass sort_keys=True, and the object to encode | |
264 | contains ``__slots__``, and you set ``warn`` to True, | |
265 | a TypeError will be raised! | |
262 | 266 | """ |
263 | 267 | self._encoder_options[name] = (args, kwargs) |
264 | 268 | |
273 | 277 | For example:: |
274 | 278 | |
275 | 279 | set_decoder_options('simplejson', encoding='utf8', cls=JSONDecoder) |
276 | set_decoder_options('demjson', strict=True) | |
277 | 280 | |
278 | 281 | See the appropriate decoder's documentation for details about |
279 | 282 | the supported arguments and keyword arguments. |
281 | 284 | """ |
282 | 285 | self._decoder_options[name] = (args, kwargs) |
283 | 286 | |
284 | def _store(self, dct, backend, obj, name): | |
285 | try: | |
286 | dct[backend] = getattr(obj, name) | |
287 | except AttributeError: | |
288 | self.remove_backend(backend) | |
289 | return False | |
290 | return True | |
291 | ||
292 | 287 | |
293 | 288 | json = JSONBackend() |
0 | 0 | from __future__ import absolute_import, division, unicode_literals |
1 | ||
2 | import queue # noqa | |
1 | 3 | import sys |
2 | import types | |
3 | import base64 | |
4 | from collections.abc import Iterator as abc_iterator # noqa | |
4 | 5 | |
5 | 6 | PY_MAJOR = sys.version_info[0] |
6 | PY2 = PY_MAJOR == 2 | |
7 | PY3 = PY_MAJOR == 3 | |
8 | PY3_ORDERED_DICT = PY3 and sys.version_info[1] >= 6 # Python 3.6+ | |
9 | 7 | |
10 | 8 | class_types = (type,) |
11 | 9 | iterator_types = (type(iter('')),) |
12 | 10 | |
13 | if PY3: | |
14 | import builtins | |
15 | import queue | |
16 | from base64 import encodebytes, decodebytes | |
17 | from collections.abc import Iterator as abc_iterator | |
18 | ||
19 | string_types = (str,) | |
20 | numeric_types = (int, float) | |
21 | ustr = str | |
22 | else: | |
23 | from collections import Iterator as abc_iterator # noqa | |
24 | ||
25 | builtins = __import__('__builtin__') | |
26 | class_types += (types.ClassType,) | |
27 | encodebytes = base64.encodestring | |
28 | decodebytes = base64.decodestring | |
29 | string_types = (builtins.basestring,) | |
30 | numeric_types = (int, float, builtins.long) | |
31 | queue = __import__('Queue') | |
32 | ustr = builtins.unicode | |
11 | string_types = (str,) | |
12 | numeric_types = (int, float) | |
13 | ustr = str | |
33 | 14 | |
34 | 15 | |
35 | 16 | def iterator(class_): |
36 | if PY2 and hasattr(class_, '__next__'): | |
37 | class_.next = class_.__next__ | |
17 | # TODO: Replace all instances of this | |
38 | 18 | return class_ |
0 | """ | |
1 | Stores custom jsonpickle errors. | |
2 | """ | |
3 | ||
4 | ||
5 | class ClassNotFoundError(BaseException): | |
6 | def __init__(*args, **kwargs): | |
7 | pass |
0 | import gmpy2 as gmpy | |
1 | ||
2 | from ..handlers import BaseHandler, register, unregister | |
3 | ||
4 | __all__ = ['register_handlers', 'unregister_handlers'] | |
5 | ||
6 | ||
7 | class GmpyMPZHandler(BaseHandler): | |
8 | def flatten(self, obj, data): | |
9 | data['int'] = int(obj) | |
10 | return data | |
11 | ||
12 | def restore(self, data): | |
13 | return gmpy.mpz(data['int']) | |
14 | ||
15 | ||
16 | def register_handlers(): | |
17 | register(gmpy.mpz, GmpyMPZHandler, base=True) | |
18 | ||
19 | ||
20 | def unregister_handlers(): | |
21 | unregister(gmpy.mpz) |
0 | 0 | from __future__ import absolute_import |
1 | ||
1 | 2 | import ast |
3 | import json | |
2 | 4 | import sys |
5 | import warnings | |
3 | 6 | import zlib |
4 | import warnings | |
5 | import json | |
6 | 7 | |
7 | 8 | import numpy as np |
8 | 9 | |
10 | from .. import compat | |
11 | from ..compat import numeric_types | |
9 | 12 | from ..handlers import BaseHandler, register, unregister |
10 | from ..compat import numeric_types | |
11 | 13 | from ..util import b64decode, b64encode |
12 | from .. import compat | |
13 | ||
14 | 14 | |
15 | 15 | __all__ = ['register_handlers', 'unregister_handlers'] |
16 | 16 | |
59 | 59 | def restore(self, data): |
60 | 60 | value = self.context.restore(data['value'], reset=False) |
61 | 61 | return self.restore_dtype(data).type(value) |
62 | ||
63 | ||
64 | class UnpickleableNumpyGenericHandler(NumpyGenericHandler): | |
65 | """ | |
66 | From issue #381, this is used for simplifying the output of numpy arrays | |
67 | when unpicklable=False (the default is True). | |
68 | """ | |
69 | ||
70 | def flatten(self, obj, data): | |
71 | if not self.context.unpicklable: | |
72 | return self.context.flatten(obj.tolist(), reset=False) | |
73 | else: | |
74 | return super(NumpyGenericHandler, self).flatten(obj, data) | |
75 | ||
76 | def restore(self, data): | |
77 | raise NotImplementedError | |
62 | 78 | |
63 | 79 | |
64 | 80 | class NumpyNDArrayHandler(NumpyBaseHandler): |
113 | 129 | if size_threshold is None, values are always stored as nested lists |
114 | 130 | :param compression: a compression module or None |
115 | 131 | valid values for 'compression' are {zlib, bz2, None} |
116 | if compresion is None, no compression is applied | |
132 | if compression is None, no compression is applied | |
117 | 133 | """ |
118 | 134 | self.size_threshold = size_threshold |
119 | 135 | self.compression = compression |
135 | 151 | data = super(NumpyNDArrayHandlerBinary, self).flatten(obj, data) |
136 | 152 | else: |
137 | 153 | # encode as binary |
138 | if obj.dtype == np.object: | |
154 | if obj.dtype == object: | |
139 | 155 | # There's a bug deep in the bowels of numpy that causes a |
140 | 156 | # segfault when round-tripping an ndarray of dtype object. |
141 | 157 | # E.g., the following will result in a segfault: |
142 | 158 | # import numpy as np |
143 | 159 | # arr = np.array([str(i) for i in range(3)], |
144 | # dtype=np.object) | |
160 | # dtype=object) | |
145 | 161 | # dtype = arr.dtype |
146 | 162 | # shape = arr.shape |
147 | 163 | # buf = arr.tobytes() |
187 | 203 | buf = self.compression.decompress(buf) |
188 | 204 | # See note above about segfault bug for numpy dtype object. Those |
189 | 205 | # are saved as a list to work around that. |
190 | if dtype == np.object: | |
206 | if dtype == object: | |
191 | 207 | values = json.loads(buf.decode()) |
192 | 208 | arr = np.array(values, dtype=dtype, order=data.get('order', 'C')) |
193 | 209 | shape = data.get('shape', None) |
231 | 247 | def __init__(self, mode='warn', size_threshold=16, compression=zlib): |
232 | 248 | """ |
233 | 249 | :param mode: {'warn', 'raise', 'ignore'} |
234 | How to react when encountering array-like objects whos | |
250 | How to react when encountering array-like objects whose | |
235 | 251 | references we cannot safely serialize |
236 | 252 | :param size_threshold: nonnegative int or None |
237 | 253 | valid values for 'size_threshold' are all nonnegative |
239 | 255 | if size_threshold is None, values are always stored as nested lists |
240 | 256 | :param compression: a compression module or None |
241 | 257 | valid values for 'compression' are {zlib, bz2, None} |
242 | if compresion is None, no compression is applied | |
258 | if compression is None, no compression is applied | |
243 | 259 | """ |
244 | 260 | super(NumpyNDArrayHandlerView, self).__init__(size_threshold, compression) |
245 | 261 | self.mode = mode |
0 | 0 | from __future__ import absolute_import |
1 | 1 | |
2 | import zlib | |
3 | from io import StringIO | |
4 | ||
2 | 5 | import pandas as pd |
3 | from io import StringIO | |
4 | import zlib | |
5 | ||
6 | from .. import encode, decode | |
6 | ||
7 | from .. import decode, encode | |
7 | 8 | from ..handlers import BaseHandler, register, unregister |
8 | 9 | from ..util import b64decode, b64encode |
9 | 10 | from .numpy import register_handlers as register_numpy_handlers |
21 | 22 | dataframes are always stored as csv strings |
22 | 23 | :param compression: a compression module or None |
23 | 24 | valid values for 'compression' are {zlib, bz2, None} |
24 | if compresion is None, no compression is applied | |
25 | if compression is None, no compression is applied | |
25 | 26 | """ |
26 | 27 | self.size_threshold = size_threshold |
27 | 28 | self.compression = compression |
158 | 159 | def restore(self, data): |
159 | 160 | buf, meta = self.pp.restore_pandas(data) |
160 | 161 | dtype = meta.get('dtype', None) |
161 | name_bundle = {k: v for k, v in meta.items() if k in {'name', 'names'}} | |
162 | name_bundle = { | |
163 | 'name': (tuple if v is not None else lambda x: x)(v) | |
164 | for k, v in meta.items() | |
165 | if k in {'name', 'names'} | |
166 | } | |
162 | 167 | idx = self.index_constructor(decode(buf), dtype=dtype, **name_bundle) |
163 | 168 | return idx |
164 | 169 |
7 | 7 | |
8 | 8 | """ |
9 | 9 | from __future__ import absolute_import, division, unicode_literals |
10 | ||
10 | 11 | import array |
11 | 12 | import copy |
12 | 13 | import datetime |
16 | 17 | import threading |
17 | 18 | import uuid |
18 | 19 | |
19 | from . import compat | |
20 | from . import util | |
20 | from . import compat, util | |
21 | 21 | |
22 | 22 | |
23 | 23 | class Registry(object): |
99 | 99 | """ |
100 | 100 | self.context = context |
101 | 101 | |
102 | def __call__(self, context): | |
103 | """This permits registering either Handler instances or classes | |
104 | ||
105 | :Parameters: | |
106 | - `context`: reference to pickler/unpickler | |
107 | """ | |
108 | self.context = context | |
109 | return self | |
110 | ||
111 | 102 | def flatten(self, obj, data): |
112 | 103 | """ |
113 | 104 | Flatten `obj` into a json-friendly form and write result to `data`. |
139 | 130 | """ |
140 | 131 | registry.register(cls, self) |
141 | 132 | return cls |
133 | ||
134 | def __call__(self, context): | |
135 | """This permits registering either Handler instances or classes | |
136 | ||
137 | :Parameters: | |
138 | - `context`: reference to pickler/unpickler | |
139 | """ | |
140 | self.context = context | |
141 | return self | |
142 | 142 | |
143 | 143 | |
144 | 144 | class ArrayHandler(BaseHandler): |
4 | 4 | # This software is licensed as described in the file COPYING, which |
5 | 5 | # you should have received as part of this distribution. |
6 | 6 | from __future__ import absolute_import, division, unicode_literals |
7 | ||
7 | 8 | import decimal |
9 | import inspect | |
10 | import itertools | |
11 | import sys | |
8 | 12 | import warnings |
9 | import sys | |
10 | import types | |
11 | 13 | from itertools import chain, islice |
12 | 14 | |
13 | from . import compat | |
14 | from . import util | |
15 | from . import tags | |
16 | from . import handlers | |
15 | from . import compat, handlers, tags, util | |
17 | 16 | from .backend import json |
18 | from .compat import numeric_types, string_types, PY3, PY2 | |
17 | from .compat import numeric_types, string_types | |
19 | 18 | |
20 | 19 | |
21 | 20 | def encode( |
35 | 34 | fail_safe=None, |
36 | 35 | indent=None, |
37 | 36 | separators=None, |
37 | include_properties=False, | |
38 | 38 | ): |
39 | 39 | """Return a JSON formatted representation of value, a Python object. |
40 | 40 | |
41 | :param unpicklable: If set to False then the output will not contain the | |
41 | :param unpicklable: If set to ``False`` then the output will not contain the | |
42 | 42 | information necessary to turn the JSON data back into Python objects, |
43 | but a simpler JSON stream is produced. | |
43 | but a simpler JSON stream is produced. It's recommended to set this | |
44 | parameter to ``False`` when your code does not rely on two objects | |
45 | having the same ``id()`` value, and when it is sufficient for those two | |
46 | objects to be equal by ``==``, such as when serializing sklearn | |
47 | instances. If you experience (de)serialization being incorrect when you | |
48 | use numpy, pandas, or sklearn handlers, this should be set to ``False``. | |
49 | If you want the output to not include the dtype for numpy arrays, add | |
50 | ``jsonpickle.register(numpy.generic, | |
51 | UnpicklableNumpyGenericHandler, base=True)`` before your pickling code. | |
44 | 52 | :param max_depth: If set to a non-negative integer then jsonpickle will |
45 | 53 | not recurse deeper than 'max_depth' steps into the object. Anything |
46 | 54 | deeper than 'max_depth' is represented using a Python repr() of the |
99 | 107 | separators. ``(',', ':')`` is the most compact JSON representation. |
100 | 108 | This value is passed directly to the active JSON backend library and |
101 | 109 | not used by jsonpickle directly. |
110 | :param include_properties: | |
111 | Include the names and values of class properties in the generated json. | |
112 | Properties are unpickled properly regardless of this setting, this is | |
113 | meant to be used if processing the json outside of Python. Defaults to | |
114 | ``False``. | |
102 | 115 | |
103 | 116 | >>> encode('my string') == '"my string"' |
104 | 117 | True |
123 | 136 | use_decimal=use_decimal, |
124 | 137 | use_base85=use_base85, |
125 | 138 | fail_safe=fail_safe, |
139 | include_properties=include_properties, | |
126 | 140 | ) |
127 | 141 | return backend.encode( |
128 | 142 | context.flatten(value, reset=reset), indent=indent, separators=separators |
129 | 143 | ) |
144 | ||
145 | ||
146 | def _in_cycle(obj, objs, max_reached, make_refs): | |
147 | """Detect cyclic structures that would lead to infinite recursion""" | |
148 | return ( | |
149 | (max_reached or (not make_refs and id(obj) in objs)) | |
150 | and not util.is_primitive(obj) | |
151 | and not util.is_enum(obj) | |
152 | ) | |
153 | ||
154 | ||
155 | def _mktyperef(obj): | |
156 | """Return a typeref dictionary | |
157 | ||
158 | >>> _mktyperef(AssertionError) == {'py/type': 'builtins.AssertionError'} | |
159 | True | |
160 | ||
161 | """ | |
162 | return {tags.TYPE: util.importable_name(obj)} | |
163 | ||
164 | ||
165 | def _wrap_string_slot(string): | |
166 | """Converts __slots__ = 'a' into __slots__ = ('a',)""" | |
167 | if isinstance(string, string_types): | |
168 | return (string,) | |
169 | return string | |
130 | 170 | |
131 | 171 | |
132 | 172 | class Pickler(object): |
143 | 183 | use_decimal=False, |
144 | 184 | use_base85=False, |
145 | 185 | fail_safe=None, |
186 | include_properties=False, | |
146 | 187 | ): |
147 | 188 | self.unpicklable = unpicklable |
148 | 189 | self.make_refs = make_refs |
150 | 191 | self.keys = keys |
151 | 192 | self.warn = warn |
152 | 193 | self.numeric_keys = numeric_keys |
153 | self.use_base85 = use_base85 and (not PY2) | |
194 | self.use_base85 = use_base85 | |
154 | 195 | # The current recursion depth |
155 | 196 | self._depth = -1 |
156 | 197 | # The maximal recursion depth |
175 | 216 | |
176 | 217 | # ignore exceptions |
177 | 218 | self.fail_safe = fail_safe |
219 | self.include_properties = include_properties | |
220 | ||
221 | def _determine_sort_keys(self): | |
222 | for _, options in self.backend._encoder_options.values(): | |
223 | if options.get("sort_keys", False): | |
224 | # the user has set one of the backends to sort keys | |
225 | return True | |
226 | return False | |
227 | ||
228 | def _sort_attrs(self, obj): | |
229 | if hasattr(obj, "__slots__") and self.warn: | |
230 | # Slots are read-only by default, the only way | |
231 | # to sort keys is to do it in a subclass | |
232 | # and that would require calling the init function | |
233 | # of the parent again. That could cause issues | |
234 | # so we refuse to handle it. | |
235 | raise TypeError( | |
236 | "Objects with __slots__ cannot have their keys reliably sorted by jsonpickle! Please sort the keys in the __slots__ definition instead." | |
237 | ) | |
238 | # Somehow some classes don't have slots or dict | |
239 | elif hasattr(obj, "__dict__"): | |
240 | try: | |
241 | obj.__dict__ = dict(sorted(obj.__dict__.items())) | |
242 | except (TypeError, AttributeError): | |
243 | # Can't set attributes of builtin/extension type | |
244 | pass | |
245 | return obj | |
178 | 246 | |
179 | 247 | def reset(self): |
180 | 248 | self._objs = {} |
220 | 288 | |
221 | 289 | def _getref(self, obj): |
222 | 290 | return {tags.ID: self._objs.get(id(obj))} |
291 | ||
292 | def _flatten(self, obj): | |
293 | if self.unpicklable and self.make_refs: | |
294 | result = self._flatten_impl(obj) | |
295 | else: | |
296 | try: | |
297 | result = self._flattened[id(obj)] | |
298 | except KeyError: | |
299 | result = self._flattened[id(obj)] = self._flatten_impl(obj) | |
300 | return result | |
223 | 301 | |
224 | 302 | def flatten(self, obj, reset=True): |
225 | 303 | """Takes an object and returns a JSON-safe representation of it. |
251 | 329 | """ |
252 | 330 | if reset: |
253 | 331 | self.reset() |
332 | if self._determine_sort_keys(): | |
333 | obj = self._sort_attrs(obj) | |
254 | 334 | return self._flatten(obj) |
255 | 335 | |
256 | def _flatten(self, obj): | |
257 | if self.unpicklable and self.make_refs: | |
258 | result = self._flatten_impl(obj) | |
259 | else: | |
260 | try: | |
261 | result = self._flattened[id(obj)] | |
262 | except KeyError: | |
263 | result = self._flattened[id(obj)] = self._flatten_impl(obj) | |
264 | return result | |
336 | def _flatten_bytestring(self, obj): | |
337 | return {self._bytes_tag: self._bytes_encoder(obj)} | |
265 | 338 | |
266 | 339 | def _flatten_impl(self, obj): |
267 | 340 | ######################################### |
268 | 341 | # if obj is nonrecursive return immediately |
269 | 342 | # for performance reasons we don't want to do recursive checks |
270 | if PY2 and isinstance(obj, types.FileType): | |
271 | return self._flatten_file(obj) | |
272 | ||
273 | 343 | if type(obj) is bytes: |
274 | 344 | return self._flatten_bytestring(obj) |
275 | 345 | |
285 | 355 | |
286 | 356 | def _max_reached(self): |
287 | 357 | return self._depth == self._max_depth |
358 | ||
359 | def _pickle_warning(self, obj): | |
360 | if self.warn: | |
361 | msg = 'jsonpickle cannot pickle %r: replaced with None' % obj | |
362 | warnings.warn(msg) | |
288 | 363 | |
289 | 364 | def _flatten_obj(self, obj): |
290 | 365 | self._seen.append(obj) |
317 | 392 | def _list_recurse(self, obj): |
318 | 393 | return [self._flatten(v) for v in obj] |
319 | 394 | |
320 | def _get_flattener(self, obj): | |
321 | if type(obj) in (list, dict): | |
322 | if self._mkref(obj): | |
323 | return ( | |
324 | self._list_recurse if type(obj) is list else self._flatten_dict_obj | |
325 | ) | |
395 | def _flatten_function(self, obj): | |
396 | if self.unpicklable: | |
397 | data = {tags.FUNCTION: util.importable_name(obj)} | |
398 | else: | |
399 | data = None | |
400 | ||
401 | return data | |
402 | ||
403 | def _getstate(self, obj, data): | |
404 | state = self._flatten(obj) | |
405 | if self.unpicklable: | |
406 | data[tags.STATE] = state | |
407 | else: | |
408 | data = state | |
409 | return data | |
410 | ||
411 | def _flatten_key_value_pair(self, k, v, data): | |
412 | """Flatten a key/value pair into the passed-in dictionary.""" | |
413 | if not util.is_picklable(k, v): | |
414 | return data | |
415 | ||
416 | if k is None: | |
417 | k = 'null' # for compatibility with common json encoders | |
418 | ||
419 | if self.numeric_keys and isinstance(k, numeric_types): | |
420 | pass | |
421 | elif not isinstance(k, string_types): | |
422 | try: | |
423 | k = repr(k) | |
424 | except Exception: | |
425 | k = compat.ustr(k) | |
426 | ||
427 | data[k] = self._flatten(v) | |
428 | return data | |
429 | ||
430 | def _flatten_obj_attrs(self, obj, attrs, data): | |
431 | flatten = self._flatten_key_value_pair | |
432 | ok = False | |
433 | for k in attrs: | |
434 | try: | |
435 | if not k.startswith('__'): | |
436 | value = getattr(obj, k) | |
437 | else: | |
438 | value = getattr(obj, f"_{obj.__class__.__name__}{k}") | |
439 | flatten(k, value, data) | |
440 | except AttributeError: | |
441 | # The attribute may have been deleted | |
442 | continue | |
443 | ok = True | |
444 | return ok | |
445 | ||
446 | def _flatten_properties(self, obj, data, allslots=None): | |
447 | if allslots is None: | |
448 | # setting a list as a default argument can lead to some weird errors | |
449 | allslots = [] | |
450 | ||
451 | # convert to set in case there are a lot of slots | |
452 | allslots_set = set(itertools.chain.from_iterable(allslots)) | |
453 | ||
454 | # i don't like lambdas | |
455 | def valid_property(x): | |
456 | return not x[0].startswith("__") and x[0] not in allslots_set | |
457 | ||
458 | properties = [ | |
459 | x[0] for x in inspect.getmembers(obj.__class__) if valid_property(x) | |
460 | ] | |
461 | ||
462 | properties_dict = {} | |
463 | for p_name in properties: | |
464 | p_val = getattr(obj, p_name) | |
465 | if util.is_not_class(p_val): | |
466 | properties_dict[p_name] = p_val | |
326 | 467 | else: |
327 | self._push() | |
328 | return self._getref | |
329 | ||
330 | # We handle tuples and sets by encoding them in a "(tuple|set)dict" | |
331 | elif type(obj) in (tuple, set): | |
332 | if not self.unpicklable: | |
333 | return self._list_recurse | |
334 | return lambda obj: { | |
335 | tags.TUPLE | |
336 | if type(obj) is tuple | |
337 | else tags.SET: [self._flatten(v) for v in obj] | |
338 | } | |
339 | ||
340 | elif util.is_object(obj): | |
341 | return self._ref_obj_instance | |
342 | ||
343 | elif util.is_type(obj): | |
344 | return _mktyperef | |
345 | ||
346 | elif util.is_module_function(obj): | |
347 | return self._flatten_function | |
348 | ||
349 | # instance methods, lambdas, old style classes... | |
468 | properties_dict[p_name] = self._flatten(p_val) | |
469 | ||
470 | data[tags.PROPERTY] = properties_dict | |
471 | ||
472 | return data | |
473 | ||
474 | def _flatten_newstyle_with_slots(self, obj, data): | |
475 | """Return a json-friendly dict for new-style objects with __slots__.""" | |
476 | allslots = [ | |
477 | _wrap_string_slot(getattr(cls, '__slots__', tuple())) | |
478 | for cls in obj.__class__.mro() | |
479 | ] | |
480 | ||
481 | # add properties to the attribute list | |
482 | if self.include_properties: | |
483 | data = self._flatten_properties(obj, data, allslots) | |
484 | ||
485 | if not self._flatten_obj_attrs(obj, chain(*allslots), data): | |
486 | attrs = [ | |
487 | x for x in dir(obj) if not x.startswith('__') and not x.endswith('__') | |
488 | ] | |
489 | self._flatten_obj_attrs(obj, attrs, data) | |
490 | ||
491 | return data | |
492 | ||
493 | def _flatten_obj_instance(self, obj): | |
494 | """Recursively flatten an instance and return a json-friendly dict""" | |
495 | data = {} | |
496 | has_class = hasattr(obj, '__class__') | |
497 | has_dict = hasattr(obj, '__dict__') | |
498 | has_slots = not has_dict and hasattr(obj, '__slots__') | |
499 | has_getnewargs = util.has_method(obj, '__getnewargs__') | |
500 | has_getnewargs_ex = util.has_method(obj, '__getnewargs_ex__') | |
501 | has_getinitargs = util.has_method(obj, '__getinitargs__') | |
502 | has_reduce, has_reduce_ex = util.has_reduce(obj) | |
503 | ||
504 | # Support objects with __getstate__(); this ensures that | |
505 | # both __setstate__() and __getstate__() are implemented | |
506 | has_own_getstate = hasattr(type(obj), '__getstate__') and type( | |
507 | obj | |
508 | ).__getstate__ is not getattr(object, '__getstate__', None) | |
509 | # not using has_method since __getstate__() is handled separately below | |
510 | # Note: on Python 3.11+, all objects have __getstate__. | |
511 | ||
512 | if has_class: | |
513 | cls = obj.__class__ | |
514 | else: | |
515 | cls = type(obj) | |
516 | ||
517 | # Check for a custom handler | |
518 | class_name = util.importable_name(cls) | |
519 | handler = handlers.get(cls, handlers.get(class_name)) | |
520 | if handler is not None: | |
521 | if self.unpicklable: | |
522 | data[tags.OBJECT] = class_name | |
523 | return handler(self).flatten(obj, data) | |
524 | ||
525 | reduce_val = None | |
526 | ||
527 | if self.include_properties: | |
528 | data = self._flatten_properties(obj, data) | |
529 | ||
530 | if self.unpicklable: | |
531 | if has_reduce and not has_reduce_ex: | |
532 | try: | |
533 | reduce_val = obj.__reduce__() | |
534 | except TypeError: | |
535 | # A lot of builtin types have a reduce which | |
536 | # just raises a TypeError | |
537 | # we ignore those | |
538 | pass | |
539 | ||
540 | # test for a reduce implementation, and redirect before | |
541 | # doing anything else if that is what reduce requests | |
542 | elif has_reduce_ex: | |
543 | try: | |
544 | # we're implementing protocol 2 | |
545 | reduce_val = obj.__reduce_ex__(2) | |
546 | except TypeError: | |
547 | # A lot of builtin types have a reduce which | |
548 | # just raises a TypeError | |
549 | # we ignore those | |
550 | pass | |
551 | ||
552 | if reduce_val and isinstance(reduce_val, string_types): | |
553 | try: | |
554 | varpath = iter(reduce_val.split('.')) | |
555 | # curmod will be transformed by the | |
556 | # loop into the value to pickle | |
557 | curmod = sys.modules[next(varpath)] | |
558 | for modname in varpath: | |
559 | curmod = getattr(curmod, modname) | |
560 | # replace obj with value retrieved | |
561 | return self._flatten(curmod) | |
562 | except KeyError: | |
563 | # well, we can't do anything with that, so we ignore it | |
564 | pass | |
565 | ||
566 | elif reduce_val: | |
567 | # at this point, reduce_val should be some kind of iterable | |
568 | # pad out to len 5 | |
569 | rv_as_list = list(reduce_val) | |
570 | insufficiency = 5 - len(rv_as_list) | |
571 | if insufficiency: | |
572 | rv_as_list += [None] * insufficiency | |
573 | ||
574 | if getattr(rv_as_list[0], '__name__', '') == '__newobj__': | |
575 | rv_as_list[0] = tags.NEWOBJ | |
576 | ||
577 | f, args, state, listitems, dictitems = rv_as_list | |
578 | ||
579 | # check that getstate/setstate is sane | |
580 | if not ( | |
581 | state | |
582 | and has_own_getstate | |
583 | and not hasattr(obj, '__setstate__') | |
584 | and not isinstance(obj, dict) | |
585 | ): | |
586 | # turn iterators to iterables for convenient serialization | |
587 | if rv_as_list[3]: | |
588 | rv_as_list[3] = tuple(rv_as_list[3]) | |
589 | ||
590 | if rv_as_list[4]: | |
591 | rv_as_list[4] = tuple(rv_as_list[4]) | |
592 | ||
593 | reduce_args = list(map(self._flatten, rv_as_list)) | |
594 | last_index = len(reduce_args) - 1 | |
595 | while last_index >= 2 and reduce_args[last_index] is None: | |
596 | last_index -= 1 | |
597 | data[tags.REDUCE] = reduce_args[: last_index + 1] | |
598 | ||
599 | return data | |
600 | ||
601 | if has_class and not util.is_module(obj): | |
602 | if self.unpicklable: | |
603 | data[tags.OBJECT] = class_name | |
604 | ||
605 | if has_getnewargs_ex: | |
606 | data[tags.NEWARGSEX] = list(map(self._flatten, obj.__getnewargs_ex__())) | |
607 | ||
608 | if has_getnewargs and not has_getnewargs_ex: | |
609 | data[tags.NEWARGS] = self._flatten(obj.__getnewargs__()) | |
610 | ||
611 | if has_getinitargs: | |
612 | data[tags.INITARGS] = self._flatten(obj.__getinitargs__()) | |
613 | ||
614 | if has_own_getstate: | |
615 | try: | |
616 | state = obj.__getstate__() | |
617 | except TypeError: | |
618 | # Has getstate but it cannot be called, e.g. file descriptors | |
619 | # in Python3 | |
620 | self._pickle_warning(obj) | |
621 | return None | |
622 | else: | |
623 | if state: | |
624 | return self._getstate(state, data) | |
625 | ||
626 | if util.is_module(obj): | |
627 | if self.unpicklable: | |
628 | data[tags.REPR] = '{name}/{name}'.format(name=obj.__name__) | |
629 | else: | |
630 | data = compat.ustr(obj) | |
631 | return data | |
632 | ||
633 | if util.is_dictionary_subclass(obj): | |
634 | self._flatten_dict_obj(obj, data) | |
635 | return data | |
636 | ||
637 | if util.is_sequence_subclass(obj): | |
638 | return self._flatten_sequence_obj(obj, data) | |
639 | ||
640 | if util.is_iterator(obj): | |
641 | # force list in python 3 | |
642 | data[tags.ITERATOR] = list(map(self._flatten, islice(obj, self._max_iter))) | |
643 | return data | |
644 | ||
645 | if has_dict: | |
646 | # Support objects that subclasses list and set | |
647 | if util.is_sequence_subclass(obj): | |
648 | return self._flatten_sequence_obj(obj, data) | |
649 | ||
650 | # hack for zope persistent objects; this unghostifies the object | |
651 | getattr(obj, '_', None) | |
652 | return self._flatten_dict_obj(obj.__dict__, data) | |
653 | ||
654 | if has_slots: | |
655 | return self._flatten_newstyle_with_slots(obj, data) | |
656 | ||
657 | # catchall return for data created above without a return | |
658 | # (e.g. __getnewargs__ is not supposed to be the end of the story) | |
659 | if data: | |
660 | return data | |
661 | ||
350 | 662 | self._pickle_warning(obj) |
351 | 663 | return None |
352 | 664 | |
371 | 683 | self._mkref(obj) |
372 | 684 | return self._flatten_obj_instance(obj) |
373 | 685 | |
374 | def _flatten_file(self, obj): | |
375 | """ | |
376 | Special case file objects | |
377 | """ | |
378 | assert not PY3 and isinstance(obj, types.FileType) | |
379 | return None | |
380 | ||
381 | def _flatten_bytestring(self, obj): | |
382 | if PY2: | |
383 | try: | |
384 | return obj.decode('utf-8') | |
385 | except UnicodeDecodeError: | |
686 | def _escape_key(self, k): | |
687 | return tags.JSON_KEY + encode( | |
688 | k, | |
689 | reset=False, | |
690 | keys=True, | |
691 | context=self, | |
692 | backend=self.backend, | |
693 | make_refs=self.make_refs, | |
694 | ) | |
695 | ||
696 | def _flatten_non_string_key_value_pair(self, k, v, data): | |
697 | """Flatten only non-string key/value pairs""" | |
698 | if not util.is_picklable(k, v): | |
699 | return data | |
700 | if self.keys and not isinstance(k, string_types): | |
701 | k = self._escape_key(k) | |
702 | data[k] = self._flatten(v) | |
703 | return data | |
704 | ||
705 | def _flatten_string_key_value_pair(self, k, v, data): | |
706 | """Flatten string key/value pairs only.""" | |
707 | if not util.is_picklable(k, v): | |
708 | return data | |
709 | if self.keys: | |
710 | if not isinstance(k, string_types): | |
711 | return data | |
712 | elif k.startswith(tags.JSON_KEY): | |
713 | k = self._escape_key(k) | |
714 | else: | |
715 | if k is None: | |
716 | k = 'null' # for compatibility with common json encoders | |
717 | ||
718 | if self.numeric_keys and isinstance(k, numeric_types): | |
386 | 719 | pass |
387 | return {self._bytes_tag: self._bytes_encoder(obj)} | |
388 | ||
389 | def _flatten_obj_instance(self, obj): | |
390 | """Recursively flatten an instance and return a json-friendly dict""" | |
391 | data = {} | |
392 | has_class = hasattr(obj, '__class__') | |
393 | has_dict = hasattr(obj, '__dict__') | |
394 | has_slots = not has_dict and hasattr(obj, '__slots__') | |
395 | has_getnewargs = util.has_method(obj, '__getnewargs__') | |
396 | has_getnewargs_ex = util.has_method(obj, '__getnewargs_ex__') | |
397 | has_getinitargs = util.has_method(obj, '__getinitargs__') | |
398 | has_reduce, has_reduce_ex = util.has_reduce(obj) | |
399 | ||
400 | # Support objects with __getstate__(); this ensures that | |
401 | # both __setstate__() and __getstate__() are implemented | |
402 | has_getstate = hasattr(obj, '__getstate__') | |
403 | # not using has_method since __getstate__() is handled separately below | |
404 | ||
405 | if has_class: | |
406 | cls = obj.__class__ | |
407 | else: | |
408 | cls = type(obj) | |
409 | ||
410 | # Check for a custom handler | |
411 | class_name = util.importable_name(cls) | |
412 | handler = handlers.get(cls, handlers.get(class_name)) | |
413 | if handler is not None: | |
414 | if self.unpicklable: | |
415 | data[tags.OBJECT] = class_name | |
416 | return handler(self).flatten(obj, data) | |
417 | ||
418 | reduce_val = None | |
419 | ||
420 | if self.unpicklable: | |
421 | if has_reduce and not has_reduce_ex: | |
720 | elif not isinstance(k, string_types): | |
422 | 721 | try: |
423 | reduce_val = obj.__reduce__() | |
424 | except TypeError: | |
425 | # A lot of builtin types have a reduce which | |
426 | # just raises a TypeError | |
427 | # we ignore those | |
428 | pass | |
429 | ||
430 | # test for a reduce implementation, and redirect before | |
431 | # doing anything else if that is what reduce requests | |
432 | elif has_reduce_ex: | |
433 | try: | |
434 | # we're implementing protocol 2 | |
435 | reduce_val = obj.__reduce_ex__(2) | |
436 | except TypeError: | |
437 | # A lot of builtin types have a reduce which | |
438 | # just raises a TypeError | |
439 | # we ignore those | |
440 | pass | |
441 | ||
442 | if reduce_val and isinstance(reduce_val, string_types): | |
443 | try: | |
444 | varpath = iter(reduce_val.split('.')) | |
445 | # curmod will be transformed by the | |
446 | # loop into the value to pickle | |
447 | curmod = sys.modules[next(varpath)] | |
448 | for modname in varpath: | |
449 | curmod = getattr(curmod, modname) | |
450 | # replace obj with value retrieved | |
451 | return self._flatten(curmod) | |
452 | except KeyError: | |
453 | # well, we can't do anything with that, so we ignore it | |
454 | pass | |
455 | ||
456 | elif reduce_val: | |
457 | # at this point, reduce_val should be some kind of iterable | |
458 | # pad out to len 5 | |
459 | rv_as_list = list(reduce_val) | |
460 | insufficiency = 5 - len(rv_as_list) | |
461 | if insufficiency: | |
462 | rv_as_list += [None] * insufficiency | |
463 | ||
464 | if getattr(rv_as_list[0], '__name__', '') == '__newobj__': | |
465 | rv_as_list[0] = tags.NEWOBJ | |
466 | ||
467 | f, args, state, listitems, dictitems = rv_as_list | |
468 | ||
469 | # check that getstate/setstate is sane | |
470 | if not ( | |
471 | state | |
472 | and hasattr(obj, '__getstate__') | |
473 | and not hasattr(obj, '__setstate__') | |
474 | and not isinstance(obj, dict) | |
475 | ): | |
476 | # turn iterators to iterables for convenient serialization | |
477 | if rv_as_list[3]: | |
478 | rv_as_list[3] = tuple(rv_as_list[3]) | |
479 | ||
480 | if rv_as_list[4]: | |
481 | rv_as_list[4] = tuple(rv_as_list[4]) | |
482 | ||
483 | reduce_args = list(map(self._flatten, rv_as_list)) | |
484 | last_index = len(reduce_args) - 1 | |
485 | while last_index >= 2 and reduce_args[last_index] is None: | |
486 | last_index -= 1 | |
487 | data[tags.REDUCE] = reduce_args[: last_index + 1] | |
488 | ||
489 | return data | |
490 | ||
491 | if has_class and not util.is_module(obj): | |
492 | if self.unpicklable: | |
493 | data[tags.OBJECT] = class_name | |
494 | ||
495 | if has_getnewargs_ex: | |
496 | data[tags.NEWARGSEX] = list(map(self._flatten, obj.__getnewargs_ex__())) | |
497 | ||
498 | if has_getnewargs and not has_getnewargs_ex: | |
499 | data[tags.NEWARGS] = self._flatten(obj.__getnewargs__()) | |
500 | ||
501 | if has_getinitargs: | |
502 | data[tags.INITARGS] = self._flatten(obj.__getinitargs__()) | |
503 | ||
504 | if has_getstate: | |
505 | try: | |
506 | state = obj.__getstate__() | |
507 | except TypeError: | |
508 | # Has getstate but it cannot be called, e.g. file descriptors | |
509 | # in Python3 | |
510 | self._pickle_warning(obj) | |
511 | return None | |
512 | else: | |
513 | return self._getstate(state, data) | |
514 | ||
515 | if util.is_module(obj): | |
516 | if self.unpicklable: | |
517 | data[tags.REPR] = '{name}/{name}'.format(name=obj.__name__) | |
518 | else: | |
519 | data = compat.ustr(obj) | |
520 | return data | |
521 | ||
522 | if util.is_dictionary_subclass(obj): | |
523 | self._flatten_dict_obj(obj, data) | |
524 | return data | |
525 | ||
526 | if util.is_sequence_subclass(obj): | |
527 | return self._flatten_sequence_obj(obj, data) | |
528 | ||
529 | if util.is_iterator(obj): | |
530 | # force list in python 3 | |
531 | data[tags.ITERATOR] = list(map(self._flatten, islice(obj, self._max_iter))) | |
532 | return data | |
533 | ||
534 | if has_dict: | |
535 | # Support objects that subclasses list and set | |
536 | if util.is_sequence_subclass(obj): | |
537 | return self._flatten_sequence_obj(obj, data) | |
538 | ||
539 | # hack for zope persistent objects; this unghostifies the object | |
540 | getattr(obj, '_', None) | |
541 | return self._flatten_dict_obj(obj.__dict__, data) | |
542 | ||
543 | if has_slots: | |
544 | return self._flatten_newstyle_with_slots(obj, data) | |
545 | ||
546 | # catchall return for data created above without a return | |
547 | # (e.g. __getnewargs__ is not supposed to be the end of the story) | |
548 | if data: | |
549 | return data | |
550 | ||
551 | self._pickle_warning(obj) | |
552 | return None | |
553 | ||
554 | def _flatten_function(self, obj): | |
555 | if self.unpicklable: | |
556 | data = {tags.FUNCTION: util.importable_name(obj)} | |
557 | else: | |
558 | data = None | |
559 | ||
722 | k = repr(k) | |
723 | except Exception: | |
724 | k = compat.ustr(k) | |
725 | ||
726 | data[k] = self._flatten(v) | |
560 | 727 | return data |
561 | 728 | |
562 | 729 | def _flatten_dict_obj(self, obj, data=None): |
594 | 761 | if self._mkref(factory): |
595 | 762 | # We've never seen this object before so pickle it in-place. |
596 | 763 | # Create an instance from the factory and assume that the |
597 | # resulting instance is a suitable examplar. | |
764 | # resulting instance is a suitable exemplar. | |
598 | 765 | value = self._flatten_obj_instance(handlers.CloneFactory(factory())) |
599 | 766 | else: |
600 | 767 | # We've seen this object before. |
610 | 777 | |
611 | 778 | return data |
612 | 779 | |
613 | def _flatten_obj_attrs(self, obj, attrs, data): | |
614 | flatten = self._flatten_key_value_pair | |
615 | ok = False | |
616 | for k in attrs: | |
617 | try: | |
618 | value = getattr(obj, k) | |
619 | flatten(k, value, data) | |
620 | except AttributeError: | |
621 | # The attribute may have been deleted | |
622 | continue | |
623 | ok = True | |
624 | return ok | |
625 | ||
626 | def _flatten_newstyle_with_slots(self, obj, data): | |
627 | """Return a json-friendly dict for new-style objects with __slots__.""" | |
628 | allslots = [ | |
629 | _wrap_string_slot(getattr(cls, '__slots__', tuple())) | |
630 | for cls in obj.__class__.mro() | |
631 | ] | |
632 | ||
633 | if not self._flatten_obj_attrs(obj, chain(*allslots), data): | |
634 | attrs = [ | |
635 | x for x in dir(obj) if not x.startswith('__') and not x.endswith('__') | |
636 | ] | |
637 | self._flatten_obj_attrs(obj, attrs, data) | |
638 | ||
639 | return data | |
640 | ||
641 | def _flatten_key_value_pair(self, k, v, data): | |
642 | """Flatten a key/value pair into the passed-in dictionary.""" | |
643 | if not util.is_picklable(k, v): | |
644 | return data | |
645 | ||
646 | if k is None: | |
647 | k = 'null' # for compatibility with common json encoders | |
648 | ||
649 | if self.numeric_keys and isinstance(k, numeric_types): | |
650 | pass | |
651 | elif not isinstance(k, string_types): | |
652 | try: | |
653 | k = repr(k) | |
654 | except Exception: | |
655 | k = compat.ustr(k) | |
656 | ||
657 | data[k] = self._flatten(v) | |
658 | return data | |
659 | ||
660 | def _flatten_non_string_key_value_pair(self, k, v, data): | |
661 | """Flatten only non-string key/value pairs""" | |
662 | if not util.is_picklable(k, v): | |
663 | return data | |
664 | if self.keys and not isinstance(k, string_types): | |
665 | k = self._escape_key(k) | |
666 | data[k] = self._flatten(v) | |
667 | return data | |
668 | ||
669 | def _flatten_string_key_value_pair(self, k, v, data): | |
670 | """Flatten string key/value pairs only.""" | |
671 | if not util.is_picklable(k, v): | |
672 | return data | |
673 | if self.keys: | |
674 | if not isinstance(k, string_types): | |
675 | return data | |
676 | elif k.startswith(tags.JSON_KEY): | |
677 | k = self._escape_key(k) | |
678 | else: | |
679 | if k is None: | |
680 | k = 'null' # for compatibility with common json encoders | |
681 | ||
682 | if self.numeric_keys and isinstance(k, numeric_types): | |
683 | pass | |
684 | elif not isinstance(k, string_types): | |
685 | try: | |
686 | k = repr(k) | |
687 | except Exception: | |
688 | k = compat.ustr(k) | |
689 | ||
690 | data[k] = self._flatten(v) | |
691 | return data | |
780 | def _get_flattener(self, obj): | |
781 | if type(obj) in (list, dict): | |
782 | if self._mkref(obj): | |
783 | return ( | |
784 | self._list_recurse if type(obj) is list else self._flatten_dict_obj | |
785 | ) | |
786 | else: | |
787 | self._push() | |
788 | return self._getref | |
789 | ||
790 | # We handle tuples and sets by encoding them in a "(tuple|set)dict" | |
791 | elif type(obj) in (tuple, set): | |
792 | if not self.unpicklable: | |
793 | return self._list_recurse | |
794 | return lambda obj: { | |
795 | tags.TUPLE | |
796 | if type(obj) is tuple | |
797 | else tags.SET: [self._flatten(v) for v in obj] | |
798 | } | |
799 | ||
800 | elif util.is_object(obj): | |
801 | return self._ref_obj_instance | |
802 | ||
803 | elif util.is_type(obj): | |
804 | return _mktyperef | |
805 | ||
806 | elif util.is_module_function(obj): | |
807 | return self._flatten_function | |
808 | ||
809 | # instance methods, lambdas, old style classes... | |
810 | self._pickle_warning(obj) | |
811 | return None | |
692 | 812 | |
693 | 813 | def _flatten_sequence_obj(self, obj, data): |
694 | 814 | """Return a json-friendly dict for a sequence subclass.""" |
700 | 820 | else: |
701 | 821 | return value |
702 | 822 | return data |
703 | ||
704 | def _escape_key(self, k): | |
705 | return tags.JSON_KEY + encode( | |
706 | k, | |
707 | reset=False, | |
708 | keys=True, | |
709 | context=self, | |
710 | backend=self.backend, | |
711 | make_refs=self.make_refs, | |
712 | ) | |
713 | ||
714 | def _getstate(self, obj, data): | |
715 | state = self._flatten(obj) | |
716 | if self.unpicklable: | |
717 | data[tags.STATE] = state | |
718 | else: | |
719 | data = state | |
720 | return data | |
721 | ||
722 | def _pickle_warning(self, obj): | |
723 | if self.warn: | |
724 | msg = 'jsonpickle cannot pickle %r: replaced with None' % obj | |
725 | warnings.warn(msg) | |
726 | ||
727 | ||
728 | def _in_cycle(obj, objs, max_reached, make_refs): | |
729 | """Detect cyclic structures that would lead to infinite recursion""" | |
730 | return ( | |
731 | (max_reached or (not make_refs and id(obj) in objs)) | |
732 | and not util.is_primitive(obj) | |
733 | and not util.is_enum(obj) | |
734 | ) | |
735 | ||
736 | ||
737 | def _mktyperef(obj): | |
738 | """Return a typeref dictionary | |
739 | ||
740 | >>> _mktyperef(AssertionError) == {'py/type': 'builtins.AssertionError'} | |
741 | True | |
742 | ||
743 | """ | |
744 | return {tags.TYPE: util.importable_name(obj)} | |
745 | ||
746 | ||
747 | def _wrap_string_slot(string): | |
748 | """Converts __slots__ = 'a' into __slots__ = ('a',)""" | |
749 | if isinstance(string, string_types): | |
750 | return (string,) | |
751 | return string |
6 | 6 | that need to be specially handled. |
7 | 7 | """ |
8 | 8 | from __future__ import absolute_import, division, unicode_literals |
9 | ||
10 | 9 | |
11 | 10 | BYTES = 'py/bytes' |
12 | 11 | B64 = 'py/b64' |
20 | 19 | NEWARGSEX = 'py/newargsex' |
21 | 20 | NEWOBJ = 'py/newobj' |
22 | 21 | OBJECT = 'py/object' |
22 | PROPERTY = 'py/property' | |
23 | 23 | REDUCE = 'py/reduce' |
24 | 24 | REF = 'py/ref' |
25 | 25 | REPR = 'py/repr' |
40 | 40 | NEWARGSEX, |
41 | 41 | NEWOBJ, |
42 | 42 | OBJECT, |
43 | PROPERTY, | |
43 | 44 | REDUCE, |
44 | 45 | REF, |
45 | 46 | REPR, |
4 | 4 | # This software is licensed as described in the file COPYING, which |
5 | 5 | # you should have received as part of this distribution. |
6 | 6 | from __future__ import absolute_import, division, unicode_literals |
7 | import quopri | |
7 | ||
8 | import dataclasses | |
8 | 9 | import sys |
9 | ||
10 | from . import compat | |
11 | from . import util | |
12 | from . import tags | |
13 | from . import handlers | |
10 | import warnings | |
11 | ||
12 | from . import compat, errors, handlers, tags, util | |
13 | from .backend import json | |
14 | 14 | from .compat import numeric_types |
15 | from .backend import json | |
16 | 15 | |
17 | 16 | |
18 | 17 | def decode( |
19 | string, backend=None, context=None, keys=False, reset=True, safe=False, classes=None | |
18 | string, | |
19 | backend=None, | |
20 | context=None, | |
21 | keys=False, | |
22 | reset=True, | |
23 | safe=False, | |
24 | classes=None, | |
25 | v1_decode=False, | |
26 | on_missing="ignore", | |
20 | 27 | ): |
21 | 28 | """Convert a JSON string into a Python object. |
22 | 29 | |
26 | 33 | |
27 | 34 | The keyword argument 'classes' defaults to None. |
28 | 35 | If set to a single class, or a sequence (list, set, tuple) of classes, |
29 | then the classes will be made available when constructing objects. This | |
30 | can be used to give jsonpickle access to local classes that are not | |
31 | available through the global module import scope. | |
36 | then the classes will be made available when constructing objects. | |
37 | If set to a dictionary of class names to class objects, the class object | |
38 | will be provided to jsonpickle to deserialize the class name into. | |
39 | This can be used to give jsonpickle access to local classes that are not | |
40 | available through the global module import scope, and the dict method can | |
41 | be used to deserialize encoded objects into a new class. | |
32 | 42 | |
33 | 43 | The keyword argument 'safe' defaults to False. |
34 | 44 | If set to True, eval() is avoided, but backwards-compatible |
37 | 47 | The keyword argument 'backend' defaults to None. |
38 | 48 | If set to an instance of jsonpickle.backend.JSONBackend, jsonpickle |
39 | 49 | will use that backend for deserialization. |
50 | ||
51 | The keyword argument 'v1_decode' defaults to False. | |
52 | If set to True it enables you to decode objects serialized in jsonpickle v1. | |
53 | Please do not attempt to re-encode the objects in the v1 format! Version 2's | |
54 | format fixes issue #255, and allows dictionary identity to be preserved | |
55 | through an encode/decode cycle. | |
56 | ||
57 | The keyword argument 'on_missing' defaults to 'ignore'. | |
58 | If set to 'error', it will raise an error if the class it's decoding is not | |
59 | found. If set to 'warn', it will warn you in said case. If set to a | |
60 | non-awaitable function, it will call said callback function with the class | |
61 | name (a string) as the only parameter. Strings passed to on_missing are | |
62 | lowercased automatically. | |
63 | ||
40 | 64 | |
41 | 65 | >>> decode('"my string"') == 'my string' |
42 | 66 | True |
43 | 67 | >>> decode('36') |
44 | 68 | 36 |
45 | 69 | """ |
70 | ||
71 | if isinstance(on_missing, str): | |
72 | on_missing = on_missing.lower() | |
73 | elif not util.is_function(on_missing): | |
74 | warnings.warn( | |
75 | "Unpickler.on_missing must be a string or a function! It will be ignored!" | |
76 | ) | |
77 | ||
46 | 78 | backend = backend or json |
47 | context = context or Unpickler(keys=keys, backend=backend, safe=safe) | |
79 | context = context or Unpickler( | |
80 | keys=keys, | |
81 | backend=backend, | |
82 | safe=safe, | |
83 | v1_decode=v1_decode, | |
84 | on_missing=on_missing, | |
85 | ) | |
48 | 86 | data = backend.decode(string) |
49 | 87 | return context.restore(data, reset=reset, classes=classes) |
50 | 88 | |
119 | 157 | obj[idx] = proxy.get() |
120 | 158 | |
121 | 159 | |
160 | def loadclass(module_and_name, classes=None): | |
161 | """Loads the module and returns the class. | |
162 | ||
163 | >>> cls = loadclass('datetime.datetime') | |
164 | >>> cls.__name__ | |
165 | 'datetime' | |
166 | ||
167 | >>> loadclass('does.not.exist') | |
168 | ||
169 | >>> loadclass('builtins.int')() | |
170 | 0 | |
171 | ||
172 | """ | |
173 | # Check if the class exists in a caller-provided scope | |
174 | if classes: | |
175 | try: | |
176 | return classes[module_and_name] | |
177 | except KeyError: | |
178 | # maybe they didn't provide a fully qualified path | |
179 | try: | |
180 | return classes[module_and_name.rsplit('.', 1)[-1]] | |
181 | except KeyError: | |
182 | pass | |
183 | # Otherwise, load classes from globally-accessible imports | |
184 | names = module_and_name.split('.') | |
185 | # First assume that everything up to the last dot is the module name, | |
186 | # then try other splits to handle classes that are defined within | |
187 | # classes | |
188 | for up_to in range(len(names) - 1, 0, -1): | |
189 | module = util.untranslate_module_name('.'.join(names[:up_to])) | |
190 | try: | |
191 | __import__(module) | |
192 | obj = sys.modules[module] | |
193 | for class_name in names[up_to:]: | |
194 | try: | |
195 | obj = getattr(obj, class_name) | |
196 | except AttributeError: | |
197 | continue | |
198 | return obj | |
199 | except (AttributeError, ImportError, ValueError): | |
200 | continue | |
201 | return None | |
202 | ||
203 | ||
204 | def has_tag(obj, tag): | |
205 | """Helper class that tests to see if the obj is a dictionary | |
206 | and contains a particular key/tag. | |
207 | ||
208 | >>> obj = {'test': 1} | |
209 | >>> has_tag(obj, 'test') | |
210 | True | |
211 | >>> has_tag(obj, 'fail') | |
212 | False | |
213 | ||
214 | >>> has_tag(42, 'fail') | |
215 | False | |
216 | ||
217 | """ | |
218 | return type(obj) is dict and tag in obj | |
219 | ||
220 | ||
221 | def getargs(obj, classes=None): | |
222 | """Return arguments suitable for __new__()""" | |
223 | # Let saved newargs take precedence over everything | |
224 | if has_tag(obj, tags.NEWARGSEX): | |
225 | raise ValueError("__newargs_ex__ returns both args and kwargs") | |
226 | ||
227 | if has_tag(obj, tags.NEWARGS): | |
228 | return obj[tags.NEWARGS] | |
229 | ||
230 | if has_tag(obj, tags.INITARGS): | |
231 | return obj[tags.INITARGS] | |
232 | ||
233 | try: | |
234 | seq_list = obj[tags.SEQ] | |
235 | obj_dict = obj[tags.OBJECT] | |
236 | except KeyError: | |
237 | return [] | |
238 | typeref = loadclass(obj_dict, classes=classes) | |
239 | if not typeref: | |
240 | return [] | |
241 | if hasattr(typeref, '_fields'): | |
242 | if len(typeref._fields) == len(seq_list): | |
243 | return seq_list | |
244 | return [] | |
245 | ||
246 | ||
247 | class _trivialclassic: | |
248 | """ | |
249 | A trivial class that can be instantiated with no args | |
250 | """ | |
251 | ||
252 | ||
253 | def make_blank_classic(cls): | |
254 | """ | |
255 | Implement the mandated strategy for dealing with classic classes | |
256 | which cannot be instantiated without __getinitargs__ because they | |
257 | take parameters | |
258 | """ | |
259 | instance = _trivialclassic() | |
260 | instance.__class__ = cls | |
261 | return instance | |
262 | ||
263 | ||
264 | def loadrepr(reprstr): | |
265 | """Returns an instance of the object from the object's repr() string. | |
266 | It involves the dynamic specification of code. | |
267 | ||
268 | >>> obj = loadrepr('datetime/datetime.datetime.now()') | |
269 | >>> obj.__class__.__name__ | |
270 | 'datetime' | |
271 | ||
272 | """ | |
273 | module, evalstr = reprstr.split('/') | |
274 | mylocals = locals() | |
275 | localname = module | |
276 | if '.' in localname: | |
277 | localname = module.split('.', 1)[0] | |
278 | mylocals[localname] = __import__(module) | |
279 | return eval(evalstr) | |
280 | ||
281 | ||
282 | def has_tag_dict(obj, tag): | |
283 | """Helper class that tests to see if the obj is a dictionary | |
284 | and contains a particular key/tag. | |
285 | ||
286 | >>> obj = {'test': 1} | |
287 | >>> has_tag(obj, 'test') | |
288 | True | |
289 | >>> has_tag(obj, 'fail') | |
290 | False | |
291 | ||
292 | >>> has_tag(42, 'fail') | |
293 | False | |
294 | ||
295 | """ | |
296 | return tag in obj | |
297 | ||
298 | ||
122 | 299 | class Unpickler(object): |
123 | def __init__(self, backend=None, keys=False, safe=False): | |
300 | def __init__( | |
301 | self, backend=None, keys=False, safe=False, v1_decode=False, on_missing="ignore" | |
302 | ): | |
124 | 303 | self.backend = backend or json |
125 | 304 | self.keys = keys |
126 | 305 | self.safe = safe |
306 | self.v1_decode = v1_decode | |
307 | self.on_missing = on_missing | |
127 | 308 | |
128 | 309 | self.reset() |
129 | 310 | |
142 | 323 | |
143 | 324 | # Extra local classes not accessible globally |
144 | 325 | self._classes = {} |
326 | ||
327 | def _swap_proxies(self): | |
328 | """Replace proxies with their corresponding instances""" | |
329 | for (obj, attr, proxy, method) in self._proxies: | |
330 | method(obj, attr, proxy) | |
331 | self._proxies = [] | |
332 | ||
333 | def _restore(self, obj): | |
334 | # if obj isn't in these types, neither it nor nothing in it can have a tag | |
335 | # don't change the tuple of types to a set, it won't work with isinstance | |
336 | if not isinstance(obj, (str, list, dict, set, tuple)): | |
337 | ||
338 | def restore(x): | |
339 | return x | |
340 | ||
341 | else: | |
342 | restore = self._restore_tags(obj) | |
343 | return restore(obj) | |
145 | 344 | |
146 | 345 | def restore(self, obj, reset=True, classes=None): |
147 | 346 | """Restores a flattened object to its original python state. |
173 | 372 | if isinstance(classes, (list, tuple, set)): |
174 | 373 | for cls in classes: |
175 | 374 | self.register_classes(cls) |
375 | elif isinstance(classes, dict): | |
376 | for cls in classes.values(): | |
377 | self.register_classes(cls) | |
176 | 378 | else: |
177 | 379 | self._classes[util.importable_name(classes)] = classes |
178 | 380 | |
179 | def _swap_proxies(self): | |
180 | """Replace proxies with their corresponding instances""" | |
181 | for (obj, attr, proxy, method) in self._proxies: | |
182 | method(obj, attr, proxy) | |
183 | self._proxies = [] | |
184 | ||
185 | def _restore(self, obj): | |
186 | # if obj isn't in these types, neither it nor nothing in it can have a tag | |
187 | # don't change the tuple of types to a set, it won't work with isinstance | |
188 | if not isinstance(obj, (str, list, dict, set, tuple)): | |
189 | ||
190 | def restore(x): | |
191 | return x | |
192 | ||
193 | else: | |
194 | restore = self._restore_tags(obj) | |
195 | return restore(obj) | |
196 | ||
197 | def _restore_tags(self, obj): | |
198 | try: | |
199 | if not tags.RESERVED <= set(obj) and not type(obj) in (list, dict): | |
200 | ||
201 | def restore(x): | |
202 | return x | |
203 | ||
204 | return restore | |
205 | except TypeError: | |
206 | pass | |
207 | if has_tag(obj, tags.B64): | |
208 | restore = self._restore_base64 | |
209 | elif has_tag(obj, tags.B85): | |
210 | restore = self._restore_base85 | |
211 | elif has_tag(obj, tags.ID): | |
212 | restore = self._restore_id | |
213 | elif has_tag(obj, tags.ITERATOR): | |
214 | restore = self._restore_iterator | |
215 | elif has_tag(obj, tags.TYPE): | |
216 | restore = self._restore_type | |
217 | elif has_tag(obj, tags.REDUCE): | |
218 | restore = self._restore_reduce | |
219 | elif has_tag(obj, tags.OBJECT): | |
220 | restore = self._restore_object | |
221 | elif has_tag(obj, tags.FUNCTION): | |
222 | restore = self._restore_function | |
223 | elif has_tag(obj, tags.BYTES): # Backwards compatibility | |
224 | restore = self._restore_quopri | |
225 | elif has_tag(obj, tags.REF): # Backwards compatibility | |
226 | restore = self._restore_ref | |
227 | elif has_tag(obj, tags.REPR): # Backwards compatibility | |
228 | restore = self._restore_repr | |
229 | elif util.is_list(obj): | |
230 | restore = self._restore_list | |
231 | elif has_tag(obj, tags.TUPLE): | |
232 | restore = self._restore_tuple | |
233 | elif has_tag(obj, tags.SET): | |
234 | restore = self._restore_set | |
235 | elif util.is_dictionary(obj): | |
236 | restore = self._restore_dict | |
237 | else: | |
238 | ||
239 | def restore(x): | |
240 | return x | |
241 | ||
242 | return restore | |
243 | ||
244 | 381 | def _restore_base64(self, obj): |
245 | 382 | return util.b64decode(obj[tags.B64].encode('utf-8')) |
246 | 383 | |
247 | 384 | def _restore_base85(self, obj): |
248 | 385 | return util.b85decode(obj[tags.B85].encode('utf-8')) |
249 | 386 | |
250 | #: For backwards compatibility with bytes data produced by older versions | |
251 | def _restore_quopri(self, obj): | |
252 | return quopri.decodestring(obj[tags.BYTES].encode('utf-8')) | |
387 | def _refname(self): | |
388 | """Calculates the name of the current location in the JSON stack. | |
389 | ||
390 | This is called as jsonpickle traverses the object structure to | |
391 | create references to previously-traversed objects. This allows | |
392 | cyclical data structures such as doubly-linked lists. | |
393 | jsonpickle ensures that duplicate python references to the same | |
394 | object results in only a single JSON object definition and | |
395 | special reference tags to represent each reference. | |
396 | ||
397 | >>> u = Unpickler() | |
398 | >>> u._namestack = [] | |
399 | >>> u._refname() == '/' | |
400 | True | |
401 | >>> u._namestack = ['a'] | |
402 | >>> u._refname() == '/a' | |
403 | True | |
404 | >>> u._namestack = ['a', 'b'] | |
405 | >>> u._refname() == '/a/b' | |
406 | True | |
407 | ||
408 | """ | |
409 | return '/' + '/'.join(self._namestack) | |
410 | ||
411 | def _mkref(self, obj): | |
412 | obj_id = id(obj) | |
413 | try: | |
414 | self._obj_to_idx[obj_id] | |
415 | except KeyError: | |
416 | self._obj_to_idx[obj_id] = len(self._objs) | |
417 | self._objs.append(obj) | |
418 | # Backwards compatibility: old versions of jsonpickle | |
419 | # produced "py/ref" references. | |
420 | self._namedict[self._refname()] = obj | |
421 | return obj | |
422 | ||
423 | def _restore_list(self, obj): | |
424 | parent = [] | |
425 | self._mkref(parent) | |
426 | children = [self._restore(v) for v in obj] | |
427 | parent.extend(children) | |
428 | method = _obj_setvalue | |
429 | proxies = [ | |
430 | (parent, idx, value, method) | |
431 | for idx, value in enumerate(parent) | |
432 | if isinstance(value, _Proxy) | |
433 | ] | |
434 | self._proxies.extend(proxies) | |
435 | return parent | |
253 | 436 | |
254 | 437 | def _restore_iterator(self, obj): |
255 | 438 | return iter(self._restore_list(obj[tags.ITERATOR])) |
439 | ||
440 | def _swapref(self, proxy, instance): | |
441 | proxy_id = id(proxy) | |
442 | instance_id = id(instance) | |
443 | ||
444 | instance_index = self._obj_to_idx[proxy_id] | |
445 | self._obj_to_idx[instance_id] = instance_index | |
446 | del self._obj_to_idx[proxy_id] | |
447 | ||
448 | self._objs[instance_index] = instance | |
449 | self._namedict[self._refname()] = instance | |
256 | 450 | |
257 | 451 | def _restore_reduce(self, obj): |
258 | 452 | """ |
324 | 518 | except IndexError: |
325 | 519 | return _IDProxy(self._objs, idx) |
326 | 520 | |
327 | def _restore_ref(self, obj): | |
328 | return self._namedict.get(obj[tags.REF]) | |
329 | ||
330 | 521 | def _restore_type(self, obj): |
331 | 522 | typeref = loadclass(obj[tags.TYPE], classes=self._classes) |
332 | 523 | if typeref is None: |
339 | 530 | return None |
340 | 531 | obj = loadrepr(obj[tags.REPR]) |
341 | 532 | return self._mkref(obj) |
342 | ||
343 | def _restore_object(self, obj): | |
344 | class_name = obj[tags.OBJECT] | |
345 | cls = loadclass(class_name, classes=self._classes) | |
346 | handler = handlers.get(cls, handlers.get(class_name)) | |
347 | if handler is not None: # custom handler | |
348 | proxy = _Proxy() | |
349 | self._mkref(proxy) | |
350 | instance = handler(self).restore(obj) | |
351 | proxy.reset(instance) | |
352 | self._swapref(proxy, instance) | |
353 | return instance | |
354 | ||
355 | if cls is None: | |
356 | return self._mkref(obj) | |
357 | ||
358 | return self._restore_object_instance(obj, cls) | |
359 | ||
360 | def _restore_function(self, obj): | |
361 | return loadclass(obj[tags.FUNCTION], classes=self._classes) | |
362 | 533 | |
363 | 534 | def _loadfactory(self, obj): |
364 | 535 | try: |
368 | 539 | del obj['default_factory'] |
369 | 540 | return self._restore(default_factory) |
370 | 541 | |
371 | def _restore_object_instance(self, obj, cls): | |
372 | # This is a placeholder proxy object which allows child objects to | |
373 | # reference the parent object before it has been instantiated. | |
374 | proxy = _Proxy() | |
375 | self._mkref(proxy) | |
376 | ||
377 | # An object can install itself as its own factory, so load the factory | |
378 | # after the instance is available for referencing. | |
379 | factory = self._loadfactory(obj) | |
380 | ||
381 | if has_tag(obj, tags.NEWARGSEX): | |
382 | args, kwargs = obj[tags.NEWARGSEX] | |
542 | def _process_missing(self, class_name): | |
543 | # most common case comes first | |
544 | if self.on_missing == 'ignore': | |
545 | pass | |
546 | elif self.on_missing == 'warn': | |
547 | warnings.warn("Unpickler._restore_object could not find %s!" % class_name) | |
548 | elif self.on_missing == 'error': | |
549 | raise errors.ClassNotFoundError( | |
550 | "Unpickler.restore_object could not find %s!" % class_name | |
551 | ) | |
552 | elif util.is_function(self.on_missing): | |
553 | self.on_missing(class_name) | |
554 | ||
555 | def _restore_pickled_key(self, key): | |
556 | """Restore a possibly pickled key""" | |
557 | if _is_json_key(key): | |
558 | key = decode( | |
559 | key[len(tags.JSON_KEY) :], | |
560 | backend=self.backend, | |
561 | context=self, | |
562 | keys=True, | |
563 | reset=False, | |
564 | ) | |
565 | return key | |
566 | ||
567 | def _restore_key_fn(self): | |
568 | """Return a callable that restores keys | |
569 | ||
570 | This function is responsible for restoring non-string keys | |
571 | when we are decoding with `keys=True`. | |
572 | ||
573 | """ | |
574 | # This function is called before entering a tight loop | |
575 | # where the returned function will be called. | |
576 | # We return a specific function after checking self.keys | |
577 | # instead of doing so in the body of the function to | |
578 | # avoid conditional branching inside a tight loop. | |
579 | if self.keys: | |
580 | restore_key = self._restore_pickled_key | |
383 | 581 | else: |
384 | args = getargs(obj, classes=self._classes) | |
385 | kwargs = {} | |
386 | if args: | |
387 | args = self._restore(args) | |
388 | if kwargs: | |
389 | kwargs = self._restore(kwargs) | |
390 | ||
391 | is_oldstyle = not (isinstance(cls, type) or getattr(cls, '__meta__', None)) | |
392 | try: | |
393 | if (not is_oldstyle) and hasattr(cls, '__new__'): | |
394 | # new style classes | |
395 | if factory: | |
396 | instance = cls.__new__(cls, factory, *args, **kwargs) | |
397 | instance.default_factory = factory | |
398 | else: | |
399 | instance = cls.__new__(cls, *args, **kwargs) | |
400 | else: | |
401 | instance = object.__new__(cls) | |
402 | except TypeError: # old-style classes | |
403 | is_oldstyle = True | |
404 | ||
405 | if is_oldstyle: | |
406 | try: | |
407 | instance = cls(*args) | |
408 | except TypeError: # fail gracefully | |
409 | try: | |
410 | instance = make_blank_classic(cls) | |
411 | except Exception: # fail gracefully | |
412 | return self._mkref(obj) | |
413 | ||
414 | proxy.reset(instance) | |
415 | self._swapref(proxy, instance) | |
416 | ||
417 | if isinstance(instance, tuple): | |
418 | return instance | |
419 | ||
420 | instance = self._restore_object_instance_variables(obj, instance) | |
421 | ||
422 | if _safe_hasattr(instance, 'default_factory') and isinstance( | |
423 | instance.default_factory, _Proxy | |
424 | ): | |
425 | instance.default_factory = instance.default_factory.get() | |
426 | ||
427 | return instance | |
582 | ||
583 | def restore_key(key): | |
584 | return key | |
585 | ||
586 | return restore_key | |
428 | 587 | |
429 | 588 | def _restore_from_dict(self, obj, instance, ignorereserved=True): |
430 | 589 | restore_key = self._restore_key_fn() |
456 | 615 | self._namestack.pop() |
457 | 616 | continue |
458 | 617 | else: |
459 | setattr(instance, k, value) | |
618 | if not k.startswith('__'): | |
619 | try: | |
620 | setattr(instance, k, value) | |
621 | except KeyError: | |
622 | # certain numpy objects require us to prepend a _ to the var | |
623 | # this should go in the np handler but I think this could be | |
624 | # useful for other code | |
625 | setattr(instance, f"_{k}", value) | |
626 | except dataclasses.FrozenInstanceError: | |
627 | # issue #240 | |
628 | # i think this is the only way to set frozen dataclass attrs | |
629 | object.__setattr__(instance, k, value) | |
630 | else: | |
631 | setattr(instance, f"_{instance.__class__.__name__}{k}", value) | |
460 | 632 | |
461 | 633 | # This instance has an instance variable named `k` that is |
462 | 634 | # currently a proxy and must be replaced |
469 | 641 | if deferred: |
470 | 642 | # SQLAlchemy Immutable mappings must be constructed in one shot |
471 | 643 | instance = instance.__class__(deferred) |
472 | ||
473 | return instance | |
474 | ||
475 | def _restore_object_instance_variables(self, obj, instance): | |
476 | instance = self._restore_from_dict(obj, instance) | |
477 | ||
478 | # Handle list and set subclasses | |
479 | if has_tag(obj, tags.SEQ): | |
480 | if hasattr(instance, 'append'): | |
481 | for v in obj[tags.SEQ]: | |
482 | instance.append(self._restore(v)) | |
483 | elif hasattr(instance, 'add'): | |
484 | for v in obj[tags.SEQ]: | |
485 | instance.add(self._restore(v)) | |
486 | ||
487 | if has_tag(obj, tags.STATE): | |
488 | instance = self._restore_state(obj, instance) | |
489 | 644 | |
490 | 645 | return instance |
491 | 646 | |
518 | 673 | instance = state |
519 | 674 | return instance |
520 | 675 | |
521 | def _restore_list(self, obj): | |
522 | parent = [] | |
523 | self._mkref(parent) | |
524 | children = [self._restore(v) for v in obj] | |
525 | parent.extend(children) | |
526 | method = _obj_setvalue | |
527 | proxies = [ | |
528 | (parent, idx, value, method) | |
529 | for idx, value in enumerate(parent) | |
530 | if isinstance(value, _Proxy) | |
531 | ] | |
532 | self._proxies.extend(proxies) | |
533 | return parent | |
534 | ||
535 | def _restore_tuple(self, obj): | |
536 | return tuple([self._restore(v) for v in obj[tags.TUPLE]]) | |
676 | def _restore_object_instance_variables(self, obj, instance): | |
677 | instance = self._restore_from_dict(obj, instance) | |
678 | ||
679 | # Handle list and set subclasses | |
680 | if has_tag(obj, tags.SEQ): | |
681 | if hasattr(instance, 'append'): | |
682 | for v in obj[tags.SEQ]: | |
683 | instance.append(self._restore(v)) | |
684 | elif hasattr(instance, 'add'): | |
685 | for v in obj[tags.SEQ]: | |
686 | instance.add(self._restore(v)) | |
687 | ||
688 | if has_tag(obj, tags.STATE): | |
689 | instance = self._restore_state(obj, instance) | |
690 | ||
691 | return instance | |
692 | ||
693 | def _restore_object_instance(self, obj, cls, class_name=""): | |
694 | # This is a placeholder proxy object which allows child objects to | |
695 | # reference the parent object before it has been instantiated. | |
696 | proxy = _Proxy() | |
697 | self._mkref(proxy) | |
698 | ||
699 | # An object can install itself as its own factory, so load the factory | |
700 | # after the instance is available for referencing. | |
701 | factory = self._loadfactory(obj) | |
702 | ||
703 | if has_tag(obj, tags.NEWARGSEX): | |
704 | args, kwargs = obj[tags.NEWARGSEX] | |
705 | else: | |
706 | args = getargs(obj, classes=self._classes) | |
707 | kwargs = {} | |
708 | if args: | |
709 | args = self._restore(args) | |
710 | if kwargs: | |
711 | kwargs = self._restore(kwargs) | |
712 | ||
713 | is_oldstyle = not (isinstance(cls, type) or getattr(cls, '__meta__', None)) | |
714 | try: | |
715 | if (not is_oldstyle) and hasattr(cls, '__new__'): | |
716 | # new style classes | |
717 | if factory: | |
718 | instance = cls.__new__(cls, factory, *args, **kwargs) | |
719 | instance.default_factory = factory | |
720 | else: | |
721 | instance = cls.__new__(cls, *args, **kwargs) | |
722 | else: | |
723 | instance = object.__new__(cls) | |
724 | except TypeError: # old-style classes | |
725 | is_oldstyle = True | |
726 | ||
727 | if is_oldstyle: | |
728 | try: | |
729 | instance = cls(*args) | |
730 | except TypeError: # fail gracefully | |
731 | try: | |
732 | instance = make_blank_classic(cls) | |
733 | except Exception: # fail gracefully | |
734 | self._process_missing(class_name) | |
735 | return self._mkref(obj) | |
736 | ||
737 | proxy.reset(instance) | |
738 | self._swapref(proxy, instance) | |
739 | ||
740 | if isinstance(instance, tuple): | |
741 | return instance | |
742 | ||
743 | instance = self._restore_object_instance_variables(obj, instance) | |
744 | ||
745 | if _safe_hasattr(instance, 'default_factory') and isinstance( | |
746 | instance.default_factory, _Proxy | |
747 | ): | |
748 | instance.default_factory = instance.default_factory.get() | |
749 | ||
750 | return instance | |
751 | ||
752 | def _restore_object(self, obj): | |
753 | class_name = obj[tags.OBJECT] | |
754 | cls = loadclass(class_name, classes=self._classes) | |
755 | handler = handlers.get(cls, handlers.get(class_name)) | |
756 | if handler is not None: # custom handler | |
757 | proxy = _Proxy() | |
758 | self._mkref(proxy) | |
759 | instance = handler(self).restore(obj) | |
760 | proxy.reset(instance) | |
761 | self._swapref(proxy, instance) | |
762 | return instance | |
763 | ||
764 | if cls is None: | |
765 | return self._mkref(obj) | |
766 | ||
767 | return self._restore_object_instance(obj, cls, class_name) | |
768 | ||
769 | def _restore_function(self, obj): | |
770 | return loadclass(obj[tags.FUNCTION], classes=self._classes) | |
537 | 771 | |
538 | 772 | def _restore_set(self, obj): |
539 | 773 | return {self._restore(v) for v in obj[tags.SET]} |
540 | 774 | |
541 | 775 | def _restore_dict(self, obj): |
542 | 776 | data = {} |
543 | self._mkref(data) | |
777 | if not self.v1_decode: | |
778 | self._mkref(data) | |
544 | 779 | |
545 | 780 | # If we are decoding dicts that can have non-string keys then we |
546 | 781 | # need to do a two-phase decode where the non-string keys are |
585 | 820 | self._namestack.pop() |
586 | 821 | return data |
587 | 822 | |
588 | def _restore_key_fn(self): | |
589 | """Return a callable that restores keys | |
590 | ||
591 | This function is responsible for restoring non-string keys | |
592 | when we are decoding with `keys=True`. | |
593 | ||
594 | """ | |
595 | # This function is called before entering a tight loop | |
596 | # where the returned function will be called. | |
597 | # We return a specific function after checking self.keys | |
598 | # instead of doing so in the body of the function to | |
599 | # avoid conditional branching inside a tight loop. | |
600 | if self.keys: | |
601 | restore_key = self._restore_pickled_key | |
823 | def _restore_tuple(self, obj): | |
824 | return tuple([self._restore(v) for v in obj[tags.TUPLE]]) | |
825 | ||
826 | def _restore_tags(self, obj): | |
827 | try: | |
828 | if not tags.RESERVED <= set(obj) and not type(obj) in (list, dict): | |
829 | ||
830 | def restore(x): | |
831 | return x | |
832 | ||
833 | return restore | |
834 | except TypeError: | |
835 | pass | |
836 | if type(obj) is dict: | |
837 | if tags.TUPLE in obj: | |
838 | restore = self._restore_tuple | |
839 | elif tags.SET in obj: | |
840 | restore = self._restore_set | |
841 | elif tags.B64 in obj: | |
842 | restore = self._restore_base64 | |
843 | elif tags.B85 in obj: | |
844 | restore = self._restore_base85 | |
845 | elif tags.ID in obj: | |
846 | restore = self._restore_id | |
847 | elif tags.ITERATOR in obj: | |
848 | restore = self._restore_iterator | |
849 | elif tags.OBJECT in obj: | |
850 | restore = self._restore_object | |
851 | elif tags.TYPE in obj: | |
852 | restore = self._restore_type | |
853 | elif tags.REDUCE in obj: | |
854 | restore = self._restore_reduce | |
855 | elif tags.FUNCTION in obj: | |
856 | restore = self._restore_function | |
857 | elif tags.REPR in obj: # Backwards compatibility | |
858 | restore = self._restore_repr | |
859 | else: | |
860 | restore = self._restore_dict | |
861 | elif util.is_list(obj): | |
862 | restore = self._restore_list | |
602 | 863 | else: |
603 | 864 | |
604 | def restore_key(key): | |
605 | return key | |
606 | ||
607 | return restore_key | |
608 | ||
609 | def _restore_pickled_key(self, key): | |
610 | """Restore a possibly pickled key""" | |
611 | if _is_json_key(key): | |
612 | key = decode( | |
613 | key[len(tags.JSON_KEY) :], | |
614 | backend=self.backend, | |
615 | context=self, | |
616 | keys=True, | |
617 | reset=False, | |
618 | ) | |
619 | return key | |
620 | ||
621 | def _refname(self): | |
622 | """Calculates the name of the current location in the JSON stack. | |
623 | ||
624 | This is called as jsonpickle traverses the object structure to | |
625 | create references to previously-traversed objects. This allows | |
626 | cyclical data structures such as doubly-linked lists. | |
627 | jsonpickle ensures that duplicate python references to the same | |
628 | object results in only a single JSON object definition and | |
629 | special reference tags to represent each reference. | |
630 | ||
631 | >>> u = Unpickler() | |
632 | >>> u._namestack = [] | |
633 | >>> u._refname() == '/' | |
634 | True | |
635 | >>> u._namestack = ['a'] | |
636 | >>> u._refname() == '/a' | |
637 | True | |
638 | >>> u._namestack = ['a', 'b'] | |
639 | >>> u._refname() == '/a/b' | |
640 | True | |
641 | ||
642 | """ | |
643 | return '/' + '/'.join(self._namestack) | |
644 | ||
645 | def _mkref(self, obj): | |
646 | obj_id = id(obj) | |
647 | try: | |
648 | self._obj_to_idx[obj_id] | |
649 | except KeyError: | |
650 | self._obj_to_idx[obj_id] = len(self._objs) | |
651 | self._objs.append(obj) | |
652 | # Backwards compatibility: old versions of jsonpickle | |
653 | # produced "py/ref" references. | |
654 | self._namedict[self._refname()] = obj | |
655 | return obj | |
656 | ||
657 | def _swapref(self, proxy, instance): | |
658 | proxy_id = id(proxy) | |
659 | instance_id = id(instance) | |
660 | ||
661 | instance_index = self._obj_to_idx[proxy_id] | |
662 | self._obj_to_idx[instance_id] = instance_index | |
663 | del self._obj_to_idx[proxy_id] | |
664 | ||
665 | self._objs[instance_index] = instance | |
666 | self._namedict[self._refname()] = instance | |
667 | ||
668 | ||
669 | def loadclass(module_and_name, classes=None): | |
670 | """Loads the module and returns the class. | |
671 | ||
672 | >>> cls = loadclass('datetime.datetime') | |
673 | >>> cls.__name__ | |
674 | 'datetime' | |
675 | ||
676 | >>> loadclass('does.not.exist') | |
677 | ||
678 | >>> loadclass('builtins.int')() | |
679 | 0 | |
680 | ||
681 | """ | |
682 | # Check if the class exists in a caller-provided scope | |
683 | if classes: | |
684 | try: | |
685 | return classes[module_and_name] | |
686 | except KeyError: | |
687 | pass | |
688 | # Otherwise, load classes from globally-accessible imports | |
689 | names = module_and_name.split('.') | |
690 | # First assume that everything up to the last dot is the module name, | |
691 | # then try other splits to handle classes that are defined within | |
692 | # classes | |
693 | for up_to in range(len(names) - 1, 0, -1): | |
694 | module = util.untranslate_module_name('.'.join(names[:up_to])) | |
695 | try: | |
696 | __import__(module) | |
697 | obj = sys.modules[module] | |
698 | for class_name in names[up_to:]: | |
699 | obj = getattr(obj, class_name) | |
700 | return obj | |
701 | except (AttributeError, ImportError, ValueError): | |
702 | continue | |
703 | return None | |
704 | ||
705 | ||
706 | def getargs(obj, classes=None): | |
707 | """Return arguments suitable for __new__()""" | |
708 | # Let saved newargs take precedence over everything | |
709 | if has_tag(obj, tags.NEWARGSEX): | |
710 | raise ValueError("__newargs_ex__ returns both args and kwargs") | |
711 | ||
712 | if has_tag(obj, tags.NEWARGS): | |
713 | return obj[tags.NEWARGS] | |
714 | ||
715 | if has_tag(obj, tags.INITARGS): | |
716 | return obj[tags.INITARGS] | |
717 | ||
718 | try: | |
719 | seq_list = obj[tags.SEQ] | |
720 | obj_dict = obj[tags.OBJECT] | |
721 | except KeyError: | |
722 | return [] | |
723 | typeref = loadclass(obj_dict, classes=classes) | |
724 | if not typeref: | |
725 | return [] | |
726 | if hasattr(typeref, '_fields'): | |
727 | if len(typeref._fields) == len(seq_list): | |
728 | return seq_list | |
729 | return [] | |
730 | ||
731 | ||
732 | class _trivialclassic: | |
733 | """ | |
734 | A trivial class that can be instantiated with no args | |
735 | """ | |
736 | ||
737 | ||
738 | def make_blank_classic(cls): | |
739 | """ | |
740 | Implement the mandated strategy for dealing with classic classes | |
741 | which cannot be instantiated without __getinitargs__ because they | |
742 | take parameters | |
743 | """ | |
744 | instance = _trivialclassic() | |
745 | instance.__class__ = cls | |
746 | return instance | |
747 | ||
748 | ||
749 | def loadrepr(reprstr): | |
750 | """Returns an instance of the object from the object's repr() string. | |
751 | It involves the dynamic specification of code. | |
752 | ||
753 | >>> obj = loadrepr('datetime/datetime.datetime.now()') | |
754 | >>> obj.__class__.__name__ | |
755 | 'datetime' | |
756 | ||
757 | """ | |
758 | module, evalstr = reprstr.split('/') | |
759 | mylocals = locals() | |
760 | localname = module | |
761 | if '.' in localname: | |
762 | localname = module.split('.', 1)[0] | |
763 | mylocals[localname] = __import__(module) | |
764 | return eval(evalstr) | |
765 | ||
766 | ||
767 | def has_tag(obj, tag): | |
768 | """Helper class that tests to see if the obj is a dictionary | |
769 | and contains a particular key/tag. | |
770 | ||
771 | >>> obj = {'test': 1} | |
772 | >>> has_tag(obj, 'test') | |
773 | True | |
774 | >>> has_tag(obj, 'fail') | |
775 | False | |
776 | ||
777 | >>> has_tag(42, 'fail') | |
778 | False | |
779 | ||
780 | """ | |
781 | return type(obj) is dict and tag in obj | |
865 | def restore(x): | |
866 | return x | |
867 | ||
868 | return restore |
8 | 8 | determining the type of an object. |
9 | 9 | """ |
10 | 10 | from __future__ import absolute_import, division, unicode_literals |
11 | ||
11 | 12 | import base64 |
12 | 13 | import collections |
14 | import inspect | |
13 | 15 | import io |
14 | 16 | import operator |
15 | 17 | import sys |
16 | 18 | import time |
17 | 19 | import types |
18 | import inspect | |
19 | ||
20 | from . import tags | |
21 | from . import compat | |
22 | from .compat import ( | |
23 | abc_iterator, | |
24 | class_types, | |
25 | iterator_types, | |
26 | numeric_types, | |
27 | PY2, | |
28 | PY3, | |
29 | PY3_ORDERED_DICT, | |
30 | ) | |
31 | ||
32 | if PY2: | |
33 | import __builtin__ | |
20 | ||
21 | from . import compat, tags | |
22 | from .compat import abc_iterator, class_types, iterator_types, numeric_types | |
34 | 23 | |
35 | 24 | SEQUENCES = (list, set, tuple) |
36 | 25 | SEQUENCES_SET = {list, set, tuple} |
44 | 33 | } |
45 | 34 | NON_REDUCIBLE_TYPES = ( |
46 | 35 | { |
47 | int, | |
48 | float, | |
49 | 36 | list, |
50 | 37 | dict, |
51 | 38 | set, |
56 | 43 | | PRIMITIVES |
57 | 44 | | FUNCTION_TYPES |
58 | 45 | ) |
46 | NON_CLASS_TYPES = { | |
47 | list, | |
48 | dict, | |
49 | set, | |
50 | tuple, | |
51 | bytes, | |
52 | } | PRIMITIVES | |
59 | 53 | |
60 | 54 | |
61 | 55 | def is_type(obj): |
110 | 104 | return True |
111 | 105 | |
112 | 106 | # at this point, the method has to be an instancemthod or a classmethod |
113 | self_attr = '__self__' if PY3 else 'im_self' | |
114 | if not hasattr(func, self_attr): | |
115 | return False | |
116 | bound_to = getattr(func, self_attr) | |
107 | if not hasattr(func, '__self__'): | |
108 | return False | |
109 | bound_to = getattr(func, '__self__') | |
117 | 110 | |
118 | 111 | # class methods |
119 | 112 | if isinstance(original, classmethod): |
138 | 131 | return isinstance(obj, object) and not isinstance( |
139 | 132 | obj, (type, types.FunctionType, types.BuiltinFunctionType) |
140 | 133 | ) |
134 | ||
135 | ||
136 | def is_not_class(obj): | |
137 | """Determines if the object is not a class or a class instance. | |
138 | Used for serializing properties. | |
139 | """ | |
140 | return type(obj) in NON_CLASS_TYPES | |
141 | 141 | |
142 | 142 | |
143 | 143 | def is_primitive(obj): |
247 | 247 | """ |
248 | 248 | return ( |
249 | 249 | hasattr(obj, '__class__') |
250 | and (issubclass(obj.__class__, SEQUENCES) or is_list_like(obj)) | |
250 | and issubclass(obj.__class__, SEQUENCES) | |
251 | 251 | and not is_sequence(obj) |
252 | 252 | ) |
253 | 253 | |
355 | 355 | |
356 | 356 | |
357 | 357 | def is_iterator(obj): |
358 | is_file = PY2 and isinstance(obj, __builtin__.file) | |
359 | return ( | |
360 | isinstance(obj, abc_iterator) and not isinstance(obj, io.IOBase) and not is_file | |
361 | ) | |
358 | return isinstance(obj, abc_iterator) and not isinstance(obj, io.IOBase) | |
362 | 359 | |
363 | 360 | |
364 | 361 | def is_collections(obj): |
380 | 377 | # defaultdicts may contain functions which we cannot serialise |
381 | 378 | if is_collections(obj) and not isinstance(obj, collections.defaultdict): |
382 | 379 | return True |
383 | # sets are slightly slower in this case | |
384 | if type(obj) in NON_REDUCIBLE_TYPES: | |
385 | return False | |
386 | elif obj is object: | |
387 | return False | |
388 | elif is_list_like(obj): | |
389 | return False | |
390 | elif isinstance(obj, types.ModuleType): | |
391 | return False | |
392 | elif is_dictionary_subclass(obj): | |
393 | return False | |
394 | elif is_reducible_sequence_subclass(obj): | |
395 | return False | |
396 | elif isinstance(getattr(obj, '__slots__', None), iterator_types): | |
397 | return False | |
398 | elif is_type(obj) and obj.__module__ == 'datetime': | |
399 | return False | |
380 | # We turn off the formatting in order to double the speed of the function. | |
381 | # Condensing it into one line seems to save the parser a lot of time. | |
382 | # fmt: off | |
383 | # pylint: disable=line-too-long | |
384 | if type(obj) in NON_REDUCIBLE_TYPES or obj is object or is_dictionary_subclass(obj) or isinstance(obj, types.ModuleType) or is_reducible_sequence_subclass(obj) or is_list_like(obj) or isinstance(getattr(obj, '__slots__', None), iterator_types) or (is_type(obj) and obj.__module__ == 'datetime'): # noqa: E501 | |
385 | return False | |
386 | # fmt: on | |
400 | 387 | return True |
401 | 388 | |
402 | 389 | |
488 | 475 | return lookup.get(module, module) |
489 | 476 | |
490 | 477 | |
491 | def untranslate_module_name(module): | |
492 | """Rename module names mention in JSON to names that we can import | |
493 | ||
494 | This reverses the translation applied by translate_module_name() to | |
495 | a module name available to the current version of Python. | |
496 | ||
497 | """ | |
498 | module = _0_9_6_compat_untranslate(module) | |
499 | lookup = dict(builtins='__builtin__') if PY2 else {} | |
500 | return lookup.get(module, module) | |
501 | ||
502 | ||
503 | 478 | def _0_9_6_compat_untranslate(module): |
504 | 479 | """Provide compatibility for pickles created with jsonpickle 0.9.6 and |
505 | 480 | earlier, remapping `exceptions` and `__builtin__` to `builtins`. |
508 | 483 | return lookup.get(module, module) |
509 | 484 | |
510 | 485 | |
486 | def untranslate_module_name(module): | |
487 | """Rename module names mention in JSON to names that we can import | |
488 | ||
489 | This reverses the translation applied by translate_module_name() to | |
490 | a module name available to the current version of Python. | |
491 | ||
492 | """ | |
493 | return _0_9_6_compat_untranslate(module) | |
494 | ||
495 | ||
511 | 496 | def importable_name(cls): |
512 | 497 | """ |
513 | 498 | >>> class Example(object): |
529 | 514 | # Use the fully-qualified name if available (Python >= 3.3) |
530 | 515 | name = getattr(cls, '__qualname__', cls.__name__) |
531 | 516 | module = translate_module_name(cls.__module__) |
517 | if not module: | |
518 | if hasattr(cls, '__self__'): | |
519 | module = cls.__self__.__class__.__module__ | |
532 | 520 | return '{}.{}'.format(module, name) |
533 | 521 | |
534 | 522 | |
550 | 538 | """ |
551 | 539 | Encode binary data to ascii text in base85. Data must be bytes. |
552 | 540 | """ |
553 | if PY2: | |
554 | raise NotImplementedError("Python 2 can't encode data in base85.") | |
555 | 541 | return base64.b85encode(data).decode('ascii') |
556 | 542 | |
557 | 543 | |
559 | 545 | """ |
560 | 546 | Decode payload - must be ascii text. |
561 | 547 | """ |
562 | if PY2: | |
563 | raise NotImplementedError("Python 2 can't decode base85-encoded data.") | |
564 | 548 | return base64.b85decode(payload) |
565 | 549 | |
566 | 550 | |
569 | 553 | |
570 | 554 | |
571 | 555 | def items(obj): |
572 | """Iterate over dicts in a deterministic order | |
573 | ||
574 | Python2 does not guarantee dict ordering, so this function | |
575 | papers over the difference in behavior. Python3 does guarantee | |
576 | dict order, without use of OrderedDict, so no sorting is needed there. | |
577 | ||
578 | """ | |
579 | if PY3_ORDERED_DICT: | |
580 | for k, v in obj.items(): | |
581 | yield k, v | |
582 | else: | |
583 | for k, v in sorted(obj.items(), key=itemgetter): | |
584 | yield k, v | |
556 | """ | |
557 | TODO: Replace all calls to this with plain dict.items() | |
558 | """ | |
559 | for k, v in obj.items(): | |
560 | yield k, v |
0 | 0 | Metadata-Version: 2.1 |
1 | 1 | Name: jsonpickle |
2 | Version: 2.0.0 | |
2 | Version: 3.0.0 | |
3 | 3 | Summary: Python library for serializing any arbitrary object graph into JSON |
4 | 4 | Home-page: https://github.com/jsonpickle/jsonpickle |
5 | 5 | Author: David Aguilar |
6 | 6 | Author-email: davvid@gmail.com |
7 | 7 | License: UNKNOWN |
8 | Description: .. image:: https://img.shields.io/pypi/v/jsonpickle.svg | |
9 | :target: `PyPI link`_ | |
10 | ||
11 | .. image:: https://img.shields.io/pypi/pyversions/jsonpickle.svg | |
12 | :target: `PyPI link`_ | |
13 | ||
14 | .. _PyPI link: https://pypi.org/project/jsonpickle | |
15 | ||
16 | .. image:: https://dev.azure.com/jaraco/jsonpickle/_apis/build/status/jaraco.jsonpickle?branchName=master | |
17 | :target: https://dev.azure.com/jaraco/jsonpickle/_build/latest?definitionId=1&branchName=master | |
18 | ||
19 | .. image:: https://readthedocs.org/projects/jsonpickle/badge/?version=latest | |
20 | :target: https://jsonpickle.readthedocs.io/en/latest/?badge=latest | |
21 | ||
22 | .. image:: https://travis-ci.org/jsonpickle/jsonpickle.svg?branch=master | |
23 | :target: https://travis-ci.org/jsonpickle/jsonpickle | |
24 | :alt: travis | |
25 | ||
26 | .. image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg | |
27 | :target: https://github.com/jsonpickle/jsonpickle/blob/master/COPYING | |
28 | :alt: BSD | |
29 | ||
30 | ||
31 | jsonpickle | |
32 | ========== | |
33 | jsonpickle is a library for the two-way conversion of complex Python objects | |
34 | and `JSON <http://json.org/>`_. jsonpickle builds upon the existing JSON | |
35 | encoders, such as simplejson, json, and demjson. | |
36 | ||
37 | For complete documentation, please visit the | |
38 | `jsonpickle documentation <http://jsonpickle.readthedocs.io/>`_. | |
39 | ||
40 | Bug reports and merge requests are encouraged at the | |
41 | `jsonpickle repository on github <https://github.com/jsonpickle/jsonpickle>`_. | |
42 | ||
43 | jsonpickle supports Python 2.7 and Python 3.4 or greater. | |
44 | ||
45 | **WARNING**: | |
46 | jsonpickle can execute arbitrary Python code. Do not load jsonpickles from untrusted / unauthenticated sources. | |
47 | ||
48 | Why jsonpickle? | |
49 | =============== | |
50 | Data serialized with python's pickle (or cPickle or dill) is not easily readable outside of python. Using the json format, jsonpickle allows simple data types to be stored in a human-readable format, and more complex data types such as numpy arrays and pandas dataframes, to be machine-readable on any platform that supports json. E.g., unlike pickled data, jsonpickled data stored in an Amazon S3 bucket is indexible by Amazon's Athena. | |
51 | ||
52 | Install | |
53 | ======= | |
54 | ||
55 | Install from pip for the latest stable release: | |
56 | ||
57 | :: | |
58 | ||
59 | pip install jsonpickle | |
60 | ||
61 | Install from github for the latest changes: | |
62 | ||
63 | :: | |
64 | ||
65 | pip install git+https://github.com/jsonpickle/jsonpickle.git | |
66 | ||
67 | If you have the files checked out for development: | |
68 | ||
69 | :: | |
70 | ||
71 | git clone https://github.com/jsonpickle/jsonpickle.git | |
72 | cd jsonpickle | |
73 | python setup.py develop | |
74 | ||
75 | ||
76 | Numpy Support | |
77 | ============= | |
78 | jsonpickle includes a built-in numpy extension. If would like to encode | |
79 | sklearn models, numpy arrays, and other numpy-based data then you must | |
80 | enable the numpy extension by registering its handlers:: | |
81 | ||
82 | >>> import jsonpickle.ext.numpy as jsonpickle_numpy | |
83 | >>> jsonpickle_numpy.register_handlers() | |
84 | ||
85 | Pandas Support | |
86 | ============== | |
87 | jsonpickle includes a built-in pandas extension. If would like to encode | |
88 | pandas DataFrame or Series objects then you must enable the pandas extension | |
89 | by registering its handlers:: | |
90 | ||
91 | >>> import jsonpickle.ext.pandas as jsonpickle_pandas | |
92 | >>> jsonpickle_pandas.register_handlers() | |
93 | ||
94 | jsonpickleJS | |
95 | ============ | |
96 | `jsonpickleJS <https://github.com/cuthbertLab/jsonpickleJS>`_ | |
97 | is a javascript implementation of jsonpickle by Michael Scott Cuthbert. | |
98 | jsonpickleJS can be extremely useful for projects that have parallel data | |
99 | structures between Python and Javascript. | |
100 | ||
101 | License | |
102 | ======= | |
103 | Licensed under the BSD License. See COPYING for details. | |
104 | See jsonpickleJS/LICENSE for details about the jsonpickleJS license. | |
105 | ||
106 | Development | |
107 | =========== | |
108 | ||
109 | Use `make` to run the unit tests:: | |
110 | ||
111 | make test | |
112 | ||
113 | `pytest` is used to run unit tests internally. | |
114 | ||
115 | A `tox` target is provided to run tests using tox. | |
116 | Setting ``multi=1`` tests using all installed and supported Python versions:: | |
117 | ||
118 | make tox | |
119 | make tox multi=1 | |
120 | ||
121 | `jsonpickle` itself has no dependencies beyond the Python stdlib. | |
122 | `tox` is required for testing when using the `tox` test runner only. | |
123 | ||
124 | The testing requirements are specified in `requirements-dev.txt`. | |
125 | It is recommended to create a virtualenv and run tests from within the | |
126 | virtualenv, or use a tool such as `vx <https://github.com/davvid/vx/>`_ | |
127 | to activate the virtualenv without polluting the shell environment:: | |
128 | ||
129 | python3 -mvenv env3x | |
130 | vx env3x pip install --requirement requirements-dev.txt | |
131 | vx env3x make test | |
132 | ||
133 | `jsonpickle` supports multiple Python versions, so using a combination of | |
134 | multiple virtualenvs and `tox` is useful in order to catch compatibility | |
135 | issues when developing. | |
136 | ||
137 | 8 | Keywords: json pickle,json,pickle,marshal,serialization,JavaScript Object Notation |
138 | 9 | Platform: POSIX |
139 | 10 | Platform: Windows |
141 | 12 | Classifier: Intended Audience :: Developers |
142 | 13 | Classifier: License :: OSI Approved :: BSD License |
143 | 14 | Classifier: Programming Language :: Python |
144 | Classifier: Programming Language :: Python :: 2 | |
145 | Classifier: Programming Language :: Python :: 2.7 | |
146 | 15 | Classifier: Programming Language :: Python :: 3 |
16 | Classifier: Programming Language :: Python :: 3.7 | |
17 | Classifier: Programming Language :: Python :: 3.8 | |
18 | Classifier: Programming Language :: Python :: 3.9 | |
19 | Classifier: Programming Language :: Python :: 3.10 | |
147 | 20 | Classifier: Programming Language :: JavaScript |
148 | 21 | Classifier: Operating System :: OS Independent |
149 | 22 | Classifier: Topic :: Software Development :: Libraries :: Python Modules |
150 | Requires-Python: >=2.7 | |
23 | Requires-Python: >=3.7 | |
151 | 24 | Provides-Extra: testing |
152 | 25 | Provides-Extra: testing.libs |
153 | 26 | Provides-Extra: docs |
27 | License-File: LICENSE | |
28 | ||
29 | .. image:: https://img.shields.io/pypi/v/jsonpickle.svg | |
30 | :target: `PyPI link`_ | |
31 | ||
32 | .. image:: https://img.shields.io/pypi/pyversions/jsonpickle.svg | |
33 | :target: `PyPI link`_ | |
34 | ||
35 | .. _PyPI link: https://pypi.org/project/jsonpickle | |
36 | ||
37 | .. image:: https://readthedocs.org/projects/jsonpickle/badge/?version=latest | |
38 | :target: https://jsonpickle.readthedocs.io/en/latest/?badge=latest | |
39 | ||
40 | .. image:: https://github.com/jsonpickle/jsonpickle/actions/workflows/test.yml/badge.svg | |
41 | :target: https://github.com/jsonpickle/jsonpickle/actions | |
42 | :alt: Github Actions | |
43 | ||
44 | .. image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg | |
45 | :target: https://github.com/jsonpickle/jsonpickle/blob/main/COPYING | |
46 | :alt: BSD | |
47 | ||
48 | ||
49 | jsonpickle | |
50 | ========== | |
51 | jsonpickle is a library for the two-way conversion of complex Python objects | |
52 | and `JSON <http://json.org/>`_. jsonpickle builds upon the existing JSON | |
53 | encoders, such as simplejson, json, and ujson. | |
54 | ||
55 | .. warning:: | |
56 | ||
57 | jsonpickle can execute arbitrary Python code. | |
58 | ||
59 | Please see the Security section for more details. | |
60 | ||
61 | ||
62 | For complete documentation, please visit the | |
63 | `jsonpickle documentation <http://jsonpickle.readthedocs.io/>`_. | |
64 | ||
65 | Bug reports and merge requests are encouraged at the | |
66 | `jsonpickle repository on github <https://github.com/jsonpickle/jsonpickle>`_. | |
67 | ||
68 | jsonpickle officially supports CPython 2.7 and CPython 3.6 or greater. Version support below CPython 3.7 will be dropped upon release of jsonpickle 3.0. | |
69 | ||
70 | Why jsonpickle? | |
71 | =============== | |
72 | Data serialized with python's pickle (or cPickle or dill) is not easily readable outside of python. Using the json format, jsonpickle allows simple data types to be stored in a human-readable format, and more complex data types such as numpy arrays and pandas dataframes, to be machine-readable on any platform that supports json. E.g., unlike pickled data, jsonpickled data stored in an Amazon S3 bucket is indexible by Amazon's Athena. | |
73 | ||
74 | Security | |
75 | ======== | |
76 | ||
77 | jsonpickle should be treated the same as the | |
78 | `Python stdlib pickle module <https://docs.python.org/3/library/pickle.html>`_ | |
79 | from a security perspective. | |
80 | ||
81 | .. warning:: | |
82 | ||
83 | The jsonpickle module **is not secure**. Only unpickle data you trust. | |
84 | ||
85 | It is possible to construct malicious pickle data which will **execute | |
86 | arbitrary code during unpickling**. Never unpickle data that could have come | |
87 | from an untrusted source, or that could have been tampered with. | |
88 | ||
89 | Consider signing data with an HMAC if you need to ensure that it has not | |
90 | been tampered with. | |
91 | ||
92 | Safer deserialization approaches, such as reading JSON directly, | |
93 | may be more appropriate if you are processing untrusted data. | |
94 | ||
95 | ||
96 | Install | |
97 | ======= | |
98 | ||
99 | Install from pip for the latest stable release: | |
100 | ||
101 | :: | |
102 | ||
103 | pip install jsonpickle | |
104 | ||
105 | Install from github for the latest changes: | |
106 | ||
107 | :: | |
108 | ||
109 | pip install git+https://github.com/jsonpickle/jsonpickle.git | |
110 | ||
111 | If you have the files checked out for development: | |
112 | ||
113 | :: | |
114 | ||
115 | git clone https://github.com/jsonpickle/jsonpickle.git | |
116 | cd jsonpickle | |
117 | python setup.py develop | |
118 | ||
119 | ||
120 | Numpy Support | |
121 | ============= | |
122 | jsonpickle includes a built-in numpy extension. If would like to encode | |
123 | sklearn models, numpy arrays, and other numpy-based data then you must | |
124 | enable the numpy extension by registering its handlers:: | |
125 | ||
126 | >>> import jsonpickle.ext.numpy as jsonpickle_numpy | |
127 | >>> jsonpickle_numpy.register_handlers() | |
128 | ||
129 | Pandas Support | |
130 | ============== | |
131 | jsonpickle includes a built-in pandas extension. If would like to encode | |
132 | pandas DataFrame or Series objects then you must enable the pandas extension | |
133 | by registering its handlers:: | |
134 | ||
135 | >>> import jsonpickle.ext.pandas as jsonpickle_pandas | |
136 | >>> jsonpickle_pandas.register_handlers() | |
137 | ||
138 | jsonpickleJS | |
139 | ============ | |
140 | `jsonpickleJS <https://github.com/cuthbertLab/jsonpickleJS>`_ | |
141 | is a javascript implementation of jsonpickle by Michael Scott Cuthbert. | |
142 | jsonpickleJS can be extremely useful for projects that have parallel data | |
143 | structures between Python and Javascript. | |
144 | ||
145 | License | |
146 | ======= | |
147 | Licensed under the BSD License. See COPYING for details. | |
148 | See jsonpickleJS/LICENSE for details about the jsonpickleJS license. | |
149 | ||
150 | Development | |
151 | =========== | |
152 | ||
153 | Use `make` to run the unit tests:: | |
154 | ||
155 | make test | |
156 | ||
157 | `pytest` is used to run unit tests internally. | |
158 | ||
159 | A `tox` target is provided to run tests using tox. | |
160 | Setting ``multi=1`` tests using all installed and supported Python versions:: | |
161 | ||
162 | make tox | |
163 | make tox multi=1 | |
164 | ||
165 | `jsonpickle` itself has no dependencies beyond the Python stdlib. | |
166 | `tox` is required for testing when using the `tox` test runner only. | |
167 | ||
168 | The testing requirements are specified in `requirements-dev.txt`. | |
169 | It is recommended to create a virtualenv and run tests from within the | |
170 | virtualenv, or use a tool such as `vx <https://github.com/davvid/vx/>`_ | |
171 | to activate the virtualenv without polluting the shell environment:: | |
172 | ||
173 | python3 -mvenv env3x | |
174 | vx env3x pip install --requirement requirements-dev.txt | |
175 | vx env3x make test | |
176 | ||
177 | `jsonpickle` supports multiple Python versions, so using a combination of | |
178 | multiple virtualenvs and `tox` is useful in order to catch compatibility | |
179 | issues when developing. | |
180 | ||
181 |
0 | 0 | .coveragerc |
1 | 1 | .flake8 |
2 | 2 | .gitignore |
3 | .isort.cfg | |
3 | 4 | .pre-commit-config.yaml |
4 | 5 | .readthedocs.yml |
5 | .travis.yml | |
6 | BENCHMARKS.md | |
6 | 7 | CHANGES.rst |
7 | 8 | LICENSE |
8 | 9 | Makefile |
10 | 11 | appveyor.yml |
11 | 12 | azure-pipelines.yml |
12 | 13 | conftest.py |
14 | jsonpickle_benchmarks.py | |
13 | 15 | pyproject.toml |
14 | 16 | pytest.ini |
15 | 17 | requirements-dev.txt |
18 | 20 | skeleton.md |
19 | 21 | tox.ini |
20 | 22 | .github/FUNDING.yml |
23 | .github/workflows/lint.yml | |
24 | .github/workflows/test.yml | |
21 | 25 | contrib/copy-docs |
22 | 26 | contrib/pyqt-reduce-handler.py |
23 | 27 | docs/api.rst |
27 | 31 | docs/history.rst |
28 | 32 | docs/index.rst |
29 | 33 | docs/requirements.txt |
34 | images/jsonpickle-0.9.6.svg | |
35 | images/jsonpickle-1.5.1.svg | |
36 | images/jsonpickle-1.5.2.svg | |
37 | images/jsonpickle-2.2.0.svg | |
38 | images/jsonpickle-3.0.0-dev.svg | |
30 | 39 | jsonpickle/__init__.py |
31 | 40 | jsonpickle/backend.py |
32 | 41 | jsonpickle/compat.py |
42 | jsonpickle/errors.py | |
33 | 43 | jsonpickle/handlers.py |
34 | 44 | jsonpickle/pickler.py |
35 | 45 | jsonpickle/tags.py |
42 | 52 | jsonpickle.egg-info/requires.txt |
43 | 53 | jsonpickle.egg-info/top_level.txt |
44 | 54 | jsonpickle/ext/__init__.py |
55 | jsonpickle/ext/gmpy.py | |
45 | 56 | jsonpickle/ext/numpy.py |
46 | 57 | jsonpickle/ext/pandas.py |
47 | 58 | jsonpickleJS/.gitignore |
0 | 0 | |
1 | 1 | [:python_version < "3.8"] |
2 | 2 | importlib_metadata |
3 | ||
4 | [:python_version > "3.10"] | |
5 | setuptools<59 | |
3 | 6 | |
4 | 7 | [docs] |
5 | 8 | sphinx |
7 | 10 | rst.linker>=1.9 |
8 | 11 | |
9 | 12 | [testing] |
10 | coverage<5 | |
11 | 13 | pytest!=3.7.3,>=3.5 |
12 | 14 | pytest-checkdocs>=1.2.3 |
13 | pytest-flake8 | |
15 | pytest-flake8>=1.1.1 | |
14 | 16 | pytest-black-multipy |
15 | 17 | pytest-cov |
16 | 18 | ecdsa |
17 | 19 | feedparser |
20 | gmpy2 | |
18 | 21 | numpy |
19 | 22 | pandas |
20 | 23 | pymongo |
21 | sklearn | |
24 | scikit-learn | |
22 | 25 | sqlalchemy |
23 | 26 | |
24 | 27 | [testing.libs] |
25 | demjson | |
26 | 28 | simplejson |
27 | 29 | ujson |
28 | ||
29 | [testing.libs:python_version < "3.8"] | |
30 | yajl | |
31 | ||
32 | [testing:python_version == "2.7"] | |
33 | enum34 | |
34 | jsonlib |
0 | """ | |
1 | Run "make benchmark" in the directory that this file is in. | |
2 | This will test the version of jsonpickle inside the local directory, | |
3 | NOT the pip installed version. | |
4 | To test the pip installed version, run this outside the jsonpickle directory: | |
5 | py.test --benchmark-only ./jsonpickle_benchmarks.py --benchmark-histogram | |
6 | MAKE SURE you have pytest-benchmark pip installed. | |
7 | ||
8 | Names of tests are shortened so they don't take up too much space on the histogram | |
9 | """ | |
10 | import itertools | |
11 | ||
12 | import jsonpickle | |
13 | ||
14 | # DEFINTIIONS: | |
15 | # HOMOGENOUS - Except for sets, each container may only have integers, floats, strings, | |
16 | # and itself inside it | |
17 | # HETEROGENOUS - Except for sets, each container must have at least one of every other | |
18 | # container type being tested | |
19 | # SIMPLE - Each container must have two each of integers, floats, and strings | |
20 | # COMPLEX - Each container must have four each of integers, floats, and strings | |
21 | ||
22 | # SETUP | |
23 | ################################################################################### | |
24 | ||
25 | ||
26 | class SlotPickleMixin(object): | |
27 | def __getstate__(self): | |
28 | all_slots = itertools.chain.from_iterable( | |
29 | getattr(cls, '__slots__', []) for cls in self.__class__.__mro__ | |
30 | ) | |
31 | return dict( | |
32 | (slot, getattr(self, slot)) for slot in all_slots if hasattr(self, slot) | |
33 | ) | |
34 | ||
35 | def __setstate__(self, state): | |
36 | for slot, value in dict(state).items(): | |
37 | setattr(self, slot, value) | |
38 | ||
39 | ||
40 | class MyClass(object): | |
41 | __slots__ = ['idk', 'idk2'] | |
42 | ||
43 | def __init__(self): | |
44 | self.idk = { | |
45 | 'a': 0, | |
46 | 'b': [0.5783, 1, 2.5789], | |
47 | 'c': {0, 1.87559, 2}, | |
48 | 'd': ['0', '1', '2'], | |
49 | 'e': {'0', '1', '2'}, | |
50 | 'f': {'a': 0, 'b': {'a': 1}}, | |
51 | } | |
52 | self.idk2 = [ | |
53 | 'a', | |
54 | 'b', | |
55 | 'c', | |
56 | 0, | |
57 | 0.18752, | |
58 | 2, | |
59 | ['a', 'b', 'c', 0.8579, 1, 2.59757], | |
60 | (self.idk, self.idk), | |
61 | ] | |
62 | ||
63 | ||
64 | class MyClassGetState(SlotPickleMixin): | |
65 | __slots__ = ['idk', 'idk2'] | |
66 | ||
67 | def __init__(self): | |
68 | self.idk = { | |
69 | 'a': 0, | |
70 | 'b': [0.5783, 1, 2.5789], | |
71 | 'c': {0, 1.87559, 2}, | |
72 | 'd': ['0', '1', '2'], | |
73 | 'e': {'0', '1', '2'}, | |
74 | 'f': {'a': 0, 'b': {'a': 1}}, | |
75 | } | |
76 | self.idk2 = [ | |
77 | 'a', | |
78 | 'b', | |
79 | 'c', | |
80 | 0, | |
81 | 0.18752, | |
82 | 2, | |
83 | ['a', 'b', 'c', 0.8579, 1, 2.59757], | |
84 | (self.idk, self.idk), | |
85 | ] | |
86 | ||
87 | def __getstate__(self): | |
88 | return SlotPickleMixin.__getstate__(self) | |
89 | ||
90 | def __setstate__(self, object_state): | |
91 | SlotPickleMixin.__setstate__(self, object_state) | |
92 | ||
93 | ||
94 | class MyClassSimple(object): | |
95 | def __init__(self): | |
96 | self.idk = {'a': 0} | |
97 | self.idk2 = ['a', 0] | |
98 | ||
99 | ||
100 | HOMOGENOUS_COMPLEX_DICT = { | |
101 | 'a': 0, | |
102 | 'b': 4.2, | |
103 | 'c': {6.9: 'd'}, | |
104 | -1: {5: 5}, | |
105 | 6: {8.42: -2.5}, | |
106 | } | |
107 | HOMOGENOUS_COMPLEX_LIST = [ | |
108 | 'a', | |
109 | 0, | |
110 | 'b', | |
111 | 4.2, | |
112 | 'c', | |
113 | [6.9, 'd'], | |
114 | -1, | |
115 | [5, 5], | |
116 | 6, | |
117 | [8.42, -2.5], | |
118 | ] | |
119 | HOMOGENOUS_COMPLEX_TUPLE = ( | |
120 | 'a', | |
121 | 0, | |
122 | 'b', | |
123 | 4.2, | |
124 | 'c', | |
125 | (6.9, 'd'), | |
126 | -1, | |
127 | (5, 5), | |
128 | 6, | |
129 | (8.42, -2.5), | |
130 | ) | |
131 | # can't put a set inside a set :( | |
132 | HOMOGENOUS_COMPLEX_SET = { | |
133 | 'a', | |
134 | 0, | |
135 | 'b', | |
136 | 4.2, | |
137 | 'c', | |
138 | (6.9, 'd'), | |
139 | -1, | |
140 | (5, 5), | |
141 | 6, | |
142 | (8.42, -2.5), | |
143 | } | |
144 | ||
145 | HETEROGENOUS_COMPLEX_DICT = { | |
146 | 'a': (0, '1'), | |
147 | 2.53: [3, 1], | |
148 | 'c': {4.2, 6.9}, | |
149 | 'd': {1: 5.432}, | |
150 | } | |
151 | HETEROGENOUS_COMPLEX_LIST = [ | |
152 | 'a', | |
153 | (0, '1'), | |
154 | 2.53, | |
155 | [3, 1], | |
156 | 'c', | |
157 | {4.2, 6.9}, | |
158 | 'd', | |
159 | {1: 5.432}, | |
160 | ] | |
161 | HETEROGENOUS_COMPLEX_TUPLE = ( | |
162 | 'a', | |
163 | (0, '1'), | |
164 | 2.53, | |
165 | [3, 1], | |
166 | 'c', | |
167 | {4.2, 6.9}, | |
168 | 'd', | |
169 | {1: 5.432}, | |
170 | ) | |
171 | HETEROGENOUS_COMPLEX_SET = { | |
172 | 'a', | |
173 | (0, '1'), | |
174 | 2.53, | |
175 | (3, 1), | |
176 | 'c', | |
177 | (4.2, 6.9), | |
178 | 'd', | |
179 | (1, 5.432), | |
180 | } | |
181 | ||
182 | simple_dict_encoded = jsonpickle.encode({'a': 0, 'b': 4.2, 3: 6.9}) | |
183 | simple_list_encoded = jsonpickle.encode(['a', 0, 'b', 4.2, 3, 6.9]) | |
184 | simple_tuple_encoded = jsonpickle.encode(('a', 0, 'b', 4.2, 3, 6.9)) | |
185 | simple_set_encoded = jsonpickle.encode({'a', 0, 'b', 4.2, 3, 6.9}) | |
186 | ||
187 | homogenous_dict_encoded = jsonpickle.encode(HOMOGENOUS_COMPLEX_DICT) | |
188 | homogenous_list_encoded = jsonpickle.encode(HOMOGENOUS_COMPLEX_LIST) | |
189 | homogenous_tuple_encoded = jsonpickle.encode(HOMOGENOUS_COMPLEX_TUPLE) | |
190 | homogenous_set_encoded = jsonpickle.encode(HOMOGENOUS_COMPLEX_SET) | |
191 | ||
192 | heterogenous_dict_encoded = jsonpickle.encode(HETEROGENOUS_COMPLEX_DICT) | |
193 | heterogenous_list_encoded = jsonpickle.encode(HETEROGENOUS_COMPLEX_LIST) | |
194 | heterogenous_tuple_encoded = jsonpickle.encode(HETEROGENOUS_COMPLEX_TUPLE) | |
195 | heterogenous_set_encoded = jsonpickle.encode(HETEROGENOUS_COMPLEX_SET) | |
196 | ||
197 | simple_class_encoded = jsonpickle.encode(MyClassSimple()) | |
198 | class_encoded = jsonpickle.encode(MyClass()) | |
199 | state_class_encoded = jsonpickle.encode(MyClassGetState()) | |
200 | ################################################################################### | |
201 | ||
202 | # SIMPLE PRIMITIVE ENCODE/DECODE | |
203 | ||
204 | ||
205 | def simple_dict_encode(benchmark): | |
206 | benchmark(jsonpickle.encode, {'a': 0}) | |
207 | ||
208 | ||
209 | def simple_dict_decode(benchmark): | |
210 | benchmark(jsonpickle.decode, simple_dict_encoded) | |
211 | ||
212 | ||
213 | def simple_list_encode(benchmark): | |
214 | benchmark(jsonpickle.encode, ['a', 0]) | |
215 | ||
216 | ||
217 | def simple_list_decode(benchmark): | |
218 | benchmark(jsonpickle.decode, simple_list_encoded) | |
219 | ||
220 | ||
221 | def simple_tuple_encode(benchmark): | |
222 | benchmark(jsonpickle.encode, ('a', 0)) | |
223 | ||
224 | ||
225 | def simple_tuple_decode(benchmark): | |
226 | benchmark(jsonpickle.decode, simple_tuple_encoded) | |
227 | ||
228 | ||
229 | def simple_set_encode(benchmark): | |
230 | benchmark(jsonpickle.encode, {'a', 0}) | |
231 | ||
232 | ||
233 | def simple_set_decode(benchmark): | |
234 | benchmark(jsonpickle.decode, simple_set_encoded) | |
235 | ||
236 | ||
237 | # COMPLEX HOMOGENOUS PRIMITIVE ENCODE/DECODE | |
238 | def complex_homogenous_dict_encode(benchmark): | |
239 | benchmark(jsonpickle.encode, HOMOGENOUS_COMPLEX_DICT) | |
240 | ||
241 | ||
242 | def complex_homogenous_dict_decode(benchmark): | |
243 | benchmark(jsonpickle.decode, homogenous_dict_encoded) | |
244 | ||
245 | ||
246 | def complex_homogenous_list_encode(benchmark): | |
247 | benchmark(jsonpickle.encode, HOMOGENOUS_COMPLEX_LIST) | |
248 | ||
249 | ||
250 | def complex_homogenous_list_decode(benchmark): | |
251 | benchmark(jsonpickle.decode, homogenous_list_encoded) | |
252 | ||
253 | ||
254 | def complex_homogenous_tuple_encode(benchmark): | |
255 | benchmark(jsonpickle.encode, HOMOGENOUS_COMPLEX_TUPLE) | |
256 | ||
257 | ||
258 | def complex_homogenous_tuple_decode(benchmark): | |
259 | benchmark(jsonpickle.decode, homogenous_tuple_encoded) | |
260 | ||
261 | ||
262 | def complex_homogenous_set_encode(benchmark): | |
263 | benchmark(jsonpickle.encode, HOMOGENOUS_COMPLEX_SET) | |
264 | ||
265 | ||
266 | def complex_homogenous_set_decode(benchmark): | |
267 | benchmark(jsonpickle.decode, homogenous_set_encoded) | |
268 | ||
269 | ||
270 | # COMPLEX HETEROGENOUS PRIMITIVE ENCODE/DECODE | |
271 | def complex_heterogenous_dict_encode(benchmark): | |
272 | benchmark(jsonpickle.encode, HETEROGENOUS_COMPLEX_DICT) | |
273 | ||
274 | ||
275 | def complex_heterogenous_dict_decode(benchmark): | |
276 | benchmark(jsonpickle.decode, heterogenous_dict_encoded) | |
277 | ||
278 | ||
279 | def complex_heterogenous_list_encode(benchmark): | |
280 | benchmark(jsonpickle.encode, HETEROGENOUS_COMPLEX_LIST) | |
281 | ||
282 | ||
283 | def complex_heterogenous_list_decode(benchmark): | |
284 | benchmark(jsonpickle.decode, heterogenous_list_encoded) | |
285 | ||
286 | ||
287 | def complex_heterogenous_tuple_encode(benchmark): | |
288 | benchmark(jsonpickle.encode, HETEROGENOUS_COMPLEX_TUPLE) | |
289 | ||
290 | ||
291 | def complex_heterogenous_tuple_decode(benchmark): | |
292 | benchmark(jsonpickle.decode, heterogenous_tuple_encoded) | |
293 | ||
294 | ||
295 | def complex_heterogenous_set_encode(benchmark): | |
296 | benchmark(jsonpickle.encode, HETEROGENOUS_COMPLEX_SET) | |
297 | ||
298 | ||
299 | def complex_heterogenous_set_decode(benchmark): | |
300 | benchmark(jsonpickle.decode, heterogenous_set_encoded) | |
301 | ||
302 | ||
303 | # CUSTOM CLASS ENCODE/DECODE | |
304 | def simple_class_encode(benchmark): | |
305 | benchmark(jsonpickle.encode, MyClassSimple()) | |
306 | ||
307 | ||
308 | def simple_class_decode(benchmark): | |
309 | benchmark(jsonpickle.decode, simple_class_encoded) | |
310 | ||
311 | ||
312 | def complex_class_encode(benchmark): | |
313 | benchmark(jsonpickle.encode, MyClass()) | |
314 | ||
315 | ||
316 | def complex_class_decode(benchmark): | |
317 | benchmark(jsonpickle.decode, class_encoded) | |
318 | ||
319 | ||
320 | def state_class_encode(benchmark): | |
321 | benchmark(jsonpickle.encode, MyClassGetState()) | |
322 | ||
323 | ||
324 | def state_class_decode(benchmark): | |
325 | benchmark(jsonpickle.decode, state_class_encoded) |
0 | 0 | [build-system] |
1 | requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4.1"] | |
1 | # setuptools >= 59 seems to break something with distutils on 3.11 | |
2 | requires = ["setuptools>=42,<59", "wheel", "setuptools_scm[toml]>=3.4.1"] | |
2 | 3 | build-backend = "setuptools.build_meta" |
3 | 4 | |
4 | 5 | [tool.black] |
0 | 0 | [pytest] |
1 | 1 | norecursedirs=dist build .tox .eggs |
2 | addopts=--doctest-modules --flake8 --black --cov | |
2 | addopts=--doctest-modules --cov | |
3 | 3 | doctest_optionflags=ALLOW_UNICODE ELLIPSIS |
4 | 4 | filterwarnings= |
5 | 5 | # https://github.com/pytest-dev/pytest/issues/6928 |
6 | 6 | ignore:direct construction of .*Item has been deprecated:DeprecationWarning |
7 | # flake8 conflicts with black otherwise | |
8 | # we can't make it ignore E501 or else others show up | |
9 | flake8-max-line-length = 2000 | |
10 | # add this so we dont have to put test_ before the benchmarks | |
11 | python_functions = test_* simple_* complex_* state_* |
0 | 0 | bson |
1 | 1 | coverage<5 |
2 | demjson | |
3 | 2 | ecdsa |
4 | enum34; python_version < '3.4' | |
5 | 3 | feedparser |
6 | jsonlib; python_version < '3.0' | |
4 | flake8<5 | |
5 | gmpy2 | |
7 | 6 | numpy |
8 | 7 | pandas |
9 | 8 | pymongo |
10 | 9 | pytest |
11 | pytest-black-multipy | |
12 | 10 | pytest-cov |
13 | pytest-flake8 | |
11 | pytest-flake8>=1.1.1 | |
12 | pytest-benchmark | |
13 | pytest-benchmark[histogram] | |
14 | scikit-learn | |
15 | scipy>=1.9.3; python_version>"3.10" | |
16 | scipy; python_version<="3.10" | |
14 | 17 | simplejson |
15 | sklearn | |
16 | sqlalchemy | |
18 | sqlalchemy>=1.2.19 | |
17 | 19 | ujson |
18 | yajl; sys_platform != 'win32' and python_version < '3.9' |
13 | 13 | Intended Audience :: Developers |
14 | 14 | License :: OSI Approved :: BSD License |
15 | 15 | Programming Language :: Python |
16 | Programming Language :: Python :: 2 | |
17 | Programming Language :: Python :: 2.7 | |
18 | 16 | Programming Language :: Python :: 3 |
17 | Programming Language :: Python :: 3.7 | |
18 | Programming Language :: Python :: 3.8 | |
19 | Programming Language :: Python :: 3.9 | |
20 | Programming Language :: Python :: 3.10 | |
19 | 21 | Programming Language :: JavaScript |
20 | 22 | Operating System :: OS Independent |
21 | 23 | Topic :: Software Development :: Libraries :: Python Modules |
30 | 32 | serialization |
31 | 33 | JavaScript Object Notation |
32 | 34 | |
35 | [tool:pytest] | |
36 | flake8-ignore = E501 | |
37 | ||
33 | 38 | [options] |
34 | 39 | packages = find: |
35 | 40 | include_package_data = true |
36 | python_requires = >=2.7 | |
41 | python_requires = >=3.7 | |
37 | 42 | install_requires = |
38 | 43 | importlib_metadata; python_version<"3.8" |
44 | setuptools<59; python_version>"3.10" | |
39 | 45 | setup_requires = setuptools_scm[toml] >= 3.4.1 |
40 | 46 | |
41 | 47 | [options.extras_require] |
42 | 48 | testing = |
43 | coverage < 5 | |
44 | 49 | pytest >= 3.5, !=3.7.3 |
45 | 50 | pytest-checkdocs >= 1.2.3 |
46 | pytest-flake8 | |
51 | pytest-flake8 >= 1.1.1 | |
47 | 52 | pytest-black-multipy |
48 | 53 | pytest-cov |
49 | 54 | |
50 | 55 | ecdsa |
51 | enum34; python_version=="2.7" | |
52 | 56 | feedparser |
53 | jsonlib; python_version=="2.7" | |
57 | gmpy2 | |
54 | 58 | numpy |
55 | 59 | pandas |
56 | 60 | pymongo |
57 | sklearn | |
61 | scikit-learn | |
58 | 62 | sqlalchemy |
59 | 63 | testing.libs = |
60 | demjson | |
61 | 64 | simplejson |
62 | 65 | ujson |
63 | yajl; python_version<"3.8" | |
64 | 66 | docs = |
65 | 67 | sphinx |
66 | 68 | jaraco.packaging >= 3.2 |
0 | 0 | from __future__ import absolute_import, division, unicode_literals |
1 | ||
1 | 2 | import decimal |
2 | 3 | import unittest |
4 | from hashlib import md5 | |
3 | 5 | from warnings import warn |
4 | 6 | |
7 | from helper import SkippableTest | |
8 | ||
5 | 9 | import jsonpickle |
6 | from jsonpickle import compat | |
7 | from jsonpickle.compat import PY2 | |
8 | from jsonpickle.compat import PY3 | |
9 | ||
10 | from helper import SkippableTest | |
11 | 10 | |
12 | 11 | |
13 | 12 | class Thing(object): |
14 | 13 | def __init__(self, name): |
15 | 14 | self.name = name |
16 | 15 | self.child = None |
16 | ||
17 | ||
18 | class A(object): | |
19 | def __init__(self): | |
20 | self.id = md5(str(id(self)).encode()).hexdigest()[:5] # unique enough hash | |
21 | ||
22 | ||
23 | class BSlots(object): | |
24 | __slots__ = ["a2", "a1", "a3"] | |
25 | ||
26 | def __init__(self): | |
27 | self.a2 = A() # set attribs not in alphabetical order | |
28 | self.a1 = A() | |
29 | self.a3 = self.a1 # create a reference | |
17 | 30 | |
18 | 31 | |
19 | 32 | SAMPLE_DATA = {'things': [Thing('data')]} |
124 | 137 | as_json = jsonpickle.dumps(obj) |
125 | 138 | clone = jsonpickle.loads(as_json) |
126 | 139 | self.assertTrue(isinstance(clone, decimal.Decimal)) |
140 | # options are persisted unless we disable them | |
141 | jsonpickle.set_encoder_options('simplejson', use_decimal=False) | |
142 | jsonpickle.set_decoder_options('simplejson', use_decimal=False) | |
143 | ||
144 | def test_sort_keys(self): | |
145 | jsonpickle.set_encoder_options('simplejson', sort_keys=True) | |
146 | b = BSlots() | |
147 | self.assertRaises(TypeError, jsonpickle.encode, b, keys=True, warn=True) | |
148 | # return encoder options to default | |
149 | jsonpickle.set_encoder_options('simplejson', sort_keys=False) | |
127 | 150 | |
128 | 151 | |
129 | 152 | def has_module(module): |
135 | 158 | return True |
136 | 159 | |
137 | 160 | |
138 | class DemjsonTestCase(BackendBase): | |
139 | def setUp(self): | |
140 | self.set_preferred_backend('demjson') | |
141 | ||
142 | def test_backend(self): | |
143 | expected_pickled = compat.ustr( | |
144 | '{"things":[{' | |
145 | '"child":null,' | |
146 | '"name":"data",' | |
147 | '"py/object":"backend_test.Thing"}' | |
148 | ']}' | |
149 | ) | |
150 | self.assertEncodeDecode(expected_pickled) | |
151 | ||
152 | def test_int_dict_keys_with_numeric_keys(self): | |
153 | jsonpickle.set_encoder_options('demjson', strict=False) | |
154 | int_dict = {1000: [1, 2]} | |
155 | pickle = jsonpickle.encode(int_dict, numeric_keys=True) | |
156 | actual = jsonpickle.decode(pickle) | |
157 | self.assertEqual(actual[1000], [1, 2]) | |
158 | ||
159 | ||
160 | class JsonlibTestCase(BackendBase): | |
161 | def setUp(self): | |
162 | if PY2: | |
163 | self.set_preferred_backend('jsonlib') | |
164 | ||
165 | def test_backend(self): | |
166 | if PY3: | |
167 | return self.skip('no jsonlib for python3') | |
168 | expected_pickled = ( | |
169 | '{"things":[{' | |
170 | r'"py\/object":"backend_test.Thing",' | |
171 | '"name":"data","child":null}' | |
172 | ']}' | |
173 | ) | |
174 | self.assertEncodeDecode(expected_pickled) | |
175 | ||
176 | ||
177 | 161 | class YajlTestCase(BackendBase): |
178 | 162 | def setUp(self): |
179 | 163 | self.set_preferred_backend('yajl') |
207 | 191 | suite.addTest(unittest.makeSuite(JsonTestCase)) |
208 | 192 | suite.addTest(unittest.makeSuite(UJsonTestCase)) |
209 | 193 | suite.addTest(unittest.makeSuite(SimpleJsonTestCase)) |
210 | if has_module('demjson'): | |
211 | suite.addTest(unittest.makeSuite(DemjsonTestCase)) | |
212 | 194 | if has_module('yajl'): |
213 | 195 | suite.addTest(unittest.makeSuite(YajlTestCase)) |
214 | if PY2: | |
215 | if has_module('jsonlib'): | |
216 | suite.addTest(unittest.makeSuite(JsonlibTestCase)) | |
217 | 196 | return suite |
218 | 197 | |
219 | 198 |
4 | 4 | import pickle |
5 | 5 | import unittest |
6 | 6 | |
7 | from helper import SkippableTest | |
8 | ||
7 | 9 | import jsonpickle |
8 | ||
9 | from helper import SkippableTest | |
10 | 10 | |
11 | 11 | bson = None |
12 | 12 |
33 | 33 | Unit tests for collections |
34 | 34 | """ |
35 | 35 | from __future__ import absolute_import, division, print_function, unicode_literals |
36 | ||
37 | import sys | |
36 | 38 | from collections import OrderedDict, defaultdict |
37 | import sys | |
38 | 39 | |
39 | 40 | import pytest |
40 | 41 | |
41 | 42 | import jsonpickle |
42 | from jsonpickle.compat import PY2 | |
43 | 43 | |
44 | 44 | __status__ = "Stable" |
45 | 45 | __version__ = "1.0.0" |
55 | 55 | |
56 | 56 | Tests restorable collections by creating pickled structures featuring |
57 | 57 | no cycles, self cycles, and mutual cycles, for all supported dictionary and |
58 | set wrappers. Python bult-in dictionaries and sets are also tested with | |
58 | set wrappers. Python built-in dictionaries and sets are also tested with | |
59 | 59 | expectation of failure via raising exceptions. |
60 | 60 | |
61 | 61 | """ |
85 | 85 | self.plain_default[key] = (key, value) |
86 | 86 | |
87 | 87 | def __hash__(self): |
88 | # return id(self) | |
89 | # the original __hash__() below means the hash can change after being | |
90 | # stored, which JP does not support on Python 2. | |
91 | if PY2: | |
92 | return id(self) | |
93 | 88 | return hash(self.v) if hasattr(self, 'v') else id(self) |
94 | 89 | |
95 | 90 | def __repr__(self): |
110 | 105 | self.plain.add(item) |
111 | 106 | |
112 | 107 | def __hash__(self): |
113 | if PY2: | |
114 | return id(self) | |
115 | 108 | return hash(self.v) if hasattr(self, 'v') else id(self) |
116 | 109 | |
117 | 110 | def __repr__(self): |
216 | 209 | plain_keys = list(c1u.plain.keys()) |
217 | 210 | ordered_keys = list(c1u.plain_ordered.keys()) |
218 | 211 | default_keys = list(c1u.plain_default.keys()) |
219 | if PY2: | |
220 | value = 67 | |
221 | else: | |
222 | value = 42 | |
212 | value = 42 | |
223 | 213 | assert value == c1u.plain[plain_keys[0]][0].v |
224 | 214 | 42 == c1u.plain_ordered[ordered_keys[0]][0].v |
225 | 215 | 42 == c1u.plain_default[default_keys[0]][0].v |
226 | 216 | |
227 | 217 | # key c2u |
228 | 218 | # succeeds because c2u does not have a cycle to itself |
229 | if PY2: | |
230 | key = c1u | |
231 | else: | |
232 | key = c2u | |
233 | assert key == c1u.plain[plain_keys[1]][0] | |
219 | assert c2u == c1u.plain[plain_keys[1]][0] | |
234 | 220 | # succeeds because c2u does not have a cycle to itself |
235 | 221 | assert c2u == c1u.plain_ordered[ordered_keys[1]][0] |
236 | 222 | assert 67 == c1u.plain_default[default_keys[1]][0].v |
5 | 5 | # This software is licensed as described in the file COPYING, which |
6 | 6 | # you should have received as part of this distribution. |
7 | 7 | |
8 | import unittest | |
9 | 8 | import datetime |
10 | 9 | import time |
10 | import unittest | |
11 | 11 | |
12 | 12 | import jsonpickle |
13 | 13 | from jsonpickle import tags |
57 | 57 | self._dt_write = datetime.datetime.utcnow() |
58 | 58 | self._value = new_value |
59 | 59 | |
60 | def erasable(self, td=datetime.timedelta(seconds=1)): | |
61 | dt_now = datetime.datetime.utcnow() | |
62 | td_read = dt_now - self._dt_read | |
63 | td_write = dt_now - self._dt_write | |
64 | return td_read > td and td_write > td | |
65 | ||
60 | 66 | def __repr__(self): |
61 | 67 | dt_now = datetime.datetime.utcnow() |
62 | 68 | td_read = dt_now - self._dt_read |
67 | 73 | s += ' dt_write: ' + str(self._dt_write) + ' (%s ago)' % td_write + '\n' |
68 | 74 | return s |
69 | 75 | |
70 | def erasable(self, td=datetime.timedelta(seconds=1)): | |
71 | dt_now = datetime.datetime.utcnow() | |
72 | td_read = dt_now - self._dt_read | |
73 | td_write = dt_now - self._dt_write | |
74 | return td_read > td and td_write > td | |
75 | ||
76 | 76 | |
77 | 77 | class PersistantVariables(object): |
78 | 78 | def __init__(self): |
0 | 0 | # -*- coding: utf-8 -*- |
1 | 1 | |
2 | 2 | import unittest |
3 | ||
3 | 4 | import jsonpickle |
4 | 5 | |
5 | 6 | |
20 | 21 | def __init__(self, name): |
21 | 22 | Node.__init__(self, name) |
22 | 23 | |
24 | def __repr__(self): | |
25 | return str(self) | |
26 | ||
23 | 27 | def __str__(self): |
24 | 28 | ret_str = 'Document "%s"\n' % self._name |
25 | 29 | for c in self._children: |
26 | 30 | ret_str += repr(c) |
27 | 31 | return ret_str |
28 | ||
29 | def __repr__(self): | |
30 | return str(self) | |
31 | 32 | |
32 | 33 | |
33 | 34 | class Question(Node): |
0 | 0 | """Test serializing ecdsa keys""" |
1 | 1 | from __future__ import absolute_import, division, unicode_literals |
2 | ||
2 | 3 | import unittest |
4 | ||
5 | import pytest | |
6 | from helper import SkippableTest | |
3 | 7 | |
4 | 8 | import jsonpickle |
5 | 9 | |
6 | from helper import SkippableTest | |
10 | ||
11 | @pytest.fixture(scope='module', autouse=True) | |
12 | def gmpy_extension(): | |
13 | """Initialize the gmpy extension for this test module""" | |
14 | jsonpickle.ext.gmpy.register_handlers() | |
15 | yield # control to the test function. | |
16 | jsonpickle.ext.gmpy.unregister_handlers() | |
7 | 17 | |
8 | 18 | |
9 | 19 | class EcdsaTestCase(SkippableTest): |
7 | 7 | |
8 | 8 | import unittest |
9 | 9 | |
10 | from helper import SkippableTest | |
11 | ||
10 | 12 | import jsonpickle |
11 | ||
12 | from helper import SkippableTest | |
13 | 13 | |
14 | 14 | RSS_DOC = """<?xml version="1.0" encoding="utf-8"?> |
15 | 15 | <feed xmlns="http://www.w3.org/2005/Atom" |
4 | 4 | # This software is licensed as described in the file COPYING, which |
5 | 5 | # you should have received as part of this distribution. |
6 | 6 | from __future__ import absolute_import, division, unicode_literals |
7 | ||
8 | import collections | |
7 | 9 | import os |
8 | 10 | import unittest |
9 | import collections | |
11 | import warnings | |
10 | 12 | |
11 | 13 | import pytest |
14 | from helper import SkippableTest | |
12 | 15 | |
13 | 16 | import jsonpickle |
14 | 17 | import jsonpickle.backend |
15 | 18 | import jsonpickle.handlers |
16 | 19 | from jsonpickle import compat, tags, util |
17 | from jsonpickle.compat import PY2, PY3 | |
18 | from helper import SkippableTest | |
19 | ||
20 | ||
21 | class Thing(object): | |
20 | ||
21 | ||
22 | class ListLike: | |
23 | def __init__(self): | |
24 | self.internal_list = [] | |
25 | ||
26 | def append(self, item): | |
27 | self.internal_list.append(item) | |
28 | ||
29 | def __getitem__(self, i): | |
30 | return self.internal_list[i] | |
31 | ||
32 | ||
33 | class Thing: | |
22 | 34 | def __init__(self, name): |
23 | 35 | self.name = name |
24 | 36 | self.child = None |
25 | 37 | |
38 | def __iter__(self): | |
39 | for attr in [ | |
40 | x for x in getattr(self.__class__, "__dict__") if not x.startswith("__") | |
41 | ]: | |
42 | yield attr, getattr(self, attr) | |
43 | ||
26 | 44 | def __repr__(self): |
27 | 45 | return 'Thing("%s")' % self.name |
28 | 46 | |
29 | 47 | |
30 | class Capture(object): | |
48 | class Capture: | |
31 | 49 | def __init__(self, *args, **kwargs): |
32 | 50 | self.args = args |
33 | 51 | self.kwargs = kwargs |
34 | 52 | |
35 | 53 | |
36 | class ThingWithProps(object): | |
54 | class ThingWithProps: | |
55 | def _get_identity(self): | |
56 | keys = [self.dogs, self.monkies, self.name] | |
57 | return hash('-'.join([str(key) for key in keys])) | |
58 | ||
59 | identity = property(_get_identity) | |
60 | ||
61 | def _get_dogs(self): | |
62 | return self._critters[0][1] | |
63 | ||
64 | dogs = property(_get_dogs) | |
65 | ||
66 | def _get_monkies(self): | |
67 | return self._critters[1][1] | |
68 | ||
69 | monkies = property(_get_monkies) | |
70 | ||
37 | 71 | def __init__(self, name='', dogs='reliable', monkies='tricksy'): |
38 | 72 | self.name = name |
39 | 73 | self._critters = (('dogs', dogs), ('monkies', monkies)) |
40 | 74 | |
41 | def _get_identity(self): | |
42 | keys = [self.dogs, self.monkies, self.name] | |
43 | return hash('-'.join([str(key) for key in keys])) | |
44 | ||
45 | identity = property(_get_identity) | |
46 | ||
47 | def _get_dogs(self): | |
48 | return self._critters[0][1] | |
49 | ||
50 | dogs = property(_get_dogs) | |
51 | ||
52 | def _get_monkies(self): | |
53 | return self._critters[1][1] | |
54 | ||
55 | monkies = property(_get_monkies) | |
75 | def __eq__(self, other): | |
76 | return self.identity == other.identity | |
56 | 77 | |
57 | 78 | def __getstate__(self): |
58 | 79 | out = dict( |
71 | 92 | self.name = state_dict.get('nom', '') |
72 | 93 | ident = state_dict.get('__identity__') |
73 | 94 | if ident != self.identity: |
74 | raise ValueError('expanded object does not match originial state!') | |
75 | ||
76 | def __eq__(self, other): | |
77 | return self.identity == other.identity | |
95 | raise ValueError('expanded object does not match original state!') | |
78 | 96 | |
79 | 97 | |
80 | 98 | class UserDict(dict): |
85 | 103 | self.valid = False |
86 | 104 | |
87 | 105 | |
88 | class Outer(object): | |
89 | class Middle(object): | |
90 | class Inner(object): | |
106 | class Outer: | |
107 | class Middle: | |
108 | class Inner: | |
91 | 109 | pass |
110 | ||
111 | ||
112 | class MySlots: | |
113 | __slots__ = ("alpha", "__beta") | |
114 | ||
115 | def __init__(self): | |
116 | self.alpha = 1 | |
117 | self.__beta = 1 | |
118 | ||
119 | ||
120 | class MyPropertiesSlots: | |
121 | __slots__ = ("alpha", "arr") | |
122 | ||
123 | def __init__(self): | |
124 | self.alpha = 1 | |
125 | self.arr = [1, 2, 3] | |
126 | ||
127 | @property | |
128 | def arr_len(self): | |
129 | return len(self.arr) | |
130 | ||
131 | @property | |
132 | def other_object(self): | |
133 | return Thing("Test") | |
134 | ||
135 | def __eq__(self, other): | |
136 | return ( | |
137 | self.alpha == other.alpha | |
138 | and self.arr == other.arr | |
139 | and self.arr_len == other.arr_len | |
140 | and list(self.other_object) == list(other.other_object) | |
141 | ) | |
142 | ||
143 | ||
144 | class MyPropertiesDict: | |
145 | def __init__(self): | |
146 | self.alpha = 1 | |
147 | self.arr = [1, 2, 3] | |
148 | ||
149 | @property | |
150 | def arr_len(self): | |
151 | return len(self.arr) | |
152 | ||
153 | @property | |
154 | def other_object(self): | |
155 | return Thing("Test") | |
156 | ||
157 | def __eq__(self, other): | |
158 | return ( | |
159 | self.alpha == other.alpha | |
160 | and self.arr == other.arr | |
161 | and self.arr_len == other.arr_len | |
162 | and list(self.other_object) == list(other.other_object) | |
163 | ) | |
164 | ||
165 | ||
166 | def on_missing_callback(class_name): | |
167 | # not actually a runtime problem but it doesn't matter | |
168 | warnings.warn("The unpickler couldn't find %s" % class_name, RuntimeWarning) | |
92 | 169 | |
93 | 170 | |
94 | 171 | class PicklingTestCase(unittest.TestCase): |
101 | 178 | self.pickler.reset() |
102 | 179 | self.unpickler.reset() |
103 | 180 | |
104 | @unittest.skipIf(not PY2, 'Python 2-specific base85 test') | |
105 | def test_base85_always_false_on_py2(self): | |
106 | self.assertFalse(self.b85_pickler.use_base85) | |
107 | ||
108 | @unittest.skipIf(PY2, 'Base85 not supported on Python 2') | |
109 | 181 | def test_base85_override_py3(self): |
110 | 182 | """Ensure the Python 2 check still lets us set use_base85 on Python 3""" |
111 | 183 | self.assertTrue(self.b85_pickler.use_base85) |
112 | 184 | |
113 | @unittest.skipIf(PY2, 'Base85 not supported on Python 2') | |
114 | 185 | def test_bytes_default_base85(self): |
115 | 186 | data = os.urandom(16) |
116 | 187 | encoded = util.b85encode(data) |
117 | 188 | self.assertEqual({tags.B85: encoded}, self.b85_pickler.flatten(data)) |
118 | 189 | |
119 | @unittest.skipIf(PY2, 'Base85 not supported on Python 2') | |
120 | 190 | def test_py3_bytes_base64_default(self): |
121 | 191 | data = os.urandom(16) |
122 | 192 | encoded = util.b64encode(data) |
123 | 193 | self.assertEqual({tags.B64: encoded}, self.pickler.flatten(data)) |
124 | 194 | |
125 | @unittest.skipIf(not PY2, 'Python 2-specific base64 test') | |
126 | def test_py2_default_base64(self): | |
127 | data = os.urandom(16) | |
128 | encoded = util.b64encode(data) | |
129 | self.assertEqual({tags.B64: encoded}, self.pickler.flatten(data)) | |
130 | ||
131 | @unittest.skipIf(PY2, 'Base85 not supported on Python 2') | |
132 | 195 | def test_decode_base85(self): |
133 | 196 | pickled = {tags.B85: 'P{Y4;Xv4O{u^=-c'} |
134 | 197 | expected = u'P\u00ffth\u00f6\u00f1 3!'.encode('utf-8') |
135 | 198 | self.assertEqual(expected, self.unpickler.restore(pickled)) |
136 | 199 | |
137 | @unittest.skipIf(PY2, 'Base85 not supported on Python 2') | |
138 | 200 | def test_base85_still_handles_base64(self): |
139 | 201 | pickled = {tags.B64: 'UMO/dGjDtsOxIDMh'} |
140 | 202 | expected = u'P\u00ffth\u00f6\u00f1 3!'.encode('utf-8') |
141 | 203 | self.assertEqual(expected, self.unpickler.restore(pickled)) |
142 | ||
143 | @unittest.skipIf(not PY2, 'Python 2-specific base85 test') | |
144 | def test_base85_crashes_py2(self): | |
145 | with self.assertRaises(NotImplementedError): | |
146 | self.unpickler.restore({tags.B85: 'P{Y4;Xv4O{u^=-c'}) | |
147 | 204 | |
148 | 205 | def test_string(self): |
149 | 206 | self.assertEqual('a string', self.pickler.flatten('a string')) |
433 | 490 | no longer supported. |
434 | 491 | """ |
435 | 492 | ae = jsonpickle.decode('{"py/type": "__builtin__.AssertionError"}') |
436 | assert ae is AssertionError | |
493 | self.assertTrue(ae is AssertionError) | |
437 | 494 | ae = jsonpickle.decode('{"py/type": "exceptions.AssertionError"}') |
438 | assert ae is AssertionError | |
495 | self.assertTrue(ae is AssertionError) | |
439 | 496 | cls = jsonpickle.decode('{"py/type": "__builtin__.int"}') |
440 | assert cls is int | |
497 | self.assertTrue(cls is int) | |
498 | ||
499 | def test_unpickler_on_missing(self): | |
500 | class SimpleClass(object): | |
501 | def __init__(self, i): | |
502 | self.i = i | |
503 | ||
504 | frozen = jsonpickle.encode(SimpleClass(4)) | |
505 | del SimpleClass | |
506 | ||
507 | # https://docs.python.org/3/library/warnings.html#testing-warnings | |
508 | ||
509 | with warnings.catch_warnings(record=True) as w: | |
510 | warnings.simplefilter("always") | |
511 | jsonpickle.decode(frozen, on_missing='warn') | |
512 | self.assertTrue(issubclass(w[-1].category, UserWarning)) | |
513 | self.assertTrue( | |
514 | "Unpickler._restore_object could not find" in str(w[-1].message) | |
515 | ) | |
516 | ||
517 | jsonpickle.decode(frozen, on_missing=on_missing_callback) | |
518 | self.assertTrue(issubclass(w[-1].category, RuntimeWarning)) | |
519 | self.assertTrue("The unpickler couldn't find" in str(w[-1].message)) | |
520 | ||
521 | self.assertTrue( | |
522 | jsonpickle.decode(frozen, on_missing='ignore') | |
523 | == { | |
524 | 'py/object': 'jsonpickle_test.PicklingTestCase.test_unpickler_on_missing.<locals>.SimpleClass', | |
525 | 'i': 4, | |
526 | } | |
527 | ) | |
528 | ||
529 | try: | |
530 | jsonpickle.decode(frozen, on_missing='error') | |
531 | except jsonpickle.errors.ClassNotFoundError: | |
532 | # it's supposed to error | |
533 | self.assertTrue(True) | |
534 | else: | |
535 | self.assertTrue(False) | |
536 | ||
537 | def test_private_slot_members(self): | |
538 | obj = jsonpickle.loads(jsonpickle.dumps(MySlots())) | |
539 | alpha = getattr(obj, "alpha", "(missing alpha)") | |
540 | beta = getattr(obj, "_" + obj.__class__.__name__ + "__beta", "(missing beta)") | |
541 | self.assertEqual(alpha, beta) | |
542 | ||
543 | def test_include_properties_slots(self): | |
544 | obj = MyPropertiesSlots() | |
545 | dumped = jsonpickle.dumps(obj, include_properties=True) | |
546 | self.assertTrue("py/property" in dumped) | |
547 | self.assertEqual(obj, jsonpickle.loads(dumped)) | |
548 | ||
549 | def test_include_properties_dict(self): | |
550 | obj = MyPropertiesDict() | |
551 | dumped = jsonpickle.dumps(obj, include_properties=True) | |
552 | self.assertTrue("py/property" in dumped) | |
553 | self.assertEqual(obj, jsonpickle.loads(dumped)) | |
554 | ||
555 | def test_load_non_fully_qualified_classes(self): | |
556 | # reuse MyPropertiesSlots because it has a nice eq method | |
557 | obj = MyPropertiesSlots() | |
558 | encoded = jsonpickle.encode(obj) | |
559 | # MyPropertiesSlots and MyPropertiesDict have compatible eq methods | |
560 | self.assertEqual( | |
561 | obj, | |
562 | jsonpickle.decode(encoded, classes={"MyPropertiesSlots": MyPropertiesDict}), | |
563 | ) | |
441 | 564 | |
442 | 565 | |
443 | 566 | class JSONPickleTestCase(SkippableTest): |
494 | 617 | self.assertEqual(type(self.obj), type(actual)) |
495 | 618 | |
496 | 619 | def test_unicode_dict_keys(self): |
497 | if PY2: | |
498 | uni = unichr(0x1234) # noqa | |
499 | else: | |
500 | uni = chr(0x1234) | |
620 | uni = chr(0x1234) | |
501 | 621 | pickle = jsonpickle.encode({uni: uni}) |
502 | 622 | actual = jsonpickle.decode(pickle) |
503 | 623 | self.assertTrue(uni in actual) |
767 | 887 | assert decoded.b[0] == 1 |
768 | 888 | assert decoded.a[1][0:3] == '[1,' |
769 | 889 | assert decoded.a[2][0][0:3] == '[1,' |
890 | ||
891 | def _test_inner_class(self, InnerScope, obj, decoded): | |
892 | self.assertTrue(isinstance(obj, InnerScope)) | |
893 | self.assertEqual(decoded.name, obj.name) | |
770 | 894 | |
771 | 895 | def test_can_serialize_inner_classes(self): |
772 | 896 | class InnerScope(object): |
790 | 914 | decoded = jsonpickle.decode(encoded, classes={InnerScope}) |
791 | 915 | self._test_inner_class(InnerScope, obj, decoded) |
792 | 916 | |
793 | def _test_inner_class(self, InnerScope, obj, decoded): | |
794 | self.assertTrue(isinstance(obj, InnerScope)) | |
795 | self.assertEqual(decoded.name, obj.name) | |
796 | ||
797 | 917 | def test_can_serialize_nested_classes(self): |
798 | if PY2: | |
799 | return self.skip('Serialization of nested classes requires ' 'Python >= 3') | |
800 | ||
801 | 918 | middle = Outer.Middle |
802 | 919 | inner = Outer.Middle.Inner |
803 | 920 | encoded_middle = jsonpickle.encode(middle) |
812 | 929 | self.assertEqual(decoded_inner, inner) |
813 | 930 | |
814 | 931 | def test_can_serialize_nested_class_objects(self): |
815 | if PY2: | |
816 | return self.skip('Serialization of nested classes requires ' 'Python >= 3') | |
817 | ||
818 | 932 | middle_obj = Outer.Middle() |
819 | 933 | middle_obj.attribute = 5 |
820 | 934 | inner_obj = Outer.Middle.Inner() |
829 | 943 | self.assertTrue(isinstance(decoded_inner_obj, Outer.Middle.Inner)) |
830 | 944 | self.assertEqual(decoded_middle_obj.attribute, middle_obj.attribute) |
831 | 945 | self.assertEqual(decoded_inner_obj.attribute, inner_obj.attribute) |
946 | ||
947 | def test_listlike(self): | |
948 | """ | |
949 | https://github.com/jsonpickle/jsonpickle/issues/362 | |
950 | """ | |
951 | ll = ListLike() | |
952 | ll.internal_list.append(1) | |
953 | roundtrip_ll = jsonpickle.decode(jsonpickle.encode(ll)) | |
954 | self.assertEqual(len(ll.internal_list), len(roundtrip_ll.internal_list)) | |
955 | ||
956 | def test_v1_decode(self): | |
957 | # TODO: Find a simple example that reproduces #364 | |
958 | self.assertTrue(True) | |
832 | 959 | |
833 | 960 | |
834 | 961 | class PicklableNamedTuple(object): |
945 | 1072 | |
946 | 1073 | |
947 | 1074 | class PickleProtocol2ReduceExString(object): |
1075 | def __reduce_ex__(self, n): | |
1076 | return __name__ + '.slotmagic' | |
1077 | ||
948 | 1078 | def __reduce__(self): |
949 | 1079 | assert False, "Should not be here" |
950 | ||
951 | def __reduce_ex__(self, n): | |
952 | return __name__ + '.slotmagic' | |
953 | 1080 | |
954 | 1081 | |
955 | 1082 | class PickleProtocol2ReduceTuple(object): |
969 | 1096 | |
970 | 1097 | @compat.iterator |
971 | 1098 | class ReducibleIterator(object): |
1099 | def __next__(self): | |
1100 | raise StopIteration() | |
1101 | ||
972 | 1102 | def __iter__(self): |
973 | 1103 | return self |
974 | ||
975 | def __next__(self): | |
976 | raise StopIteration() | |
977 | 1104 | |
978 | 1105 | def __reduce__(self): |
979 | 1106 | return ReducibleIterator, () |
1032 | 1159 | |
1033 | 1160 | |
1034 | 1161 | class PickleProtocol2ReduceTupleSetState(PickleProtocol2ReduceTuple): |
1035 | def __setstate__(self, state): | |
1036 | self.bar = state['foo'] | |
1037 | ||
1038 | 1162 | def __reduce__(self): |
1039 | 1163 | return ( |
1040 | 1164 | type(self), # callable |
1044 | 1168 | iter([]), # dictitems |
1045 | 1169 | ) |
1046 | 1170 | |
1171 | def __setstate__(self, state): | |
1172 | self.bar = state['foo'] | |
1173 | ||
1047 | 1174 | |
1048 | 1175 | class PickleProtocol2ReduceTupleStateSlots(object): |
1049 | 1176 | __slots__ = ('argval', 'optional', 'foo') |
1066 | 1193 | def __init__(self): |
1067 | 1194 | self.inner = [] |
1068 | 1195 | |
1196 | def append(self, item): | |
1197 | self.inner.append(item) | |
1198 | ||
1069 | 1199 | def __reduce__(self): |
1070 | 1200 | return ( |
1071 | 1201 | PickleProtocol2ReduceListitemsAppend, # callable |
1075 | 1205 | iter([]), # dictitems |
1076 | 1206 | ) |
1077 | 1207 | |
1078 | def append(self, item): | |
1079 | self.inner.append(item) | |
1080 | ||
1081 | 1208 | |
1082 | 1209 | class PickleProtocol2ReduceListitemsExtend(object): |
1083 | 1210 | def __init__(self): |
1084 | 1211 | self.inner = [] |
1212 | ||
1213 | def extend(self, items): | |
1214 | self.inner.exend(items) | |
1085 | 1215 | |
1086 | 1216 | def __reduce__(self): |
1087 | 1217 | return ( |
1092 | 1222 | iter([]), # dictitems |
1093 | 1223 | ) |
1094 | 1224 | |
1095 | def extend(self, items): | |
1096 | self.inner.exend(items) | |
1097 | ||
1098 | 1225 | |
1099 | 1226 | class PickleProtocol2ReduceDictitems(object): |
1100 | 1227 | def __init__(self): |
1101 | 1228 | self.inner = {} |
1229 | ||
1230 | def __setitem__(self, k, v): | |
1231 | return self.inner.__setitem__(k, v) | |
1102 | 1232 | |
1103 | 1233 | def __reduce__(self): |
1104 | 1234 | return ( |
1109 | 1239 | iter(zip(['foo', 'bar'], ['foo', 'bar'])), # dictitems |
1110 | 1240 | ) |
1111 | 1241 | |
1112 | def __setitem__(self, k, v): | |
1113 | return self.inner.__setitem__(k, v) | |
1114 | ||
1115 | 1242 | |
1116 | 1243 | class PickleProtocol2Classic: |
1117 | 1244 | def __init__(self, foo): |
1132 | 1259 | def test_pickle_newargs_ex(self): |
1133 | 1260 | """ |
1134 | 1261 | Ensure we can pickle and unpickle an object whose class needs arguments |
1135 | to __new__ and get back the same typle | |
1262 | to __new__ and get back the same type | |
1136 | 1263 | """ |
1137 | 1264 | instance = PicklableNamedTupleEx(**{'a': 'b', 'n': 2}) |
1138 | 1265 | encoded = jsonpickle.encode(instance) |
1178 | 1305 | |
1179 | 1306 | |
1180 | 1307 | class PicklingProtocol2TestCase(SkippableTest): |
1181 | def test_classic_init_has_args(self): | |
1182 | """ | |
1183 | Test unpickling a classic instance whose init takes args, | |
1184 | has no __getinitargs__ | |
1185 | Because classic only exists under 2, skipped if PY3 | |
1186 | """ | |
1187 | if PY3: | |
1188 | return self.skip('No classic classes in PY3') | |
1189 | instance = PickleProtocol2Classic(3) | |
1190 | encoded = jsonpickle.encode(instance) | |
1191 | decoded = jsonpickle.decode(encoded) | |
1192 | self.assertEqual(decoded.foo, 3) | |
1193 | ||
1194 | def test_getinitargs(self): | |
1195 | """ | |
1196 | Test __getinitargs__ with classic instance | |
1197 | ||
1198 | Because classic only exists under 2, skipped if PY3 | |
1199 | """ | |
1200 | if PY3: | |
1201 | return self.skip('No classic classes in PY3') | |
1202 | instance = PickleProtocol2ClassicInitargs(3) | |
1203 | encoded = jsonpickle.encode(instance) | |
1204 | decoded = jsonpickle.decode(encoded) | |
1205 | self.assertEqual(decoded.bar, 'choo') | |
1206 | ||
1207 | 1308 | def test_reduce_complex_num(self): |
1208 | 1309 | instance = 5j |
1209 | 1310 | encoded = jsonpickle.encode(instance) |
1348 | 1449 | def test_pickle_newargs(self): |
1349 | 1450 | """ |
1350 | 1451 | Ensure we can pickle and unpickle an object whose class needs arguments |
1351 | to __new__ and get back the same typle | |
1452 | to __new__ and get back the same type | |
1352 | 1453 | """ |
1353 | 1454 | instance = PicklableNamedTuple(('a', 'b'), (1, 2)) |
1354 | 1455 | encoded = jsonpickle.encode(instance) |
0 | 0 | from __future__ import absolute_import, division, unicode_literals |
1 | ||
1 | 2 | import datetime |
2 | 3 | import warnings |
3 | 4 | |
14 | 15 | import jsonpickle |
15 | 16 | import jsonpickle.ext.numpy |
16 | 17 | from jsonpickle import handlers |
17 | from jsonpickle.compat import PY2 | |
18 | 18 | |
19 | 19 | |
20 | 20 | @pytest.fixture(scope='module', autouse=True) |
31 | 31 | |
32 | 32 | def test_dtype_roundtrip(): |
33 | 33 | dtypes = [ |
34 | np.int, | |
35 | np.float, | |
36 | np.complex, | |
34 | np.int_, | |
37 | 35 | np.int32, |
38 | np.str, | |
39 | np.object, | |
40 | np.unicode, | |
36 | np.float_, | |
37 | np.float64, | |
38 | np.complex_, | |
39 | np.complex128, | |
40 | np.str_, | |
41 | np.object_, | |
42 | np.compat.unicode, | |
41 | 43 | np.dtype(np.void), |
42 | 44 | np.dtype(np.int32), |
43 | 45 | np.dtype(np.float32), |
44 | 46 | np.dtype('f4,i4,f2,i1'), |
45 | 47 | np.dtype(('f4', 'i4'), ('f2', 'i1')), |
46 | np.dtype('1i4', align=True), | |
48 | np.dtype('i4', align=True), | |
47 | 49 | np.dtype('M8[7D]'), |
48 | 50 | np.dtype( |
49 | 51 | { |
125 | 127 | np.array([0, 1, -1, np.inf, -np.inf, np.nan], dtype='f2'), |
126 | 128 | ] |
127 | 129 | |
128 | if not PY2: | |
129 | arrays.extend( | |
130 | [ | |
131 | np.rec.array( | |
132 | [('NGC1001', 11), ('NGC1002', 1.0), ('NGC1003', 1.0)], | |
133 | dtype=[('target', 'S20'), ('V_mag', 'f4')], | |
134 | ) | |
135 | ] | |
136 | ) | |
130 | arrays.extend( | |
131 | [ | |
132 | np.rec.array( | |
133 | [('NGC1001', 11), ('NGC1002', 1.0), ('NGC1003', 1.0)], | |
134 | dtype=[('target', 'S20'), ('V_mag', 'f4')], | |
135 | ) | |
136 | ] | |
137 | ) | |
137 | 138 | for array in arrays: |
138 | 139 | decoded = roundtrip(array) |
139 | 140 | assert_equal(decoded, array) |
196 | 197 | a.strides = 1 |
197 | 198 | |
198 | 199 | # this is kinda fishy; a has overlapping memory, _a does not |
199 | if PY2: | |
200 | warn_count = 0 | |
201 | else: | |
202 | warn_count = 1 | |
200 | warn_count = 1 | |
203 | 201 | with warnings.catch_warnings(record=True) as w: |
204 | 202 | _a = roundtrip(a) |
205 | 203 | assert len(w) == warn_count |
250 | 248 | b = a[1:, 1:] |
251 | 249 | assert b.base is a |
252 | 250 | |
253 | if PY2: | |
254 | warn_count = 0 | |
255 | else: | |
256 | warn_count = 1 | |
251 | warn_count = 1 | |
257 | 252 | with warnings.catch_warnings(record=True) as w: |
258 | 253 | _a, _b = roundtrip([a, b]) |
259 | 254 | assert len(w) == warn_count |
272 | 267 | """test behavior with memoryviews which are not ndarrays""" |
273 | 268 | bstring = 'abcdefgh'.encode('utf-8') |
274 | 269 | a = np.frombuffer(bstring, dtype=np.byte) |
275 | if PY2: | |
276 | warn_count = 0 | |
277 | else: | |
278 | warn_count = 1 | |
270 | warn_count = 1 | |
279 | 271 | with warnings.catch_warnings(record=True) as w: |
280 | 272 | _a = roundtrip(a) |
281 | 273 | npt.assert_array_equal(a, _a) |
289 | 281 | is not an ndarray. |
290 | 282 | |
291 | 283 | """ |
292 | if PY2: | |
293 | warn_count = 0 | |
294 | else: | |
295 | warn_count = 1 | |
284 | warn_count = 1 | |
296 | 285 | a = np.arange(10) |
297 | 286 | b = np.lib.stride_tricks.as_strided(a, shape=(5,), strides=(a.dtype.itemsize * 2,)) |
298 | 287 | data = [a, b] |
336 | 325 | |
337 | 326 | |
338 | 327 | def test_zero_dimensional_array(): |
339 | expect = np.array(0.0) | |
340 | actual = roundtrip(expect) | |
328 | expect = np.array(float(0.0), dtype="float64") | |
329 | actual = jsonpickle.decode(jsonpickle.encode(expect)) | |
341 | 330 | npt.assert_array_equal(expect, actual) |
342 | 331 | |
343 | 332 | |
362 | 351 | |
363 | 352 | |
364 | 353 | def test_ndarray_dtype_object(): |
365 | a = np.array(['F' + str(i) for i in range(30)], dtype=np.object) | |
354 | a = np.array(['F' + str(i) for i in range(30)], dtype=object) | |
366 | 355 | buf = jsonpickle.encode(a) |
367 | 356 | # This is critical for reproducing the numpy segfault issue when |
368 | 357 | # restoring ndarray of dtype object. |
369 | 358 | del a |
370 | expect = np.array(['F' + str(i) for i in range(30)], dtype=np.object) | |
359 | expect = np.array(['F' + str(i) for i in range(30)], dtype=object) | |
371 | 360 | actual = jsonpickle.decode(buf) |
372 | 361 | npt.assert_array_equal(expect, actual) |
373 | 362 | |
382 | 371 | assert expect == actual |
383 | 372 | |
384 | 373 | |
374 | def test_np_poly1d(): | |
375 | # issue 391, test poly1d roundtrip | |
376 | obj = np.poly1d([1, 2, 3]) | |
377 | assert obj == jsonpickle.decode(jsonpickle.encode(obj)) | |
378 | ||
379 | ||
385 | 380 | if __name__ == '__main__': |
386 | 381 | pytest.main([__file__]) |
0 | 0 | from __future__ import absolute_import, division, unicode_literals |
1 | ||
1 | 2 | import array |
2 | import enum | |
3 | 3 | import collections |
4 | 4 | import datetime |
5 | 5 | import decimal |
6 | import enum | |
6 | 7 | import re |
7 | 8 | import threading |
9 | ||
10 | import pytest | |
8 | 11 | import pytz |
12 | from helper import SkippableTest | |
9 | 13 | |
10 | 14 | import jsonpickle |
11 | from jsonpickle import compat | |
12 | from jsonpickle import handlers | |
13 | from jsonpickle import tags | |
14 | from jsonpickle import util | |
15 | from jsonpickle.compat import queue, PY2, PY3_ORDERED_DICT | |
16 | ||
17 | import pytest | |
18 | ||
19 | from helper import SkippableTest | |
15 | from jsonpickle import compat, handlers, tags, util | |
16 | from jsonpickle.compat import queue | |
20 | 17 | |
21 | 18 | |
22 | 19 | class Thing(object): |
107 | 104 | pass |
108 | 105 | |
109 | 106 | |
107 | def func(x): | |
108 | return x | |
109 | ||
110 | ||
110 | 111 | class ThingWithFunctionRefs(object): |
111 | 112 | def __init__(self): |
112 | 113 | self.fn = func |
113 | ||
114 | ||
115 | def func(x): | |
116 | return x | |
117 | 114 | |
118 | 115 | |
119 | 116 | class ThingWithQueue(object): |
521 | 518 | self.assertTrue(decoded == u1) |
522 | 519 | self.assertTrue(isinstance(decoded, compat.ustr)) |
523 | 520 | |
524 | # bytestrings are wrapped in PY3 but in PY2 we try to decode first | |
521 | # bytestrings are wrapped in py 3 | |
525 | 522 | encoded = self.pickler.flatten(b1) |
526 | if PY2: | |
527 | self.assertEqual(encoded, u1) | |
528 | self.assertTrue(isinstance(encoded, compat.ustr)) | |
529 | else: | |
530 | self.assertNotEqual(encoded, u1) | |
531 | encoded_ustr = util.b64encode(b'foo') | |
532 | self.assertEqual({tags.B64: encoded_ustr}, encoded) | |
533 | self.assertTrue(isinstance(encoded[tags.B64], compat.ustr)) | |
523 | self.assertNotEqual(encoded, u1) | |
524 | encoded_ustr = util.b64encode(b'foo') | |
525 | self.assertEqual({tags.B64: encoded_ustr}, encoded) | |
526 | self.assertTrue(isinstance(encoded[tags.B64], compat.ustr)) | |
534 | 527 | decoded = self.unpickler.restore(encoded) |
535 | 528 | self.assertTrue(decoded == b1) |
536 | if PY2: | |
537 | self.assertTrue(isinstance(decoded, compat.ustr)) | |
538 | else: | |
539 | self.assertTrue(isinstance(decoded, bytes)) | |
529 | self.assertTrue(isinstance(decoded, bytes)) | |
540 | 530 | |
541 | 531 | # bytestrings that we can't decode to UTF-8 will always be wrapped |
542 | 532 | encoded = self.pickler.flatten(b2) |
547 | 537 | decoded = self.unpickler.restore(encoded) |
548 | 538 | self.assertEqual(decoded, b2) |
549 | 539 | self.assertTrue(isinstance(decoded, bytes)) |
550 | ||
551 | def test_backcompat_bytes_quoted_printable(self): | |
552 | """Test decoding bytes objects from older jsonpickle versions""" | |
553 | ||
554 | b1 = b'foo' | |
555 | b2 = b'foo\xff' | |
556 | ||
557 | # older versions of jsonpickle used a quoted-printable encoding | |
558 | expect = b1 | |
559 | actual = self.unpickler.restore({tags.BYTES: 'foo'}) | |
560 | self.assertEqual(expect, actual) | |
561 | ||
562 | expect = b2 | |
563 | actual = self.unpickler.restore({tags.BYTES: 'foo=FF'}) | |
564 | self.assertEqual(expect, actual) | |
565 | 540 | |
566 | 541 | def test_nested_objects(self): |
567 | 542 | obj = ThingWithTimedeltaAttribute(99) |
604 | 579 | typecodes = ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'f', 'd') |
605 | 580 | for typecode in typecodes: |
606 | 581 | obj = array.array(typecode, (1, 2, 3)) |
607 | self._test_array_roundtrip(obj) | |
608 | ||
609 | def test_array_handler_python2(self): | |
610 | """Python2 allows the "c" byte/char typecode""" | |
611 | if PY2: | |
612 | obj = array.array('c', bytes('abcd')) | |
613 | 582 | self._test_array_roundtrip(obj) |
614 | 583 | |
615 | 584 | def test_exceptions_with_arguments(self): |
693 | 662 | decoded = jsonpickle.decode(encoded, keys=True) |
694 | 663 | assert decoded[0].default_factory() == 0 |
695 | 664 | assert decoded[1] is decoded[2] |
696 | ||
697 | ||
698 | def test_defaultdict_subclass_with_self_as_default_factory(): | |
699 | """Serialize a defaultdict subclass with self as its default factory""" | |
700 | cls = ThingWithSelfAsDefaultFactory | |
701 | tree = cls() | |
702 | newtree = _test_defaultdict_tree(tree, cls) | |
703 | assert type(newtree['A'].default_factory) == cls | |
704 | assert newtree.default_factory is newtree | |
705 | assert newtree['A'].default_factory is newtree['A'] | |
706 | assert newtree['Z'].default_factory is newtree['Z'] | |
707 | ||
708 | ||
709 | def test_defaultdict_subclass_with_class_as_default_factory(): | |
710 | """Serialize a defaultdict with a class as its default factory""" | |
711 | cls = ThingWithClassAsDefaultFactory | |
712 | tree = cls() | |
713 | newtree = _test_defaultdict_tree(tree, cls) | |
714 | assert newtree.default_factory is cls | |
715 | assert newtree['A'].default_factory is cls | |
716 | assert newtree['Z'].default_factory is cls | |
717 | 665 | |
718 | 666 | |
719 | 667 | def _test_defaultdict_tree(tree, cls): |
740 | 688 | return newtree |
741 | 689 | |
742 | 690 | |
691 | def test_defaultdict_subclass_with_self_as_default_factory(): | |
692 | """Serialize a defaultdict subclass with self as its default factory""" | |
693 | cls = ThingWithSelfAsDefaultFactory | |
694 | tree = cls() | |
695 | newtree = _test_defaultdict_tree(tree, cls) | |
696 | assert type(newtree['A'].default_factory) == cls | |
697 | assert newtree.default_factory is newtree | |
698 | assert newtree['A'].default_factory is newtree['A'] | |
699 | assert newtree['Z'].default_factory is newtree['Z'] | |
700 | ||
701 | ||
702 | def test_defaultdict_subclass_with_class_as_default_factory(): | |
703 | """Serialize a defaultdict with a class as its default factory""" | |
704 | cls = ThingWithClassAsDefaultFactory | |
705 | tree = cls() | |
706 | newtree = _test_defaultdict_tree(tree, cls) | |
707 | assert newtree.default_factory is cls | |
708 | assert newtree['A'].default_factory is cls | |
709 | assert newtree['Z'].default_factory is cls | |
710 | ||
711 | ||
743 | 712 | def test_posix_stat_result(): |
744 | 713 | """Serialize a posix.stat() result""" |
745 | 714 | try: |
776 | 745 | |
777 | 746 | def test_ordered_dict_python3(): |
778 | 747 | """Ensure that we preserve dict order on python3""" |
779 | if not PY3_ORDERED_DICT: | |
780 | return | |
781 | 748 | # Python3.6+ preserves dict order. |
782 | 749 | obj = {'z': 'Z', 'x': 'X', 'y': 'Y'} |
783 | 750 | clone = jsonpickle.decode(jsonpickle.encode(obj)) |
0 | 0 | from __future__ import absolute_import, division, unicode_literals |
1 | ||
1 | 2 | import datetime |
2 | 3 | |
3 | 4 | import pytest |
4 | 5 | |
5 | 6 | try: |
7 | import numpy as np | |
6 | 8 | import pandas as pd |
7 | import numpy as np | |
8 | from pandas.testing import assert_series_equal | |
9 | from pandas.testing import assert_frame_equal | |
10 | from pandas.testing import assert_index_equal | |
9 | from pandas.testing import ( | |
10 | assert_frame_equal, | |
11 | assert_index_equal, | |
12 | assert_series_equal, | |
13 | ) | |
11 | 14 | except ImportError: |
12 | 15 | pytest.skip('numpy is not available', allow_module_level=True) |
13 | 16 | |
128 | 131 | |
129 | 132 | |
130 | 133 | def test_int64_index_roundtrip(): |
131 | idx = pd.Int64Index([-1, 0, 3, 4]) | |
134 | idx = pd.Index([-1, 0, 3, 4], dtype=np.int64) | |
132 | 135 | decoded_idx = roundtrip(idx) |
133 | 136 | assert_index_equal(decoded_idx, idx) |
134 | 137 | |
135 | 138 | |
136 | 139 | def test_uint64_index_roundtrip(): |
137 | idx = pd.UInt64Index([0, 3, 4]) | |
140 | idx = pd.Index([0, 3, 4], dtype=np.uint64) | |
138 | 141 | decoded_idx = roundtrip(idx) |
139 | 142 | assert_index_equal(decoded_idx, idx) |
140 | 143 | |
141 | 144 | |
142 | 145 | def test_float64_index_roundtrip(): |
143 | idx = pd.Float64Index([0.1, 3.7, 4.2]) | |
146 | idx = pd.Index([0.1, 3.7, 4.2], dtype=np.float64) | |
144 | 147 | decoded_idx = roundtrip(idx) |
145 | 148 | assert_index_equal(decoded_idx, idx) |
146 | 149 |
1 | 1 | |
2 | 2 | import unittest |
3 | 3 | |
4 | from helper import SkippableTest | |
5 | ||
4 | 6 | import jsonpickle |
5 | ||
6 | from helper import SkippableTest | |
7 | 7 | |
8 | 8 | try: |
9 | 9 | import sqlalchemy as sqa |
0 | 0 | # -*- coding: utf-8 -*- |
1 | 1 | """Test miscellaneous objects from the standard library""" |
2 | 2 | |
3 | import unittest | |
3 | 4 | import uuid |
4 | import unittest | |
5 | 5 | |
6 | 6 | import jsonpickle |
7 | 7 |
5 | 5 | # you should have received as part of this distribution. |
6 | 6 | |
7 | 7 | from __future__ import absolute_import, division, unicode_literals |
8 | ||
9 | import doctest | |
10 | import io | |
11 | import time | |
8 | 12 | import unittest |
9 | import doctest | |
10 | import time | |
11 | ||
12 | from jsonpickle import compat | |
13 | from jsonpickle import util | |
13 | ||
14 | from jsonpickle import compat, util | |
14 | 15 | |
15 | 16 | |
16 | 17 | class Thing(object): |
28 | 29 | |
29 | 30 | |
30 | 31 | class MethodTestClass(object): |
32 | ||
33 | variable = None | |
34 | ||
31 | 35 | @staticmethod |
32 | 36 | def static_method(): |
33 | 37 | pass |
39 | 43 | def bound_method(self): |
40 | 44 | pass |
41 | 45 | |
42 | variable = None | |
43 | ||
44 | 46 | |
45 | 47 | class MethodTestSubclass(MethodTestClass): |
46 | 48 | pass |
52 | 54 | |
53 | 55 | |
54 | 56 | class UtilTestCase(unittest.TestCase): |
55 | @unittest.skipIf(not compat.PY2, 'Python 2-specific Base85 test') | |
56 | def test_b85encode_crashes_on_python2(self): | |
57 | with self.assertRaises(NotImplementedError): | |
58 | util.b85encode(b'') | |
59 | ||
60 | @unittest.skipIf(not compat.PY2, 'Python 2-specific Base85 test') | |
61 | def test_b85decode_crashes_on_python2(self): | |
62 | with self.assertRaises(NotImplementedError): | |
63 | util.b85decode(u'RC2?pb0AN3baKO~') | |
64 | ||
65 | 57 | def test_is_primitive_int(self): |
66 | 58 | self.assertTrue(util.is_primitive(0)) |
67 | 59 | self.assertTrue(util.is_primitive(3)) |
74 | 66 | self.assertTrue(util.is_primitive(float(3))) |
75 | 67 | |
76 | 68 | def test_is_primitive_long(self): |
77 | self.assertTrue(util.is_primitive(2 ** 64)) | |
69 | self.assertTrue(util.is_primitive(2**64)) | |
78 | 70 | |
79 | 71 | def test_is_primitive_bool(self): |
80 | 72 | self.assertTrue(util.is_primitive(True)) |
234 | 226 | old_instance = MethodTestOldStyle() |
235 | 227 | self.assertTrue(has_method(old_instance, 'bound_method')) |
236 | 228 | self.assertFalse(has_method(MethodTestOldStyle, 'bound_method')) |
229 | ||
230 | def test_importable_name(self): | |
231 | func_being_tested_obj = util.importable_name | |
232 | io_method_obj = io.BytesIO(b'bytes').readline | |
233 | self.assertEqual( | |
234 | util.importable_name(func_being_tested_obj), | |
235 | 'jsonpickle.util.importable_name', | |
236 | ) | |
237 | self.assertEqual(util.importable_name(io_method_obj), '_io.BytesIO.readline') | |
238 | self.assertEqual(util.importable_name(dict), 'builtins.dict') | |
237 | 239 | |
238 | 240 | |
239 | 241 | def suite(): |
5 | 5 | |
6 | 6 | """ |
7 | 7 | from __future__ import absolute_import, division, unicode_literals |
8 | ||
9 | import collections | |
8 | 10 | import unittest |
9 | import collections | |
10 | ||
11 | from jsonpickle import encode, decode | |
11 | ||
12 | from jsonpickle import decode, encode | |
12 | 13 | |
13 | 14 | |
14 | 15 | class World(object): |
21 | 22 | self.name = name |
22 | 23 | self.spells = collections.OrderedDict() |
23 | 24 | world.wizards.append(self) |
24 | ||
25 | def __hash__(self): | |
26 | return hash('Wizard %s' % self.name) | |
27 | ||
28 | def __eq__(self, other): | |
29 | for (ka, va), (kb, vb) in zip(self.spells.items(), other.spells.items()): | |
30 | if ka.name != kb.name: | |
31 | print('Wizards differ: %s != %s' % (ka.name, kb.name)) | |
32 | return False | |
33 | for sa, sb in zip(va, vb): | |
34 | if sa != sb: | |
35 | print('Spells differ: %s != %s' % (sa.name, sb.name)) | |
36 | return False | |
37 | return self.name == other.name | |
38 | 25 | |
39 | 26 | def __cmp__(self, other): |
40 | 27 | for (ka, va), (kb, vb) in zip(self.spells.items(), other.spells.items()): |
49 | 36 | return cmp_spell |
50 | 37 | return cmp(self.name, other.name) # noqa: F821 |
51 | 38 | |
39 | def __eq__(self, other): | |
40 | for (ka, va), (kb, vb) in zip(self.spells.items(), other.spells.items()): | |
41 | if ka.name != kb.name: | |
42 | print('Wizards differ: %s != %s' % (ka.name, kb.name)) | |
43 | return False | |
44 | for sa, sb in zip(va, vb): | |
45 | if sa != sb: | |
46 | print('Spells differ: %s != %s' % (sa.name, sb.name)) | |
47 | return False | |
48 | return self.name == other.name | |
49 | ||
50 | def __hash__(self): | |
51 | return hash('Wizard %s' % self.name) | |
52 | ||
52 | 53 | |
53 | 54 | class Spell(object): |
54 | 55 | def __init__(self, caster, target, name): |
61 | 62 | spells = caster.spells[target] = [] |
62 | 63 | spells.append(self) |
63 | 64 | |
64 | def __hash__(self): | |
65 | return hash( | |
66 | 'Spell %s by %s on %s' % (self.name, self.caster.name, self.target.name) | |
67 | ) | |
65 | def __cmp__(self, other): | |
66 | return ( | |
67 | cmp(self.name, other.name) # noqa: F821 | |
68 | or cmp(self.caster.name, other.caster.name) # noqa: F821 | |
69 | or cmp(self.target.name, other.target.name) # noqa: F821 | |
70 | ) # noqa: F821 | |
68 | 71 | |
69 | 72 | def __eq__(self, other): |
70 | 73 | return ( |
73 | 76 | and self.target.name == other.target.name |
74 | 77 | ) |
75 | 78 | |
76 | def __cmp__(self, other): | |
77 | return ( | |
78 | cmp(self.name, other.name) # noqa: F821 | |
79 | or cmp(self.caster.name, other.caster.name) # noqa: F821 | |
80 | or cmp(self.target.name, other.target.name) # noqa: F821 | |
81 | ) # noqa: F821 | |
79 | def __hash__(self): | |
80 | return hash( | |
81 | 'Spell %s by %s on %s' % (self.name, self.caster.name, self.target.name) | |
82 | ) | |
82 | 83 | |
83 | 84 | |
84 | 85 | def hashsum(items): |